拥有一个HttpClient实例并适当配置MaxConnectionsPerServer
有一篇使用私有静态HttpClient _httpClient = new HttpClient()的文章;而不是像使用(var httpClient = new HttpClient())那样丢弃实例,以便不使用HttpClient耗尽套接字。但是,尽管这对于单线程处理非常有效,但会在多线程,高负载环境中导致套接字耗尽。
有关套接字耗尽的详细信息将在其他文章中进行介绍,因此在此将其省略,但是由于MaxConnectionsPerServer默认为int.MaxValue并且连接数实际上是无限的,所以
有必要如下明确设置连接数。
1 2 3 4 | private static HttpClient _httpClient = new HttpClient(new HttpClientHandler { MaxConnectionsPerServer = 4 }); |
Azure Stotage库中的HttpClient连接数
由于上述原因,即使在BLOB的API处理和Azure存储的队列中也会发生套接字耗尽。
(在使用多个线程处理的环境(例如Azure Functions的队列触发器)中,SocketException在高负载下发生)
由于DelegatingHandler参数已从Azure Stotage库的v9.4.1版本添加到CloudBlobClient和CloudQueueClient构造函数中,因此实现处理程序并按如下所示指定连接数似乎很不错。
(使用.Net Core v3.0,Microsoft.Azure.Storage.Blob(v11.1.3),Microsoft.Azure.Storage.Queue(v11.1.3)检查)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class HttpClientInjectionHandler : DelegatingHandler { private bool IsFirstCall = true; protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (IsFirstCall) { var handler = (HttpClientHandler)InnerHandler; handler.MaxConnectionsPerServer = 5; IsFirstCall = false; } return base.SendAsync(request, cancellationToken); } } |
1 2 | private static CloudStorageAccount _storageAccount = CloudStorageAccount.Parse(@"Connection String..."); private static CloudBlobClient _blobClient = new CloudBlobClient(_storageAccount.BlobEndpoint, _storageAccount.Credentials, new HttpClientInjectionHandler()); |
Azure存储库版本说明
?v9.3.3:WindowsAzure.Storage
1 2 | using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; |
v9.4.0?v11:Microsoft.Azure.Storage.Blob
1 2 | using Microsoft.Azure.Storage; using Microsoft.Azure.Storage.Blob; |
v12 azure.Storage.Blobs
类名不同于
v11。 v12在构造函数中没有DelegatingHandler参数。
?v11:CloudBlobClient
v12?:BlobServiceClient
参考文献
- 您正在使用HTTPCLIENT WRONG,并且正在破坏您的软件
- 在多个线程中操作HttpClient时的注意事项
- 谨慎讨论处理.NET(框架)HttpClient