HttpClient和套接字耗尽-澄清吗? [英] HttpClient and socket exhaustion - clarification?
问题描述
本文 表示我们应该使用静态 HttpClient
以便重用套接字.
但是那里的第一条评论说存在DNS更改识别问题,解决方案在另一篇文章
But the first comment there says that there is a DNS changes recognition issue, and the solution is in another article here:
第二篇文章建议:
var client = new HttpClient();
client.DefaultRequestHeaders.ConnectionClose = true;
哪个控件控制 KeepAlive
标头.但是会妨碍您利用重新使用套接字的好处
Which controls the KeepAlive
header.
But suffers from preventing you to take advantage of benefits of re-using a socket
另一个解决方案是:
var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute
但是:
他没有说我们每次要发出请求时是否应该使用 new Httpclient
,还是应该仍然使用静态请求.
He didn't say whether should we use new Httpclient
each time we want to make a request, or should we still use the static one.
问题:
说我要使用此解决方案:
Say I want to use this solution :
var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute
- 我仍然应该使用
static HttpClient
方法吗?还是应该在每次拨打电话时new HttpClient
?或者-我应该为每个scheme://basedns
创建静态/非静态new HttpClient
吗? - Should I still use the
static HttpClient
approach ? or should Inew HttpClient
each time I want to make a call? Or - Should I create static/not staticnew HttpClient
for eachscheme://basedns
?
他展示了问题,但他的结论并未给出完整的最终解决方案.
请注意-我在问.net框架.不是.net Core.
推荐答案
这是非常的老文章,它确实解释了为什么应该重用HttpClient,但没有解释如何处理DNS更改.在单HttpClient中进行了解释.当心这种严重的行为及其解决方法.那仍然只处理一个连接.
That's a very old article that does explain why HttpClient should be reused, but doesn't explain how to handle DNS changes. That's explained in Singleton HttpClient? Beware of this serious behaviour and how to fix it. That still only deals with one connection.
显而易见的答案是避免单例HttpClient,但仍会重用它们一段时间.此外,不同的套接字用于连接到不同的服务器,这意味着我们确实需要在每个服务器上重用(和回收)套接字.该解决方案后来以HttpClientFactory的形式出现.
The obvious answer is to avoid singleton HttpClients but still reuse them for some time. Besides, different sockets are used to connect to different servers, which means we'd really need to reuse (and recycle) sockets per server. The solution came later in the form of HttpClientFactory.
令人高兴的是HttpClientFactory是.NET Standard 2.0程序包, Microsoft.Extensions.可以由.NET Core和.NET Old使用的Http ,而不仅仅是ASP.NET Core应用程序.例如,我在控制台应用程序中使用它.
The nice thing is that HttpClientFactory is a .NET Standard 2.0 package, Microsoft.Extensions.Httpthat can be used by both .NET Core and .NET Old, not just ASP.NET Core applications. I use it in console applications for example.
一个很好的介绍是ASP.NET Core 2.1(PART 1)中的 HttpClientFactory(由史蒂夫·戈登(Steve Gordon)撰写,以及 all )在该系列.
A very good introduction is HttpClientFactory in ASP.NET Core 2.1 (PART 1) by Steve Gordon, and all his articles in that series.
简而言之,每次我们想要HttpClient时,我们都会向工厂索要实例:
In short, each time we want an HttpClient we ask the factory for an instance :
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IHttpClientFactory _httpClientFactory;
public ValuesController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public async Task<ActionResult> Get()
{
var client = _httpClientFactory.CreateClient();
var result = await client.GetStringAsync("http://www.google.com");
return Ok(result);
}
}
HttpClient将工作委托给SocketClientHandler.那就是需要重用的东西.HttpClientFactory产生HttpClient实例,这些实例重新使用套接字处理程序池中的套接字处理程序.处理程序会定期回收以处理DNS更改.
HttpClient delegates work to a SocketClientHandler. That's what needs to be reused. HttpClientFactory produces HttpClient instances that resuse Socket handlers from a pool of socket handlers. The handlers are recyclec periodically to take care of DNS changes.
更好的是,HttpClientFactory 可以与Polly组合将重试逻辑添加到HttpClient实例.它通过配置处理程序在后台执行此操作.
Even better, HttpClientFactory can be combined with Polly to add retry logic to the HttpClient instances. It does this behind the scenes by configuring the handlers.
这篇关于HttpClient和套接字耗尽-澄清吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!