2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

HttpClientをマルチスレッドで使用するとソケット枯渇する

Last updated at Posted at 2020-04-15

HttpClientインスタンスは1つにし、MaxConnectionsPerServerを適切に設定する

HttpClientの利用でソケット枯渇しないように、using (var httpClient = new HttpClient())のようにインスタンスを使い捨てにせずにprivate static HttpClient _httpClient = new HttpClient();でインスタンスを使いまわす記事がありますが、これはシングルスレッドでの処理では効果がありますが、マルチスレッドの高負荷環境ではソケット枯渇が発生します。

ソケット枯渇発生についての詳細は、他の方の記事にが参考になりますので、ここでは割愛しますが、MaxConnectionsPerServerのデフォルトがint.MaxValueで接続数が実質無制限のため、
次のように明示的に接続数を設定する事が必要です。

private static HttpClient _httpClient = new HttpClient(new HttpClientHandler
{
    MaxConnectionsPerServer = 4
});

Azure Stotage ライブラリ内のHttpClientの接続数

Azure StorageのBLOBやQueueのAPI処理でも先の原因でソケット枯渇が発生します。
(Azure FunctionsのQueueTriggerなどマルチスレッドで処理する環境では高負荷時にSocketException発生します)
Azure Stotage ライブラリのv9.4.1からCloudBlobClientやCloudQueueClientコンストラクタにDelegatingHandlerパラメータが追加されていますので、次のようにハンドラを実装し接続数を指定すると良いようです。

(.Net Core v3.0, Microsoft.Azure.Storage.Blob(v11.1.3), Microsoft.Azure.Storage.Queue(v11.1.3)で確認)

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);
    }
}
private static CloudStorageAccount _storageAccount = CloudStorageAccount.Parse(@"Connection String...");
private static CloudBlobClient _blobClient = new CloudBlobClient(_storageAccount.BlobEndpoint, _storageAccount.Credentials, new HttpClientInjectionHandler());

Azure Storage ライブラリのバージョン メモ

~v9.3.3: WindowsAzure.Storage

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

v9.4.0~v11: Microsoft.Azure.Storage.Blob

using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;

v12 azure.Storage.Blobs

v11までとクラス名が異なる。v12にはコンストラクタにDelegatingHandlerパラメータが無いまま。
~v11:CloudBlobClient
v12~:BlobServiceClient

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?