2010-11-25 10 views
5

Ich benutze ActiveMQ in einem .Net-Programm und ich bin mit Nachrichten-Ereignissen überflutet.Wie kann ich die Menge an Nachrichten, die von ActiveMQ in meiner C# -App kommen, drosseln?

Kurz gesagt, wenn ich ein Queue-Ereignis 'onMessage (IMessage receivedMsg)' bekomme, lege ich die Nachricht in eine interne Warteschlange, aus der X-Threads ihre Sache machen.

Zuerst hatte ich: "AcknowledgementMode.AutoAcknowledge" beim Erstellen der Sitzung, so nehme ich an, dass alle Nachrichten in der Warteschlange wurde abgesaugt und in die Speicherwarteschlange (was ist riskant, da mit einem Absturz, alles ist) hat verloren).

Also habe ich verwendet: 'AcknowledgementMode.ClientAcknowledge' beim Erstellen der Sitzung, und wenn ein Arbeiter mit der Nachricht fertig war, ruft er die 'commit()' Methode für die Nachricht auf. Allerdings werden immer noch alle Nachrichten aus der Warteschlange abgesaugt.

Wie kann ich konfigurieren, dass NUR eine X Anzahl von Nachrichten verarbeitet wird oder sich in einer internen Warteschlange befindet und nicht alles sofort heruntergeladen wird?

+0

Obwohl ich ActiveMQ nie berührt habe - können Sie das nicht umdrehen: Richten Sie N Threads mit ActiveMQ-Listenern ein und verarbeiten Sie die Nachrichten innerhalb des Listenereignisses? –

+0

@will hughes: mein ganzes Programm ist auf eine asynchrone Weise geschrieben. So wird sogar der DB-Zugriff asynchron mit Rückrufen durchgeführt. Also kann ich nicht bei der Veranstaltung bleiben. – Toad

Antwort

3

Sind Sie auf .NET 4.0? Sie könnten eine BlockingCollection verwenden. Stellen Sie es auf die maximale Menge ein, die es enthalten kann. Sobald ein Thread versucht, ein überschüssiges Element einzufügen, blockiert die Add-Operation, bis die Sammlung erneut unter den Schwellenwert fällt.

Vielleicht würde das für die Drosselung tun?

Es gibt auch eine API für die Drosselung im Rx-Framework, aber ich weiß nicht, wie es implementiert ist. Wenn Sie Ihre Queue-Quelle als Observable implementieren, wird diese API für Sie verfügbar sein, aber ich weiß nicht, ob dies Ihren Anforderungen entspricht.

+0

große Antwort! Klappt wunderbar. Danke – Toad

2

Sie können den Client-Vorabruf so einstellen, dass gesteuert wird, wie viele Nachrichten der Client gesendet wird. Wenn die Sitzung automatisch bestätigt wird, bestätigt der Client nur dann eine Nachricht, wenn sie über den Rückruf von onMessage oder einen synchronen Empfang an Ihre App gesendet wurde. Standardmäßig ruft der Client 1000 Nachrichten vom Broker ab. Wenn der Client ausfällt, werden diese Nachrichten an einen anderen Client zurückgegeben, wenn dies eine Warteschlange ist. Andernfalls werden sie für ein Thema einfach verworfen, da es sich um einen broadcastbasierten Kanal handelt. Wenn Sie den Vorabruf auf 1 setzen, wird Ihr Client nur eine Nachricht vom Server gesendet, und jedes Mal, wenn Ihr onMessage-Rückruf abgeschlossen ist, wird eine neue Nachricht gesendet, da der Client diese Nachricht bestätigt, dh wenn die Sitzung in Auto Ack ist Modus.

finden Sie in der NMS-Konfigurationsseite für alle Optionen: http://activemq.apache.org/nms/configuring.html

Grüße

Tim.

+0

Bish: Leider, selbst wenn ich auf clientacknowledge setze, wird die Warteschlange so viele Ereignisse auslösen, wie Nachrichten in der Warteschlange sind. Ich habe es mit 10.000 messqges in der Warteschlange getestet und sie werden gefeuert, ohne dass ich etwas anerkenne. Die einzige Möglichkeit, dies zu stoppen, besteht darin, die onMessage zu stoppen, bis ich sie verarbeitet habe. – Toad

+0

Hört sich an, als wäre Ihr Programmiermodell durch die synchronen Empfangsanrufe besser geeignet, dann können Sie alles drosseln, was Sie wollen. Der Sinn des Messaging-Systems besteht darin, Nachrichten so schnell wie möglich zuzustellen, damit Ihre App mit der Drosselung umgehen kann. –