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.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).
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ć.
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.
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.
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.
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ą.
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