Frage

begann ich ZeroMQ in dieser Woche mit, und wenn das Request-Response-Muster unter Verwendung bin ich nicht sicher, wie ein Arbeiter zu haben, sicher „aufhängen“ und schließen Sie seine Steckdose ohne möglicherweise eine Nachricht löschen und wodurch den Kunden, der die Nachricht gesendet nie eine Antwort erhalten. Stellen Sie sich einen Arbeiter in Python geschrieben, die etwa wie folgt aussieht:

import zmq
c = zmq.Context()
s = c.socket(zmq.REP)
s.connect('tcp://127.0.0.1:9999')
while i in range(8):
    s.recv()
    s.send('reply')
s.close()

Ich habe Experimente getan und festgestellt habe, dass ein Kunde bei 127.0.0.1:9999 von Socket-Typ zmq.REQ, die eine faire-Warteschlange macht Anfrage nur das Pech mit dem Fair-Queuing-Algorithmus haben könnte, die oben Arbeiter direkt wählen, nachdem der Arbeiter seine getan hat letzte send() aber bevor es läuft die folgende close() Methode. In diesem Fall scheint es, dass der Antrag vom omq Stapel in den Arbeitsprozess empfangen und gepuffert, und dass der Antrag wird dann verloren, wenn close() alles mit dem Socket wirft.

Wie kann ein Arbeiter detach „sicher“ - ist es eine Möglichkeit, um das Signal „Ich mag Nachrichten nicht mehr“, dann (a) eine Schleife über eine endgültigen Nachrichten, die während der Übertragung des Signals angekommen sind, (b) erzeugen ihre Antworten, und dann (c) ausführen close() mit der Garantie, dass keine Nachrichten weggeworfen werden?

Edit: Ich nehme an dem Rohzustand, dass ich mag, gebe einen „halbgeschlossenen“ Zustand, in dem keine weiteren Anfragen empfangen werden können - und der Absender würde wissen, dass - wo aber die Rückpfad immer noch offen ist, so dass ich meine eingehenden Puffer für eine letzte Nachricht angekommen und reagiert auf sie überprüfen, ob es eine Sitzung im Puffer ist.

Edit: In Antwort auf eine gute Frage, korrigiert die Beschreibung, die Anzahl der machen wartenden Nachrichten Plural, da es viele Verbindungen wartet auf Antworten könnte

.
War es hilfreich?

Lösung

Sie scheinen zu glauben, dass Sie versuchen, eine „einfache“ Race-Bedingung wie in

zu vermeiden
... = zmq_recv(fd);
do_something();
zmq_send(fd, answer);
/* Let's hope a new request does not arrive just now, please close it quickly! */
zmq_close(fd);

, aber ich denke, das Problem ist, dass Fair Queuing (Round-Robin) macht die Sache noch schwieriger: Sie vielleicht schon einmal mehrere Anforderungen in der Warteschlange auf Ihrem Arbeitnehmer haben. Der Absender wird nicht für Ihre Arbeiter warten, frei zu sein, bevor sie eine neue Anforderung senden, wenn er seinerseits ein erhalten, so zum Zeitpunkt des zmq_send andere Anfragen rufen Sie vielleicht schon warten.

In der Tat sieht es aus wie Sie die falsche Datenrichtung gewählt haben könnten. Anstatt eine Anfrage mit Pool senden Anforderungen an Ihren Mitarbeitern (auch wenn Sie es vorziehen, nicht neue erhalten), mögen Sie vielleicht Ihre Mitarbeiter haben eine neue Anforderung von einer Anforderung in einer Warteschlange, kümmert sich um sie zu holen, dann die Antwort senden.

Natürlich ist es bedeutet, mit XREP / XREQ, aber ich denke, es ist es wert.

Edit: Ich schrieb einige Code Implementierung die andere Richtung zu erklären, was ich meine.

Andere Tipps

Ich denke, das Problem ist, dass Ihre Messaging-Architektur ist falsch. Ihre Mitarbeiter sollten einen REQ-Buchse verwenden, um eine Anforderung für die Arbeit zu schicken und auf diese Weise immer nur eine Stelle bei dem Arbeiter der Warteschlange ist. Dann Abschluss der Arbeiten zu bestätigen, können Sie entweder eine andere REQ Anforderung verwenden, die doppelt als ack für den vorherigen Job und Antrag auf eine neue, oder Sie können eine zweite Steuerbuchse haben.

Manche Menschen tun dies mit PUB / SUB für die Steuerung, so dass jeder Arbeiter acks und die Master abonniert sie veröffentlicht.

Sie müssen bedenken, dass mit ZeroMQ gibt es 0 Nachrichtenwarteschlangen. Überhaupt keine! Nur Nachrichten in entweder dem Sender oder Empfänger je nach Einstellung wie High-Water-Mark gepuffert, und die Art der Buchse. Wenn Sie wirklich brauchen, Nachrichtenwarteschlangen tun, dann müssen Sie ein Broker App zu schreiben, zu handhaben, oder schalten Sie einfach auf AMQP, wo die gesamte Kommunikation über eine 3rd-Party-Broker ist.

Ich habe auch darüber nachgedacht. Vielleicht möchten Sie eine SCHLIEßEN Nachricht implementieren, die den Kunden darüber informiert, dass der Arbeitnehmer weggeht. Sie könnten dann für einen bestimmten Zeitraum, den Arbeiter Drain haben vor dem Herunterfahren. Nicht ideal, natürlich, aber vielleicht bearbeitbar sein.

Es gibt einen Interessenkonflikt zwischen den Anfragen so schnell wie möglich für die Arbeitnehmer zu senden, und immer Zuverlässigkeit bei einem bearbeiteten abstürzt oder stirbt. Es gibt einen ganzen Abschnitt des ZeroMQ Führer, die verschiedene Antworten auf diese Frage der Zuverlässigkeit erklärt. Lesen Sie, dass, es wird eine Menge helfen.

tl; dr Arbeiter können / abstürzen und Kunden benötigen eine resend Funktionalität. Der Leitfaden bietet wieder verwendbaren Code für das, in vielen Sprachen.

Wäre das nicht die einfachste Lösung sein, die Kunden Timeout zu haben, wenn die Antwort zu warten und dann erneut versuchen, wenn keine Antwort empfangen wird?

Versuchen Sie vor dem Aufruf der Nähe schlafen. Dies wird in 2.1 behoben, aber nicht in 2.0 vor.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top