RabbitMQ graceful shutdown
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 statusNode: 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 ...
RuntimeOS 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.