2016-03-21 10 views
7

Używam producenta RabbitMQ do wysyłania długotrwałych zadań (30 minut +) do klienta. Problem polega na tym, że konsument wciąż pracuje nad zadaniem, gdy połączenie z serwerem zostanie zamknięte, a żądanie niepotwierdzone zostanie zażądane.RabbitMQ zamyka połączenie podczas przetwarzania długich zadań, a ustawienia limitu czasu powodują błędy.

Z badań Rozumiem, że albo heartbeat lub increased connection timeout może być użyte do rozwiązania tego problemu. Oba te rozwiązania powodują błędy przy próbie ich. Czytając odpowiedzi na podobne posty, dowiedziałem się, że wiele zmian zostało zaimplementowanych w RabbitMQ od momentu opublikowania odpowiedzi (np. Domyślny limit czasu pulsu zmienił się na 60 z 580 przed RabbitMQ 3.5.5).

Określając bicie serca i zablokowany limit czasu połączenia: wyświetlany jest

credentials = pika.PlainCredentials('user', 'password') 
parameters = pika.ConnectionParameters('XXX.XXX.XXX.XXX', port, '/', credentials, blocked_connection_timeout=2000) 
connection = pika.BlockingConnection(parameters) 

channel = connection.channel() 

następujący błąd:

TypeError: __init__() got an unexpected keyword argument 'blocked_connection_timeout' 

Określając heartbeat_interval=1000 w związku Parametry podobny błąd jest pokazane: TypeError: __init__() got an unexpected keyword argument 'heartbeat_interval'

I podobnie dla socket_timeout = 1000 wyświetlany jest następujący błąd: TypeError: __init__() got an unexpected keyword argument 'socket_timeout'

Używam RabbitMQ 3.6.1, pika 0.10.0 i python 2.7 na Ubuntu 14.04.

  1. Dlaczego powyższe podejścia powodują powstawanie błędów?
  2. Czy można zastosować podejście pulsu w przypadku długotrwałego, ciągłego zadania? Na przykład czy można używać pulsu podczas wykonywania dużych połączeń z bazą danych, które trwają ponad 30 minut? Opowiadam się za podejściem opartym na biciu serca, ponieważ wiele razy trudno jest ocenić, jak długo potrwa zadanie takie jak dołączenie do bazy danych.

Czytałem poprzez odpowiedzi na podobne pytania

Aktualizacja: bieganie code from the pika documentation produkuje ten sam błąd.

+0

Czy przed serwerem królika znajduje się saldo obciążenia? To, jak wygląda twoje środowisko, może być istotne przy odpowiadaniu na to pytanie. – mschuett

+0

Maszyny producenta i konsumenta znajdują się w tej samej sieci prywatnej. – Greg

+1

Problem polega na tym, że musisz przetwarzać dane podczas oczekiwania, nawet jeśli nie zużywasz wiadomości; connection.process_data_events(). W przeciwnym razie pika nie reaguje na bicie serca. – eandersson

Odpowiedz

5

Wystąpił ten sam problem z moimi systemami, który widzisz, z przerwanym połączeniem podczas bardzo długich zadań.

Możliwe, że puls może pomóc utrzymać połączenie przy życiu, jeśli konfiguracja sieci jest taka, że ​​bezczynne połączenia TCP/IP są wymuszone upuszczeniem. Jeśli tak nie jest, zmiana bicia serca nie pomoże.

Zmiana limitu czasu połączenia w ogóle nie pomoże. To ustawienie jest używane tylko podczas początkowego tworzenia połączenia.

Używam producenta RabbitMQ do wysyłania długotrwałych zadań (30 minut +) do konsumenta. Problem polega na tym, że konsument wciąż pracuje nad zadaniem, gdy połączenie z serwerem zostanie zamknięte, a żądanie niepotwierdzone zostanie zażądane.

istnieją dwa powody, z których oba zostały prowadzone na już:

  1. Połączenia upuść losowo, nawet w najbardziej sprzyjających okolicznościach
  2. Ponowne rozpoczęcie procesu z powodu re -ukresowana wiadomość może powodować problemy

Po wdrożeniu kodu RabbitMQ z zadaniami w zakresie od mniej niż sekundy, do kilku godzin w czasie, stwierdziłem, że natychmiast potwierdzam komunikat i aktualizuję system z komunikatami o stanie działa najlepiej w przypadku bardzo długich zadań, takich jak ten.

Będziesz potrzebować systemu zapisu (prawdopodobnie z bazą danych), który śledzi status danego zadania.

Gdy konsument odbierze wiadomość i rozpocznie proces, powinien natychmiast potwierdzić komunikat i wysłać komunikat stanu "uruchomiono" do systemu zapisu.

Po zakończeniu procesu wyślij kolejną wiadomość, aby potwierdzić, że została wykonana.

Nie rozwiąże to problemu zerwanego połączenia, ale nic nie usunie go w 100%. Zapobiegnie to natomiast problemowi ponownej kolejki wiadomości po zerwaniu połączenia.

To rozwiązanie wprowadza jednak inny problem: kiedy trwa długi proces, jak wznowić pracę?

Podstawową odpowiedzią jest wykorzystanie statusu systemu rekordów (baza danych) do zadania, aby poinformować, że należy ponownie odebrać tę pracę. Po uruchomieniu aplikacji sprawdź bazę danych, aby zobaczyć, czy jest praca, która jest niedokończona. Jeśli istnieje, wznów lub uruchom ponownie tę pracę w dowolny sposób.

Powiązane problemy