Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die System.Net.Http.HttpClient-Klasse sendet HTTP-Anforderungen und empfängt HTTP-Antworten von einer Ressource, die durch einen URI identifiziert wird. Eine HttpClient-Instanz ist eine Sammlung von Einstellungen, die auf alle von dieser Instanz ausgeführten Anforderungen angewendet wird, und jede Instanz verwendet einen eigenen Verbindungspool, der ihre Anforderungen von anderen isoliert. Ab .NET Core 2.1 stellt die SocketsHttpHandler-Klasse die Implementierung bereit, sodass das Verhalten auf allen Plattformen konsistent ist.
DNS-Verhalten
HttpClient löst DNS-Einträge nur auf, wenn eine Verbindung erstellt wird. Die vom DNS-Server angegebene Gültigkeitsdauer (Time To Live, TTL) wird nicht nachverfolgt. Wenn sich DNS-Einträge regelmäßig ändern, was in einigen Szenarien vorkommen kann, berücksichtigt der Client diese Updates nicht. Um dieses Problem zu beheben, können Sie die Gültigkeitsdauer der Verbindung einschränken, indem Sie die PooledConnectionLifetime-Eigenschaft festlegen, sodass die DNS-Suche wiederholt wird, wenn die Verbindung ersetzt wird. Betrachten Sie das folgenden Beispiel:
var handler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15) // Recreate every 15 minutes
};
var sharedClient = new HttpClient(handler);
Der vorherige HttpClient
ist so konfiguriert, dass Verbindungen 15 Minuten lang wiederverwendet werden. Nach Ablauf des von PooledConnectionLifetime angegebenen Zeitintervalls und nachdem die Verbindung die letzte zugehörige Anforderung (falls vorhanden) abgeschlossen hat, wird diese Verbindung geschlossen. Wenn es Anforderungen gibt, die in der Warteschlange warten, wird nach Bedarf eine neue Verbindung erstellt.
Das 15-Minuten-Intervall wurde willkürlich zur Veranschaulichung gewählt. Sie sollten den Wert basierend auf der erwarteten Häufigkeit von DNS- oder anderen Netzwerkänderungen auswählen.
Gepoolte Verbindungen
Der Verbindungspool für einen HttpClient ist mit dem zugrunde liegenden SocketsHttpHandler verknüpft. Wenn die HttpClient-Instanz verworfen wird, werden alle vorhandenen Verbindungen innerhalb des Pools verworfen. Wenn Sie später eine Anforderung an denselben Server senden, muss eine neue Verbindung erstellt werden. Daher gibt es eine Leistungsstrafe für die unnötige Verbindungserstellung. Darüber hinaus werden TCP-Ports nicht sofort nach dem Schließen der Verbindung freigegeben. (Weitere Informationen hierzu finden Sie unter „TCP TIME-WAIT
“ in RFC 9293.) Bei hoher Anforderungsrate ist das Betriebssystemlimit der verfügbaren Ports möglicherweise erschöpft. Um Porterschöpfungsprobleme zu vermeiden, wird empfohlen, HttpClient-Instanzen für möglichst viele HTTP-Anforderungen wiederzuverwenden.
Empfohlene Verwendung
Als Zusammenfassung der empfohlenen HttpClient
-Verwendung in Bezug auf die Lebensdauerverwaltung sollten Sie entweder langlebige Clients mit eingerichteter PooledConnectionLifetime
(.NET Core und .NET 5 oder höher) verwenden oder kurzlebige Clients, die von IHttpClientFactory
erstellt werden.
In .NET Core und .NET 5 oder höher:
- Verwenden Sie eine
static
-Instanz vom Typ oder HttpClient, wobei PooledConnectionLifetime auf das gewünschte Intervall festgelegt ist, z. B. 2 Minuten, je nach erwarteten DNS-Änderungen. Dadurch werden sowohl die Probleme mit Porterschöpfung als auch bei DNS-Änderungen behoben, ohne den Mehraufwand von IHttpClientFactory hinzuzufügen. Wenn Sie In der Lage sein müssen, Ihren Handler zu simulieren, können Sie ihn separat registrieren.
Tipp
Wenn Sie nur eine begrenzte Anzahl von HttpClient-Instanzen verwenden, ist dies ebenfalls eine akzeptable Strategie. Es kommt darauf an, dass sie nicht mit jeder Anforderung erstellt und verworfen werden, da sie jeweils einen Verbindungspool enthalten. Die Verwendung mehrerer Instanzen ist für Szenarien mit mehreren Proxys oder zum Trennen von Cookiecontainern erforderlich, ohne die Cookieverarbeitung vollständig zu deaktivieren.
Mit IHttpClientFactory können Sie mehrere, unterschiedlich konfigurierte Clients für unterschiedliche Anwendungsfälle verwenden. Beachten Sie jedoch, dass die von der Factory erstellten Clients kurzlebig sein sollen, und sobald der Client erstellt wurde, besitzt die Factory keine Kontrolle mehr darüber.
Die Factory poolt HttpMessageHandler-Instanzen, und wenn seine Gültigkeitsdauer noch nicht abgelaufen ist, kann ein Handler aus dem Pool wiederverwendet werden, wenn die Factory eine neue HttpClient-Instanz erstellt. Durch diese Wiederverwendung werden Probleme mit Socketerschöpfung vermieden.
Wenn Sie die Konfigurierbarkeit wünschen, die IHttpClientFactory bereitstellt, wird empfohlen, den Ansatz mit typisierten Clients zu verwenden.
- Verwenden Sie eine
Verwenden Sie in .NET Framework IHttpClientFactory, um Ihre
HttpClient
-Instanzen zu verwalten. Wenn Sie die Factory nicht verwenden und stattdessen für jede Anforderung selbst eine neue Clientinstanz erstellen, können Sie die verfügbaren Ports erschöpfen.Warnung
Wenn Ihre App Cookies erfordert, empfiehlt es sich, die Verwendung IHttpClientFactoryzu vermeiden. Das Poolen der HttpMessageHandler-Instanzen führt zur Freigabe von CookieContainer-Objekten. Unvorgesehene CookieContainer Freigaben können Cookies zwischen nicht zusammenhängenden Teilen der Anwendung durchlecken. Darüber hinaus wird der Handler wiederverwendet, wenn HandlerLifetime abläuft, was bedeutet, dass alle in ihm CookieContainer gespeicherten Cookies verloren gehen.
Weitere Informationen zum Verwalten der HttpClient
-Lebensdauer mit IHttpClientFactory
finden Sie unter IHttpClientFactory
-Richtlinien.
Resilienz bei statischen Clients
Es ist mithilfe des folgenden Musters möglich, einen static
- oder Singleton-Client so zu konfigurieren, dass eine beliebige Anzahl von Resilienzpipelines verwendet wird:
using Microsoft.Extensions.Http.Resilience;
using Polly;
class MyClass
{
static HttpClient? s_httpClient;
MyClass()
{
var retryPipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
.AddRetry(new HttpRetryStrategyOptions
{
BackoffType = DelayBackoffType.Exponential,
MaxRetryAttempts = 3
})
.Build();
var socketHandler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(15)
};
var resilienceHandler = new ResilienceHandler(retryPipeline)
{
InnerHandler = socketHandler,
};
s_httpClient = new HttpClient(resilienceHandler);
}
}
Der vorangehende Code:
- Basiert auf dem NuGet-Paket Microsoft.Extensions.Http.Resilience.
- Gibt einen vorübergehenden HTTP-Fehlerhandler an, der mit einer Wiederholungspipeline konfiguriert ist, die bei jedem Versuch ein exponentielles Backoff für Verzögerungsintervalle durchführt.
- Definiert eine gepoolte Verbindungslebensdauer von 15 Minuten für
socketHandler
. - Übergibt
socketHandler
mit der Wiederholungslogik anresilienceHandler
. - Instanziiert eine freigegebene
HttpClient
gegebene .resilienceHandler