RabbitMQ graceful shutdown

Tomasz Gintowt
3 min readJul 22, 2021

TL;DR W tym tekście znajdziesz informację, jak można wykonać “graceful shutdown” noda RabbitMQ.

Jeśli wystarczy Ci wpisanie “systemctl stop rabbitmq” to możesz przerwać czytanie w tym miejscu, zaoszczędzić trochę czasu i wzrok. Jest duże prawdopodobieństwo, że uda Ci się zrobić coś pożytecznego. Możesz iść na kawę lub z kimś porozmawiać.

Jeśli, jednak systemctl stop to za mało dla Ciebie, zapraszam do dalszego czytania.

Czemu “systemctl stop rabbitmq” to za mało ? Takie wyłączenie, może spowodować przeciążenie mnesia, wewnętrznej bazy, w której RabbitMQ przechowuje informacje. W najgorszym wypadku będziemy mieli niedostępny klaster do czasu, aż wszystkie kolejki zostaną przypisane do pozostałych instancji w klastrze.

Możemy przełączyć node w “maintenance_mode”. Kiedy node jest stanie maintenance jest niedostępny dla klientów, a już istniejące połączenia/kolejki i wiadomości zostaną przeniesione na pozostaje instancje. Co dokładnie się dzieje:

node nie akceptuje nowych połączeń

wszystkie istniejące połączenia zostaną zamknięte

primary replicas zostaną przeniesione na pozostałe instancje

node zostanie oznaczony jako niedostępny

Jak to zrobić ?

Załóżmy, że mamy dwu lub trzy nodowy klaster RabbitMQ. Chcemy z gracją i wdziękiem wyłączyć jeden node i nie zrobić przy tym dużo zamieszania.

W RabbitMQ od wersji 3.8.8 jest dostępna opcja “maintenance_mode_status”.

rabbitmqctl enable_feature_flag maintenance_mode_status

To czy node znajduje się w stanie maintenance, możemy sprawdzić na dwa sposoby:

rabbitmq-diagnostics cluster_status...
Maintenance status
Node: rabbit@rabbit001node, status: not under maintenance
Node: rabbit@rabbit002node, status: not under maintenance
Node: rabbit@rabbit003node, status: not under maintenance
...

lub

rabbitmq-diagnostics status
Status of node rabbit@rabbit001node ...
Runtime
OS PID: 1346
OS: Linux
Uptime (seconds): 13491
Is under maintenance?: false

Przełączanie node w maintenance mode

Posłużymy się komendą rabbitmq-upgrade

rabbitmq-upgrade drainlub

rabbitmq-upgrade drain -n rabbit@rabbit001node

Tutaj mała uwaga, polecenie nie zwraca błędu, nawet jeśli “maintenance_mode_status” nie jest włączony. Taka informacje jest logach.

[warning] <0.4052.538> Feature flag `maintenance_mode_status` is not enabled, draining is a no-op

Postęp prac, możemy obserwować w logach. Możemy też sprawdzić połączenia, niestety polecenia

rabbitmq-diagnostics list_connections
rabbitmqctl list_connections

pokazują, połączenia dla całego klastra, a nie pojedynczego node.Tutaj pomoże nam stare, sprawdzone polecenie

neststat -tunap|grep 5672

Teraz, możemy wyłączyć node przy pomocy systemctl.

UWAGA! Maintenance mode działa tylko do pierwszego restartu. Po restarcie node automatycznie dołącza do klastra.

Co zrobić, gdy się rozmyśliliśmy i nie wykonaliśmy restartu ? Można wyłączyć maintenance_mode poleceniem:

rabbitmq-upgrade revivelubrabbitmq-upgrade revive -n rabbit@rabbit001node

Udanego Rabbitowania!

Tomasz Gintowt jest Architektem/DevOps/DBA/Trenerem, głównie skupiony na dostarczaniu rozwiązań składowania i przetwarzania danych. Nie są mu obce wszelkiej maści bazy danych, systemy real-time data i streamingu. Obecnie pracuje z Apache Kafka, RabbitMQ, Elastic Stack i PostgreSQL. Organizator spotkań DataOps Poland. Prywatnie fan ciasta marchewkowego.

https://www.linkedin.com/in/tomasz-gintowt/

https://www.meetup.com/dataops-poland/

--

--

Tomasz Gintowt

Architect, DevOps, SysOps, and DBA. Currently, I’m an IT Systems Engineer working with Apache Kafka, RabbitMQ, PostgreSQL, Elastic Stack in Real-Time Data Team.