Unser Produkt wurde auf der .Net Core 2.2-Plattform unter Verwendung von WCF 4.5 für die Interaktion mit dem SOAP-Client-Service entwickelt. Während des Dienstes stellten die Datenbusentwickler eine hohe Belastung des Servers fest. Außerdem traten Probleme beim Zugriff auf den Dienst auf. Als Ergebnis wurde festgestellt, dass der Grund in der Anzahl der Wirkstoffe liegt.
Es gibt ein Problem wie die Erschöpfung der Verbindung. Dies kann auf das Fehlen verfügbarer Ports beim Herstellen einer Verbindung oder auf die Begrenzung der Anzahl der Verbindungen zu externen oder internen Diensten zurückzuführen sein. Es gibt zwei Lösungen:
• Erhöhung der verfügbaren Ressourcen,
• Reduzierung der Anzahl der Verbindungen.
Die erste Option steht uns nicht zur Verfügung, da eine Erhöhung der Ressourcen nur auf Seiten des Dienstleisters erfolgen kann. Aus diesem Grund haben wir uns entschlossen, nach Optionen zur Optimierung der Anzahl der Verbindungen zu suchen. In diesem Artikel werden wir über die gefundene Lösung sprechen.

Idee
Wie sich herausstellte, bestand das Problem darin, dass wir für jede Anforderung eine neue Instanz des WCF-Clients erstellt haben. Dies machte es unmöglich, den bereits in WCF implementierten Verbindungspool zu verwenden, da der Pool für jeden Kanal erstellt wird und wir für jede Anforderung einen neuen Kanal erstellen. Natürlich können Sie den Dienst, der für die Interaktion mit WCF verantwortlich ist, mithilfe eines statischen WCF-Clients neu schreiben. In diesem Fall wäre der Pool jedoch auch statisch, was zu dem
in diesem Artikel beschriebenen DNS-Änderungsproblem führen könnte. Es wurde auch über die Lösung gesprochen -
HttpClientFactory . Das Wesentliche der Lösung ist, dass die Fabrik mit einem eigenen Pool arbeiten kann, in dem die Verbindungen regelmäßig aktualisiert werden. Die Standardaktualisierungsdauer beträgt zwei Minuten, kann jedoch geändert werden.
In unserem Produkt haben wir HttpClientFactory bereits für die Interaktion mit anderen Diensten verwendet, und die Verwendung der Factory in WCF schien eine gute Alternative zu einem statischen WCF-Client zu sein. In diesem Fall müssten wir keine Änderungen an der Implementierung des WCF-Dienstes vornehmen. Aber sie könnten den Pool benutzen, mit dem die Fabrik arbeiten kann. Auf diese Weise konnten wir
das in diesem Artikel beschriebene Problem mit der NTLM-Authentifizierung unter Linux lösen, da Sie bei der Konfiguration des http-Clients das Authentifizierungsschema für den Nachrichtenhandler festlegen können.
Implementierung
Um mit HttpClientFactory zu arbeiten, fügen Sie einfach die Client-Konfigurationsbeschreibung zu ConfigureServices hinzu. Dort können Sie mehrere benannte oder typisierte Clients mit Ihrer eigenen Konfiguration hinzufügen. In diesem Fall verwendet jeder Client seinen eigenen Verbindungspool. Im Beispiel verwenden wir einen benannten Client.
services.AddHttpClient("ClientName");
In WCF können Sie Ihre eigenen Nachrichtenhandler für den http-Client hinzufügen. Fügen Sie dazu den Bindungsparametern einen von der Methode initialisierten Delegaten hinzu. Dort erhalten wir als Eingabeparameter einen auf der WCF-Seite erstellten Handler und geben unseren eigenen Handler zurück. Infolgedessen wird der von der Delegate-Methode erhaltene Handler an den http-Designer des Clients auf der WCF-Seite übergeben.
Wenn Sie den Handler aus dem Factory-Pool zurückgeben, ersetzen wir den eingehenden Handler durch diesen. Um den Handler aus dem Factory-Pool abzurufen, verwenden wir die HttpMessageHandlerFactory. Um Zugriff auf die Bindungsparameter zu erhalten, muss eine von IEndpointBehavior geerbte Klasse implementiert werden. Und fügen Sie es dann unserem WCF-Client hinzu.
Schematisch sieht der Algorithmus zum Erstellen eines neuen Clients auf der WCF-Seite so aus.

Wir implementieren CustomEndpointBehaviour.
public class CustomEndpointBehavior : IEndpointBehavior { private readonly Func<HttpMessageHandler> _httpHandler; public CustomEndpointBehavior(IHttpMessageHandlerFactory factory) {
Fügen Sie als Nächstes unser EndpointBehavior zum WCF-Client hinzu.
var httpMessageHandler = serviceProvider.GetRequiredService<IHttpMessageHandlerFactory>(); var client = new WcfClient(); client.Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior(httpMessageHandler));
Beim Erstellen von Verbindungen über WCF werden nach Möglichkeit Handlerinstanzen aus dem Pool verwendet. Dies verringert die Anzahl der Wirkstoffe.
Test
Zur Überprüfung haben wir 100 identische Anfragen gesendet. Infolgedessen erreichte der Peak der Verbindungen ohne Pool 53, und mit einem Pool überschritt er 7 nicht.
Überwachen von Verbindungen ohne Pool:

Poolverbindungen überwachen:

Fazit
Wir von True Engineering haben einen Verbindungspool in WCF implementiert, der nicht von der Implementierung der Arbeit mit dem WCF-Client abhängt. Außerdem werden Ressourcen sowohl auf der Serverseite, auf der die Anwendung ausgeführt wird, als auch auf der Seite des Dienstanbieters effektiv gespart.
Wir haben viel Zeit damit verbracht, nach Optimierungsoptionen zu suchen, aber die Lösung selbst erwies sich als präzise und einfach. Nimm es, solange es heiß ist.