Ich habe eine Serverkomponente, die über Zeroc-ICE läuft. Als ich es laden wollte, dachte ich, dass die Verwendung einer parallelen Bibliothek zum Erstellen mehrerer Anforderungen dies tun würde. Aber es wird nicht so enden. Das Verwenden der Parallel (Parallel.For) -Bibliothek aus C # war anscheinend einfacher, aber es scheint nicht genau zu sein, dass alles parallel im selben Moment generiert wird. Es kann also nicht die Definition für das Erstellen von N Anforderungen pro Sekunde sein. Wie soll ich das machen Ich denke, jeder, der zuerst Lasttests durchführen möchte, würde darüber nachdenken.
Was ist der effiziente Weg, um tatsächlich N Anfragen in wirklich einer Sekunde zu erstellen?
Ein weiterer Mythos handelt von der parallelen Programmierung. Bitte klären Sie uns auf, wenn Sie in C # oder .Net generell parallele Programmiermuster verwendet haben. Stellen Sie sich vor, ich habe 5 Prozesse. Wie werden alle fünf Prozesse gleichzeitig gestartet? Was bedeutet es für meinen Ressourcenverbrauch? Ich habe versucht, in viele Materialien zu lesen, die über das Internet verfügbar sind, aber ich bekomme immer mehr Fragen als die Antwort auf meine Fragen.
Ich habe Parallel.For verwendet und N Threads erstellt und die Zeit gemessen. Dann habe ich dasselbe mit Task.Factory.start für die Aufzählung von Aufgaben versucht. Die gemessene Zeit war unterschiedlich. Was genau ist der Unterschied zwischen diesen? Wann und für welche Zwecke sollte ich die entsprechenden Klassen verwenden? Wir haben oft viele Reichtümer, aber es ist nur so, dass wir nicht genau wissen, wie wir uns voneinander unterscheiden können. Dies ist ein solcher Fall für mich, nicht in der Lage zu finden, warum ich nicht eine von der anderen verwenden sollte.
Ich habe die Stoppuhr verwendet, um diese Zeiten zu messen, die als die besten gelten. In dem Szenario, in dem ich eine Komponente beim Laden teste, ist dies die Methode zum Messen der Reaktionszeit. Stoppuhr scheint für mich die beste Lösung zu sein. Alle Meinungen sind willkommen.
ps: Es gibt viele Lasttest-Tools für Webanwendungen. Meins ist ein kundenspezifischer Fall von Serverkomponenten. Und meine Frage bezieht sich eher auf das Erstellen von N Threads pro Sekunde.
Alle Meinungen sind willkommen. Denken Sie nur nicht, dass es so sehr keine Programmierfrage ist. Es ist selbstverständlich. Es sollte für jeden Programmierer, der die Leistung seines Produkts selbst testen möchte, ein Kinderspiel sein. Ich habe viele Optionen ausprobiert und musste dann darauf zurückgreifen, wie ich es tatsächlich tun sollte.
quelle
Antworten:
Ich habe nicht alle Antworten. Hoffentlich kann ich etwas Licht ins Dunkel bringen.
Um meine vorherigen Aussagen zu .NETs Threading-Modellen zu vereinfachen, müssen Sie lediglich wissen, dass die Parallel Library Tasks verwendet und der standardmäßige TaskScheduler für Tasks den ThreadPool verwendet. Je höher Ihre Position in der Hierarchie ist (ThreadPool befindet sich unten), desto mehr Aufwand haben Sie beim Erstellen der Elemente. Dieser zusätzliche Aufwand bedeutet sicherlich nicht, dass er langsamer ist, aber es ist gut zu wissen, dass er vorhanden ist. Letztendlich hängt die Leistung Ihres Algorithmus in einer Umgebung mit mehreren Threads von seinem Design ab. Was sequentiell gut abschneidet, läuft möglicherweise nicht so gut parallel. Es sind zu viele Faktoren involviert, um Ihnen feste und schnelle Regeln zu geben. Sie ändern sich je nachdem, was Sie tun möchten. Da Sie sich mit Netzwerkanforderungen befassen, werde ich versuchen, ein kleines Beispiel zu geben.
Lassen Sie mich feststellen, dass ich kein Experte für Steckdosen bin und so gut wie nichts über Zeroc-Ice weiß. Ich weiß ein bisschen über asynchrone Operationen Bescheid, und hier wird es Ihnen wirklich helfen. Wenn Sie eine synchrone Anfrage über einen Socket senden
Socket.Receive()
, wird Ihr Thread beim Aufruf blockiert, bis eine Anfrage eingeht. Das ist nicht gut. Dein Thread kann keine Anfragen mehr stellen, da er blockiert ist. Mit Socket.Beginxxxxxx () wird die E / A-Anforderung gestellt und in die IRP-Warteschlange für den Socket gestellt, und Ihr Thread wird fortgesetzt. Dies bedeutet, dass Ihr Thread tatsächlich Tausende von Anfragen in einer Schleife stellen kann, ohne dass diese blockiert werden!Wenn ich Sie richtig verstehe, verwenden Sie Anrufe über Zeroc-Ice in Ihrem Testcode und versuchen nicht, einen http-Endpunkt zu erreichen. In diesem Fall kann ich zugeben, dass ich nicht weiß, wie Zeroc-Ice funktioniert. Ich würde allerdings vorschlagen , im Anschluss an die Beratung hier aufgeführt , insbesondere den Teil:
Consider Asynchronous Method Invocation (AMI)
. Die Seite zeigt dies:Das scheint das Äquivalent zu dem zu sein, was ich oben unter Verwendung von .NET-Sockets beschrieben habe. Möglicherweise gibt es andere Möglichkeiten, die Leistung zu verbessern, wenn Sie versuchen, viele Sendevorgänge durchzuführen, aber ich würde hier oder mit einem anderen Vorschlag beginnen, der auf dieser Seite aufgeführt ist. Sie waren in Bezug auf das Design Ihrer Anwendung sehr vage, sodass ich genauer sein kann als oben. Denken Sie daran, verwenden Sie nicht mehr Threads als unbedingt erforderlich , um das zu erledigen, was Sie benötigen. Andernfalls wird Ihre Anwendung wahrscheinlich viel langsamer ausgeführt, als Sie möchten.
Einige Beispiele im Pseudocode (versucht, es so nah wie möglich am Eis zu machen, ohne dass ich es wirklich lernen muss):
Ein besserer Weg:
Denken Sie daran, dass mehr Threads! = Bessere Leistung beim Versuch, Sockets zu senden (oder wirklich etwas zu tun). Threads sind insofern keine Zauberei, als sie automatisch jedes Problem lösen, an dem Sie arbeiten. Idealerweise möchten Sie 1 Thread pro Kern, wenn ein Thread nicht viel Zeit damit verbringt, zu warten, dann können Sie mehr rechtfertigen. Das Ausführen jeder Anforderung in einem eigenen Thread ist eine schlechte Idee, da Kontextwechsel auftreten und Ressourcen verschwendet werden. (Wenn Sie alles sehen möchten, was ich darüber geschrieben habe, klicken Sie auf Bearbeiten und sehen Sie sich die früheren Überarbeitungen dieses Beitrags an. Ich habe ihn entfernt, da er nur das Hauptproblem zu trüben schien.)
Sie können diese Anfrage definitiv in Threads stellen, wenn Sie eine große Anzahl von Anfragen pro Sekunde stellen möchten. Gehen Sie jedoch bei der Thread-Erstellung nicht über Bord. Finde ein Gleichgewicht und bleibe dabei. Sie erzielen eine bessere Leistung, wenn Sie ein asynchrones Modell im Vergleich zu einem synchronen Modell verwenden.
Ich hoffe das hilft.
quelle
Ich werde Frage 1) überspringen und gleich zu Frage 2 übergehen, da dies im Allgemeinen ein akzeptabler Weg ist, um das zu erreichen, was Sie suchen. Um in der Vergangenheit n Nachrichten pro Sekunde zu erzielen , können Sie einen einzelnen Prozess erstellen, mit dem p AppDomains gestartet werden. Grundsätzlich startet jede AppDomain eine Anforderungsschleife erst, wenn ein bestimmter Zeitpunkt erreicht ist (mithilfe eines Timers). Diese Zeit sollte für jede AppDomain gleich sein, um sicherzustellen, dass sie zum gleichen Zeitpunkt auf Ihren Server trifft.
So etwas sollte für das Senden Ihrer Anfragen funktionieren:
Dies wird wahrscheinlich die Leistung auf jedem Computer beeinträchtigen, auf dem Sie es ausführen, sodass Sie immer eine ähnliche Art von Schleife von mehreren verschiedenen Computern implementieren können, wenn Sie über die Ressourcen verfügen (indem Sie Prozesse anstelle von Anwendungsdomänen verwenden).
Geben Sie für Ihre dritte Frage diesen Link ein: http://www.albahari.com/threading/
Schließlich sollte eine Stoppuhr mit einem Trefferzähler gekoppelt werden, um sowohl die Dauer als auch die eindeutigen Treffer auf Ihrem Server zu verfolgen. Damit sollten Sie nachträglich einige Analysen durchführen können.
quelle
Kümmere dich nicht um Fäden, wenn N einigermaßen klein ist. Verwenden Sie die Wanduhrzeit (
DateTime.Now
), um N Anforderungen pro Sekunde zu generieren . Nehmen Sie sich die Zeit vor und nach der Anforderung und fügen Sie ein hinzuSleep
, um die nächste Anforderung zu verzögern.Zum Beispiel mit N = 5 (200 ms):
Das ist nicht perfekt; Vielleicht finden Sie, dass
Sleep
das nicht genau ist. Sie können die Abweichungen fortlaufend zählen (vor der X-ten Anforderung sollte die Zeit später X-1 / N betragen) und die Ruhezeit entsprechend anpassen.Sobald N zu groß wird, erstellen Sie einfach M Threads und lassen jeden Thread N / M-Anforderungen auf dieselbe Weise generieren.
quelle
Der einfachste Weg, Lasttests für ein .NET-Projekt durchzuführen, ist der Kauf der Ultimate Edition von Visual Studio. Dies wird mit einem integrierten Testwerkzeug geliefert, mit dessen Hilfe alle Arten von Tests einschließlich Belastungstests durchgeführt werden können. Lasttests können durchgeführt werden, indem virtuelle Benutzer entweder auf einem einzelnen PC oder auf mehrere verteilt für eine größere Anzahl von Benutzern erstellt werden. Auf den Zielservern kann auch ein kleines Programm installiert werden, das zusätzliche Daten für die Dauer des Tests zurückgibt.
Dies ist zwar teuer, aber die ultimative Edition enthält viele Funktionen. Wenn also alle verwendet würden, wäre der Preis angemessener.
quelle
Wenn Sie möchten, dass alle X-Threads genau zur gleichen Zeit auf Ihre Ressource treffen, können Sie jeden Thread hinter einen Countdown-Latch setzen und eine kurze Wartezeit zwischen den Semaphorprüfungen festlegen.
C # hat eine Implementierung (http://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx).
Zur gleichen Zeit, wenn Sie Ihr System einem Stresstest unterziehen, möchten Sie möglicherweise auch die Rennbedingungen überprüfen. In diesem Fall möchten Sie für jeden Thread Ruheperioden einrichten, die mit zufälliger Häufigkeit und Peaks / Furloughs über die Zeit oszillieren.
In ähnlicher Weise möchten Sie möglicherweise nicht nur schnell mehrere Anforderungen senden, sondern können Ihren Server auch erfolgreicher in einen schlechten Zustand versetzen / seine tatsächliche Leistung testen, indem Sie eine kleinere Anzahl von Threads einrichten, die mehr Zeit für das Konsumieren und Zurücksenden von Nachrichten aufwenden und weiter über den Socket, da Ihr Server wahrscheinlich seine eigenen Threads hochfahren muss, um langsam laufende Nachrichten zu verarbeiten.
quelle