Контекст:
Мы используем HA-кластер RabbitMQ 2.8.4 для обмена сообщениями в центре обработки данных среднего размера (от сотен до тысяч серверов). Функции обмена сообщениями критически важны для нашего приложения.
Мы используем клиентский API C для операций AMQP / RabbitMQ и HTTP API для подключаемого модуля управления RabbitMQ для периодического мониторинга состояния очереди и отправки предупреждений в зависимости от размера / пропускной способности и т. Д.
Единственные порты / соединения, разрешенные от клиентов к серверам обмена сообщениями, - это порты AMQP и HTTP для API управления.
В ближайшем будущем руководство решило, что простои кластера обмена сообщениями (что приводит к простою некоторых запрашивающих частей приложения) недопустимы. Через несколько месяцев это станет возможным, но до тех пор озабоченность продажами не позволит нам обслуживать систему обмена сообщениями. Это отстой, но мы (специалисты по инфраструктуре / DevOps) не можем делать эти звонки.
Проблема:
Некоторое время мы были жертвами проблемы, обсуждаемой в этот ТАК вопрос. После шторма подключений или длительного периода, в течение которого новые клиенты очень часто подключаются и используют систему AMQP, API управления RabbitMQ показывает сотни тысяч подключений, которые он перечисляет как «запущенные», но больше не существует. netstat
, lsof
и другая диагностика доказывает, что сокеты, соответствующие этим соединениям, не открыты на клиентах; API управления по какой-то причине просто не может удалить записи. rabbitmqctl list_connections
иногда показывает, что некоторые из несуществующих соединений все еще открыты, но всегда показывает гораздо меньше, чем API управления, и его обнаружение «устаревания» кажется лучше, чем у API, и в конечном итоге он удаляет ложные соединения из своего списка.
Когда мы пытаемся удалить одно из этих «ложных» соединений через веб-интерфейс, страница не реагирует на наше нажатие «удалить», и соединение остается в списке. Когда мы пытаемся удалить его, отправив DELETE в JSON API, мы получаем ошибку сервера 500, указывающую на то, что соединение недействительно, поэтому его нельзя удалить (точно так, как описано в связанном вопросе SO выше).
После долгого накопления этих несуществующих объектов подключения происходят три неприятных события, не имеющих определенного порядка:
В случаях, когда эта проблема начинает нарушать работу нашего приложения, мы должны сделать одно из двух: * Перезапустить весь кластер обмена сообщениями, что плохо, потому что вызывает кратковременный простой, и плохо, потому что сообщения могут быть отброшены во время этого процесса. * Перезапустите и очистите базу данных API управления, что плохо, потому что мы не можем использовать API управления, и, что еще хуже, потому что он часто ломает API управления таким образом, что он не запускается должным образом, пока мы не перезапустим весь кластер, как в первая пуля.
Большинство людей, страдающих подобными проблемами, решают их путем обновления до RabbitMQ 3. *. У нас нет ни времени, ни разрешения, ни разрешения на простой для такого проекта. Даже в условиях периодических простоев на несколько минут при перезапуске кластера из-за этой проблемы у нас не было права на обновление. Это чисто политическое ограничение, но прискорбная реальность.
Вопрос:
Учитывая, что мы не можем обновить RabbitMQ в ближайшем будущем и что нам нужно продолжать использовать API управления, как мы можем решить проблему постоянных устаревших соединений, которые вызывают сбои кластера обмена сообщениями?
У нас есть возможность разрабатывать новый / другой клиентский код и выполнять задания на самих серверах обмена сообщениями, но у нас нет возможности использовать rabbitmqctl
локально или через ssh
на любой из клиентских машин.
Что мы пробовали:
tcp_keepalive
и exit_on_close
Настройки TCP на самих серверах RabbitMQ. Никакая комбинация этих значений не решает проблему.Вы продолжаете периодически все перезагружать.
Другой вариант - выполнить резервное копирование исправления из 3.x в текущую версию, но если вам не разрешено обновление, вам, вероятно, также не разрешат это сделать. И это почти наверняка будет намного сложнее, чем обновление, особенно если код RabbitMQ был значительно переработан.
Пока вы не сможете изменить политика ситуации, это ваши варианты.