1725928142
2024-09-09 17:56:55
ご存知ですか? HttpClient 以内 using このステートメントにより、SNAT (送信元ネットワーク アドレス変換) ポートが枯渇する可能性がありますか? これにより、アプリケーションで重大なパフォーマンスの問題が発生する可能性があります。
SNAT ポートが使い果たされるとどうなりますか?
- 接続が遅い、または接続が切れる リモートエンドポイントへ
- ソケット例外 接続タイムアウトのため
この問題はローカル環境で再現するのが難しいですが、運用システムに重大な影響を及ぼし、広範囲にわたる混乱を引き起こす可能性があります。
なぜこれが重要なのでしょうか?
アプリケーションが複数のサードパーティAPIとやり取りする場合、誤って設定された HttpClient 関連性のない HTTP リクエストも含め、すべての HTTP リクエストの速度が低下したり、タイムアウトが発生したりする可能性があります。
さまざまな使い方を見てきました HttpClient 間違ったやり方です。いくつか例を挙げます。
public async Task Get(string? requestUri)
{
return await new HttpClient().GetAsync(requestUri);
}
C#では、 using ステートメントは、通常、使い捨てオブジェクト( HttpClientブロックを終了すると、適切に破棄されます。
しかし、 HttpClient、それは 避ける このパターン。 HttpClient 実装する IDisposable インターフェースは、 共有 オブジェクトは、頻繁に破棄したり再作成したりしてはならないことを意味します。
public async Task Get(string? requestUri)
{
using (var httpClient = new HttpClient())
return await httpClient.GetAsync(requestUri);
}
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Scoped)]
public class MyService : IMyService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task Get(string? requestUri)
{
return await _httpClient.GetAsync(requestUri);
}
}
実行ごとに HttpClient の新しいインスタンスを作成する代わりに、アプリケーションの存続期間全体にわたって HttpClient の単一のインスタンスを共有する必要があります。
ここでは、より良い方法を紹介します。
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)] IMyServiceインスタンスのシングルトンを作成するのに役立ちます
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task Get(string? requestUri)
{
return await _httpClient.GetAsync(requestUri);
}
}
.NET Coreでは、注入された IHttpClientFactory 物体。
では、最適な使い方を紹介します IHttpClientFactory サービス付き:
// register specific client in StartUp.cs
services.AddHttpClient("MyClient", (provider, client) => {
client.BaseAddress = new Uri("YOU URL");
client.DefaultRequestHeaders.Add("x-api-key", "YOUR API KEY");
});
[ServiceConfiguration(typeof(IMyService), Lifecycle = ServiceInstanceScope.Singleton)]
public class MyService : IMyService
{
private readonly IHttpClientFactory _httpClientFactory;
public OrderHistorySyncService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task Get(string? requestUri)
{
return await _httpClientFactory.CreateClient("MyClient").GetAsync(requestUri);
}
}
2024年9月9日
#SNAT #Azure #App #Service #ソケットの枯渇