2017-09-27 4 views
4

Ich habe ernsthafte Probleme mit dem .NET HttpClient unter hoher Last. Ich habe ein GitHub Repo erstellt, um das Problem zu demonstrieren. Würde jede Hilfe sehr schätzen. Ja, ich verwende nur eine HttpClient pro Behörde. Das gleiche Problem mit http und https. Kein serverseitiges Problem, da der Server die ganze Zeit über reaktiv bleibt.HttpClient nicht unter Schwerlast

https://github.com/erikbra/HttpClientProblems/issues/1

Regel die folgende Fehlermeldung erhalten. System.Net Trace-Protokoll sagt, es ruft ::Abort auf der Verbindung. Aber sehr schwierig, weitere Informationen zu bekommen.

System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: The connection with the server was terminated abnormally 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Threading.Tasks.RendezvousAwaitable`1.GetResult() 
    at System.Net.Http.WinHttpHandler.<StartRequest>d__105.MoveNext() 
    --- End of inner exception stack trace --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult() 
    at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__58.MoveNext() 
    --- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at UnitTests.Call_Api.<CallApi>d__22.MoveNext() in C:\Users\ErikBrandstadmoen\Source\Repos\HttpClientProblems\UnitTests.NetCore\Call_Api.cs:line 204 
    --- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at UnitTests.Call_Api.<Measure>d__23.MoveNext() in C:\Users\ErikBrandstadmoen\Source\Repos\HttpClientProblems\UnitTests.NetCore\Call_Api.cs:line 219 

[UPDATE]

Um genau zu sein, ich will verstehen, was geschieht. Offensichtlich wird die Verbindung unterbrochen, aber warum? Der Server reagiert immer noch, es ist also keine Einschränkung für den Server. Wo ist der Flaschenhals?

Was passiert, wenn z.B. Stellen Sie ServicePointManager.DefaultConnectionLimit auf 2 und starten Sie 4 Aufgaben? Werden sie nicht nacheinander serviert? Ähnlich wie zum Beispiel 128 und 1000. Aber irgendwo hört es auf zu skalieren. Wie kann ich weiter untersuchen, was der Flaschenhals ist? Ich bekomme nur eine TaskCanceledException, und diese tragen keine weiteren Details. Irgendwelche Tipps?

Antwort

2

Ich ging nicht in Codedetails Ihrer Github-Lösung, aber das riecht als erwartetes Verhalten. Es gibt eine Einstellung der maximalen Verbindungsnummern pro ServicePoint und seine normale, dass Sie Verbindungen bei länger laufenden Anforderungen schneller ausführen, wenn Sie parallel asynchrone Ausführung ausführen.

Dies könnte ein guter Ausgangspunkt sein: https://docs.microsoft.com/en-us/dotnet/framework/network-programming/managing-connections

Es gibt keine definitive, einheitliche Antwort auf die Frage, wie viele Verbindungen in Ordnung ist, aber Sie sollten Ihre MaxDegreeOfParalelism unter der Nummer Ihrer maximalen Verbindungen halten erlaubt und Sie sind sicher .

[UPDATE]

Auch, was Sie einen Blick nehmen möchten bei System.Net.Http.WinHttpHandler ist:

https://msdn.microsoft.com/en-us/library/system.net.http.winhttphandler(v=vs.105).aspx

Wenn Sie eine Instanz von HttpClient machen, man kann so etwas tun :

var httpMessageHandler = new System.Net.Http.WinHttpHandler(); 
//here you set different handler options (see docs link above) 
var httpClient = new HttpClient(httpMessageHandler); 
+0

Vielen Dank für Ihre Antwort. Ich werde in den WinHttpHandler schauen. Aber wenn man darüber nachdenkt, ist das nicht ein Problem damit, wie HttpClient den HttpConnections Nachrichten zuweist? Wenn ich alle Anfragen in Serie abspiele, gelingt das natürlich, wenn auch langsam. Dann benutzt es nur 1 Verbindung. Sollte HttpClient das nicht gut handhaben, so dass alle Aufgaben, die RequestMessages senden, gut in der Warteschlange stehen und der Anzahl der verfügbaren HttpConnections zugewiesen werden? Also, wenn ich 2 Verbindungen hatte, sollte es in der Hälfte der Zeit enden, wenn 16, 1/16 der Zeit, usw. verwendet wird? Ich kann sehen, dass die Nachrichten Verbindungen zugewiesen werden, wenn sie verfolgt werden. –

+0

genau, aber wie würde httpclient die Anzahl der verfügbaren Verbindungen wissen, wenn Sie es nicht sagen? Sie können HTTP-Client-Anfragen unter Windows zu Hause mit maximal 4 oder 10 Verbindungen oder auf einem Server mit maximal 10000 Verbindungen ausführen. und sie werden anfangen, Probleme in verschiedenen Schwellen zu melden. –