Das Lesen von MSMQ wird langsamer, wenn viele Nachrichten in der Warteschlange stehen

8

Kurze Einführung

Ich habe ein SEDA-basiertes System und verwendete MSMQ für die Kommunikation (Ereignisauslösung) zwischen den verschiedenen Anwendungen / Diensten.

Einer dieser Dienste ruft Nachrichten nach Datei ab, also habe ich einen Datei-Listener, der den Dateiinhalt liest und diesen in eine Warteschlange einfügt (oder tatsächlich vier verschiedene Warteschlangen, aber das ist nicht sehr wichtig für die erste Frage).

Server ist Windows Server 2008

Erste Frage - Lesen wird langsamer

Meine Anwendung, die diese Nachrichten auf der anderen Seite liest, liest in der Regel etwa 20 Nachrichten pro Sekunde aus der Warteschlange, aber wenn der Dienst, der Nachrichten versendet, einige tausend Nachrichten in die Warteschlange stellt, geht der Lesevorgang aus und die Leseanwendung liest nur zwei. 4 Nachrichten pro Sekunde. Wenn keine Buchung in der Warteschlange vorhanden ist, kann die Leseanwendung erneut bis zu 20 Nachrichten pro Sekunde lesen.

Der Code in der Leseanwendung ist ziemlich einfach, in C # entwickelt, verwende ich die Funktion Read (TimeSpan Timeout) in System.Messaging.

F: Warum wird das Lesen verlangsamt, wenn viele Nachrichten in die Warteschlange gestellt werden?

Zweite Frage - Einschränkungen von TPS

Eine zusätzliche Frage betrifft das Lesen selbst. Es scheint keinen Unterschied zu geben, wie viele Nachrichten ich pro Sekunde lesen kann, wenn ich 1 oder 5 Threads zum Lesen aus der Warteschlange verwende. Ich habe auch versucht, eine "Round-Robin-Lösung" zu implementieren, wo der Post-Service in einen zufälligen Satz von 4 Warteschlangen posten würde, und die Leseanwendung hatte einen Thread, der jede dieser Warteschlangen abhört, aber es gibt immer noch nur 20 TPS Lesen von 1 Warteschlange mit 1 Thread, 1 Warteschlange mit 4 Threads oder 4 Warteschlangen (mit einem Thread pro Warteschlange).

Ich weiß, dass die Verarbeitung im Thread ungefähr 50 ms dauert, also 20 TPS ist ziemlich korrekt, wenn nur eine Nachricht zu der Zeit verarbeitet wird, aber der Hinweis bei Multi Threading sollte sein, dass Nachrichten parallel und nicht sequentiell behandelt werden.

Es gibt ungefähr 110 verschiedene Warteschlangen auf dem Server.

F: Warum kann ich zu diesem Zeitpunkt nicht mehr als 20 Nachrichten aus meiner Warteschlange abrufen, selbst wenn mehrere Threads verwendet werden und mehrere Warteschlangen verwendet werden?

Dies ist der Code, der heute läuft:

%Vor%

Aber selbst wenn es 4 Threads gibt, scheint alles darauf zu warten, dass die Funktion den "Empfang" -Punkt erneut eingibt. Ich habe auch versucht, 4 verschiedene Warteschlangen (content1, content2, content3 und content4), aber ich bekomme immer noch 1 Nachricht alle 50 ms verarbeitet.

Hat das etwas mit dem TimeSpan in Receive () zu tun, und / oder ist es möglich, dies wegzulassen?

Eine andere Frage ist, ob die Verwendung privater Warteschlangen, die nicht öffentlich sind, alles lösen wird?

    
Manfred Bjorlin 27.06.2011, 10:22
quelle

2 Antworten

4

Leistungsprobleme.
Sie erwähnen nicht, ob der gesamte Code auf dem Server ausgeführt wird oder ob Clients remote auf die Warteschlangen auf dem Server zugreifen. Von der Geschwindigkeit nehme ich das letztere an.
Sind auch die Warteschlangen transaktional? Wie groß sind die Nachrichten?

Wenn Sie eine Nachricht aus einer Warteschlange lesen möchten, stellt Ihre Anwendung keine Verbindung zur Warteschlange her. Alles zwischen dem lokalen Warteschlangenmanager und dem fernen Warteschlangenmanager. Der Warteschlangenmanager ist der einzige Prozess, der in Warteschlangen schreibt und von diesen liest. Wenn mehrere Warteschlangen oder eine einzelne Warteschlange vorhanden sind, wird das nicht unbedingt anders funktionieren.

Der MSMQ-Warteschlangenmanager wird daher zu einem bestimmten Zeitpunkt ein Engpass sein, da es nur so viel Arbeit gleichzeitig gibt. Ihre erste Frage zeigt dies: Wenn Sie den Warteschlangenmanager stark belasten, der Nachrichten einfügt, verlangsamt sich Ihre Fähigkeit Nachrichten zu empfangen. Ich würde empfehlen, Leistungsmonitor zu sehen, um zu sehen, ob MQSVC.EXE zum Beispiel ausgereizt ist.

    
John Breakwell 27.06.2011 12:31
quelle
2

Warum verwenden Sie die Zeitspanne? - Das ist eine schlechte Sache und hier ist warum.

Beim Entwickeln von Diensten und der Warteschlange müssen Sie auf theadsafe-Weise programmieren. Jedes Element in der Warteschlange erzeugt einen neuen Thread. Durch das Verwenden der Zeitspanne werden die einzelnen Threads gezwungen, einen einzelnen Timer-Ereignis-Thread zu verwenden. Diese Ereignisse müssen warten, bis sie an der Reihe sind.

Die Norm ist 1 Thread pro Warteschlangenereignisse. Dies ist im Allgemeinen Ihr System.Messaging.ReceiveCompletedEventArgs-Ereignis. Ein anderer Thread ist dein onStart Event ...

20 Threads oder 20 Lesevorgänge pro Sekunde sind wahrscheinlich richtig. Im Allgemeinen können Sie beim Thread-Pooling nur 36 Threads gleichzeitig in .net erstellen.

Mein Rat ist, das Timer-Ereignis zu löschen und Ihre Warteschlange einfach die Daten verarbeiten zu lassen.

mach etwas mehr so;

%Vor%     
KenL 27.06.2011 11:22
quelle

Tags und Links