Connections pool with WCF for .NET Core with usage of HttpClientFactory

Now our product is being developed on the basis of.Net Core 2.2 platform with the use of WCF 4.5 for interaction with SOAP client service. In the process of service operation, our data bus developers had noticed the high load on the server. After that, the problems with access to the service had appeared. The cause was contained in the number of active connections. The found solution is described in this article.

Image
WCF_1400х400.jpg

There is such a problem as connection exhaustion. It can appear because of the lack with accessible ports while making a connection or limits to the number of connections with external or internal service. There are two solutions:

  • Increasing the available resources,
  • Decreasing the number of connections.

The first solution is not available for us, because increasing the resources can be done only on the side of the service provider. Thus, we had decided to search for ways to optimize the number of connections. 

Idea

As it turned out, the issue had been that for every request we created a new copy of WCF client. It had done impossible to use the already realized in WCF connections pool because this pool is created for each channel, but we, opposite, had created a new channel for every request. Of course, it was possible to rewrite the service responsible for interaction with WCF, for the usage of the static WCF client. However, in this case, the pool will be also static and it will cause the issue with the change of DNS. There is a solution to HttpClientFactory. The core of the solution is in the fact that the factory can work with its own pool, where connections are updated periodically. The update period, in default, is two minutes but can be changed, if required.

At our product, we had used HttpClientFactory for interaction with other services, and the use of the factory in WCF looked like a good alternative to WCF static client. At the same time, we did not need to amend the realization of the WCF service. Well, but we could use the pool which the factory can work with. Moreover, it allowed us to resolve the issue with NTLM authorization in Linux because with the configuration of HTTP client we can set the authentication scheme for the notification handler.

Realization

For working with HttpClientFactory it is enough to add the description of the client configuration to ConfigureServices. There is the possibility to add several named or typed clients with their own configurations. In this case, for each client, his own connections pool will be used. For the example below the named client is used.

Image
wtf_sc_0.png

At WCF, it is possible to add own notification handlers for http clients. For that at binding parameters, we add the delegate by initialized method. There, as an input parameter, we get the handler created on WCF side and return our own handler. As a result, the handler, gotten from the delegate method, will be transferred to the constructor of http client on WCF side.

Thus, returning the handler from the factory pool, we will change the input handler by it. For getting the handler from the factory pool, HttpMessageHandlerFactory is used. In addition, to get access to binding parameters, it is required to realize the class inherited from IEndpointBehavior. Then to add it to our WCF client.

Schematically the algorithm of actions to create a new client on WCF side looks as the following:

Image
wtf_2_4

We realize CustomEndpointBehaviour.

Image
wcf_3.png

After that, we add our EndpointBehavior to WCF client.

Image
wcf_4.png

Now, when creating connections through WCF, copies of handlers from the pool will be used, if possible. It will reduce the number of active connections.

Testing

For checking we had sent 100 similar requests. In the result, without the pool, the peak of connections was 53, and with the pool had not exceeded 7.

Monitoring the connections without the pool:

Image
wcf_5.png

Monitoring the connections with the pool:

Image
wcf_6.png

Conclusion

We, in True Engineering, have realized the connections pool at WCF, which does not depend on realization of working with WCF client. Moreover, it effectively saves resources as on the server’s side, where the application launches, as well as on the service provider’s side.

We have spent a lot of time to find ways of optimization, but the solution itself have been gotten out laconic and simple to use. Take and use it, while it is hot :).

Our latest publications

See our knowledgebase