简体   繁体   English

多个 HttpClientHandler 实例超时错误

[英]Time out errors with multiple HttpClientHandler instance

We have written an application that connects with an external API.我们编写了一个与外部 API 连接的应用程序。 You need to have a Token to communicate with this api.您需要有一个 Token 才能与这个 api 进行通信。 The token have to be unique for each user.每个用户的令牌必须是唯一的。 To obtain a token we need to call an endpoint with a client-certificate that belongs to this user.要获取令牌,我们需要使用属于该用户的客户端证书调用端点。

We have implemented this by using 1 static HttpClientHandler instance for all API requests.我们通过对所有 API 请求使用 1 个 static HttpClientHandler 实例来实现这一点。 Each request is setting up a HttpClient with this static handler given;每个请求都使用给定的 static 处理程序设置一个 HttpClient; and only the client will be disposed, the handler will be kept alive.并且只有客户端将被释放,处理程序将保持活动状态。 However to obtain a token;但是要获得token; we need to add the certificate to the handler.我们需要将证书添加到处理程序。 Therefore when obtaining a token;因此在获取token时; we uses a new HttpClientHandler instance specific for obtaining the token.我们使用一个新的 HttpClientHandler 实例来获取令牌。 As soon the token is obtained, we dispose the client and the handler instance.获得令牌后,我们立即处理客户端和处理程序实例。

Now a lot of calls are failing with the following error:现在很多电话都因以下错误而失败:

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [ip]:443连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应 [ip]:443

most of the errors happens when we obtain the Token.大多数错误发生在我们获取 Token 时。 But sometimes a normal API call is failing with this same error.但有时,正常的 API 调用会因同样的错误而失败。

The other party has also researched this issue;对方也研究过这个问题; and the latest conclusion they gave us: is that at the end of the request we keep the connection alive;他们给我们的最新结论是:在请求结束时,我们保持连接处于活动状态; so the port is reserved for that connection.因此该端口是为该连接保留的。 However sometimes a new request (new connection I guess) is tried to setup from our side with the same port.但是,有时会尝试从我们这边使用相同的端口设置一个新请求(我猜是新连接)。 There firewall is blocking/dropping this new request;有防火墙阻止/丢弃这个新请求; because this port is already in use.因为这个端口已经被使用了。 And that is why we ends with this time out error.这就是为什么我们以这个超时错误结束。

Well this makes sense;嗯,这是有道理的; we do not have control over the ports that the connection uses.我们无法控制连接使用的端口。 But why does this happening?但是为什么会这样呢? I have this theory that the issue lies in the combination of the static handler (that supports 10 parallels connections and keep this connections inactive, but alive) and the second (or more) other handlers that may think that a port is free (because there are not activities on this port) may try to setup a connection with that port.我有这样的理论,即问题在于 static 处理程序(支持 10 个并行连接并保持此连接处于非活动状态,但仍处于活动状态)和可能认为端口空闲的第二个(或更多)其他处理程序的组合(因为那里不是此端口上的活动)可能会尝试建立与该端口的连接。 But it is just a theory;但这只是一个理论; i can not find proof for this.我找不到这方面的证据。

Is there someone that can confirm this theory;有没有人可以证实这个理论? or maybe give an other explanation why this issue may appear?或者也许给出其他解释为什么会出现这个问题? And/or is there a solution/workaround for this issue?和/或是否有针对此问题的解决方案/解决方法?

Ho, I think you're facing a problem called Socket Exhaustion.何,我认为您面临一个称为 Socket Exhaustion 的问题。 Although you do dispose() the HTTP Client, the socket it used will still be reserved for a certain amount of time.尽管您确实dispose() HTTP 客户端,但它使用的套接字仍将保留一段时间。 To prevent this, you need a mechanism that allows you to re-use the HttpClients and therefore the underlying sockets they use.为了防止这种情况发生,您需要一种机制来允许您重用 HttpClients 以及它们使用的底层 sockets。

The recommended way is to use the HttpClientFactory.推荐的方法是使用 HttpClientFactory。 This factory will build a pool with HttpClients and provides you with one on-demand while maintaining the pool of clients for you.该工厂将使用 HttpClients 构建一个池,并按需为您提供一个,同时为您维护客户端池。

More information is found on the Microsoft Docs website: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests更多信息可在 Microsoft Docs 网站上找到: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM