Gniazdo ZeroMQ pub buforuje wszystkie moje dane wychodzące podczas łączenia

Zauważyłem, że gniazdo ZeroMQ pub buforuje wszystkie wychodzące dane, jeśli jest podłączone, na przykład

import zmq
import time
context = zmq.Context()

# create a PUB socket
pub = context.socket (zmq.PUB)
pub.connect("tcp://127.0.0.1:5566")
# push some message before connected
# they should be dropped
for i in range(5):
    pub.send('a message should not be dropped')

time.sleep(1)

# create a SUB socket
sub = context.socket (zmq.SUB)
sub.bind("tcp://127.0.0.1:5566")
sub.setsockopt(zmq.SUBSCRIBE, "")

time.sleep(1)

# this is the only message we should see in SUB
pub.send('hi')

while True:
    print sub.recv()

Sub wiąże się po tych wiadomościach, powinny one zostać porzucone, ponieważ PUB powinien upuszczać wiadomości, Jeśli nikt się z nimi nie połączy. Ale zamiast upuszczać wiadomości, buforuje wszystkie wiadomości.

a message should not be dropped
a message should not be dropped
a message should not be dropped
a message should not be dropped
a message should not be dropped
hi

Jak widać, te "wiadomość nie powinna być upuszczona" są buforowane przez gniazdo, po podłączeniu przepuszcza je do gniazda podrzędnego. Jeśli zwiążę w pubie gniazdo i podłącz do gniazda SUB, a następnie działa poprawnie.

import zmq
import time
context = zmq.Context()

# create a PUB socket
pub = context.socket (zmq.PUB)
pub.bind("tcp://127.0.0.1:5566")
# push some message before connected
# they should be dropped
for i in range(5):
    pub.send('a message should not be dropped')

time.sleep(1)

# create a SUB socket
sub = context.socket (zmq.SUB)
sub.connect("tcp://127.0.0.1:5566")
sub.setsockopt(zmq.SUBSCRIBE, "")

time.sleep(1)

# this is the only message we should see in SUB
pub.send('hi')

while True:
    print repr(sub.recv())

I możesz zobaczyć tylko wyjście

'hi'

Tego rodzaju dziwne zachowanie powoduje problem, buforuje wszystkie dane na gniazdku łączącym, mam dwa serwery, serwer a publikuje dane na serwerze B

Server A -- publish --> Server B

Działa dobrze, jeśli serwer B zostanie włączony. Ale co jeśli uruchomię serwer A i nie uruchomię serwera B?

W rezultacie podłączenie gniazda PUB na serwerze a przechowuje wszystkie te dane, zużycie pamięci wzrasta i wyżej.

Tu jest problem, czy takie zachowanie to błąd czy funkcja? Jeśli jest to funkcja, gdzie mogę znaleźć dokument, który wspomina o tym zachowaniu? I jak Mogę zatrzymać łączenie pub socket buforuje wszystkie dane?

Dzięki.
Author: Fang-Pen Lin, 2012-01-21

6 answers

To, czy gniazdo blokuje lub upuszcza wiadomości, zależy od typu gniazda, jak opisano w dokumentacji ZMQ::Socket (podkreślenie poniżej jest moje):

ZMQ::HWM::]}

Opcja ZMQ::HWM pobiera znak wysokiej wody dla określone Gniazdo. Znak wysokiej wody to twarda granica na maksimum liczba nierozliczonych wiadomości 0MQ jest kolejkowana w pamięci dla dowolnego pojedynczy peer, z którym komunikuje się określone Gniazdo.

Jeżeli limit ten został osiągnięty, Gniazdo wprowadza wyjątkową stanu i w zależności od typu gniazda, 0MQ przyjmuje odpowiednie działania takie jak blokowanie lub upuszczanie wysłanych wiadomości. Zobacz opisy poszczególnych gniazd w ZMQ:: Gniazdo dla dokładnych działania podejmowane dla każdego typu gniazd.

Domyślna wartość ZMQ:: HWM o wartości zero oznacza "bez limitu".

Możesz sprawdzić, czy zablokuje się lub spadnie, przeglądając dokumentację dla Typ gniazda dla ZMQ::HWM option action, który będzie Block lub Drop.

Akcja dla ZMQ::PUB to Drop, więc jeśli nie spada, powinieneś sprawdzić wartość HWM (High Water Mark) i zwrócić uwagę na ostrzeżenie, że domyślna wartość ZMQ:: HWM o wartości zero oznacza "bez limitu", co oznacza, że nie wejdzie w wyjątkowy stan, dopóki system nie skończy się pamięć (w którym momencie Nie wiem, jak się zachowuje).

 6
Author: aculich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-22 03:29:08

Wydaje mi się, że to zachowanie jest semantyczne zmq_connect(). Oznacza to, że: gdy zmq_connect () zwróci sukces, to połączenie zostanie ustanowione koncepcyjnie i w ten sposób twój connecting-PUB zacznie kolejkować wiadomość zamiast upuszczać .

Poniższy fragment "ZMQ Guide " jest podpowiedzią na ten temat:

W teorii z gniazdami ØMQ nie ma znaczenia, który koniec się łączy, a który koniec wiąże. Jednak z gniazdami PUB-SUB, jeśli połączysz SUB gniazdo i podłączenie Gniazdo PUB, Gniazdo SUB może odbierać stare wiadomości, czyli wiadomości wysłane przed uruchomieniem SUB. to jest artefakt sposobu działania bind / connect. najlepiej związać PUB i podłącz Łódź, jeśli możesz.

Następująca sekcja w zmq_connect () zawiera kilka wskazówek, pokazanych poniżej:

Kluczowe różnice w stosunku do konwencjonalnych gniazd

Ogólnie rzecz biorąc, konwencjonalne gniazda prezentują synchroniczny interfejs do niezawodne strumienie bajtów zorientowane na połączenie (SOCK_STREAM) lub nierzetelne datagramy (SOCK_DGRAM). Dla porównania gniazda ØMQ prezentują abstrakcję asynchronicznego kolejki komunikatów, z dokładną semantyką kolejkowania w zależności od Typ gniazda w użyciu. Gdzie konwencjonalne gniazda przenoszą strumienie bajtów lub dyskretnych datagramów, gniazda ØMQ przesyłają dyskretne wiadomości.

gniazda ØMQ jako asynchroniczne oznacza, że timingi fizyczne połączenie konfiguracja i zburzenie, ponowne połączenie i skuteczne dostarczanie są przejrzyste dla użytkownika i zorganizowane przez samego ØMQ. Ponadto wiadomości mogą być ustawione w kolejce w przypadku, gdy peer nie może ich otrzymać.

 4
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-04 10:33:38

Ustawiają opcję HWM na gnieździe.

 1
Author: sustrik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-21 23:28:39

Więc bind () i connect() powodują dwa różne zachowania. Dlaczego po prostu nie wybierzesz tego, który wolisz (wydaje się, że bind ()) i nie użyjesz tego?

Cechą ZeroMQ jest to, że buforuje wiadomości wychodzące do momentu nawiązania połączenia.

 0
Author: John Zwinck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-21 16:41:22

Powinieneś być w stanie ustawić znak wysokiej wody w gnieździe za pomocą HWM settingom the Pub socket. Pozwala określić, ile wiadomości jest przechowywanych.

 0
Author: mgoetzke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-21 20:45:46

Oto hack, który może pomóc...

Ustaw ZMQ::HWM Na stałą liczbę, powiedzmy 10. Po podłączeniu wywołaj metodę recv gniazda abonenckiego w pętli, aż odrzuci ona wszystkie buforowane wiadomości, a dopiero potem Uruchom główną pętlę odbiorczą.

 0
Author: Yike Lu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-22 01:06:21