RabbitMQ остановил приём сообщений: память на пороге
memory resource limit alarm set on node: RabbitMQ занял память до vm_memory_high_watermark и блокирует публикацию. Почему копится память и как это устроено в контейнере.
Что это значит
Брокер занял память до порога vm_memory_high_watermark (по умолчанию 40 % памяти, которую он видит). Как и при нехватке диска, RabbitMQ блокирует публикацию, пока память не освободится. Сервисы RX в это время не могут отправить ни одного сообщения.
Память растёт, когда сообщения копятся быстрее, чем их разбирают: обработчик остановлен, завис или не успевает. Вторая причина: тысячи очередей и соединений, каждое занимает память само по себе.
В контейнере есть особенность. По нашему замеру RabbitMQ 3.13 в Docker считал порог от памяти сервера, а не от лимита контейнера: 7 ГБ при лимите 400 МБ. В такой конфигурации контейнер убивают по памяти раньше, чем сработает тревога.
Как проверить
rabbitmq-diagnostics memory_breakdown
rabbitmqctl list_queues name messages consumers | sort -k2 -n | tail
rabbitmq-diagnostics status | grep -i -A2 "memory"
Первая команда покажет, на что ушла память. Вторая найдёт очереди, в которых копятся сообщения.
Что сделать
- Найти очередь с накоплением и поднять её обработчик. Память освободится по мере разбора.
- Для контейнера задать порог явно, числом:
vm_memory_high_watermark.absolute = 1GB, примерно 60 % от лимита контейнера. - Удалить очереди, у которых давно нет потребителя, и задать политику срока жизни для временных очередей.
- Следить за памятью брокера постоянно. Об этом пороге обычно вспоминают после первой остановки.