Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Apps

Управление вашим кластером RabbitMQ

by
Difficulty:AdvancedLength:MediumLanguages:

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

RabbitMQ - отличный брокер распределенных сообщений, но его не так просто администрировать программно. В этом уроке я покажу вам, как создать кластер, добавить узлы, удалить узлы, запускать их и останавливать. В качестве бонуса я поделюсь файлом Fabric, который позволит вам получить полный контроль. Код доступен на GitHub.

Краткое введение в RabbitMQ

RabbitMQ - очень популярная очередь сообщений. У вас может быть несколько производителей, отправляющих сообщения, и потребители могут использовать эти сообщения полностью отделенным образом. RabbitMQ очень популярен по нескольким причинам:

  1. Это быстро и надежно.
  2. Это открытый исходный код, но есть коммерческая поддержка, если вы этого хотите.
  3. Он работает в вашей операционной системе.
  4. Он активно развивается.
  5. Он проверен в бою.

RabbitMQ реализован на Erlang, что немного необычно, но одна из причин, по которой он так надежен.

Предпосылки

В этом руководстве я буду использовать локальный кластер Vagrant из трех узлов. Если у вас уже есть три доступные машины (виртуальные или нет), вы можете использовать их вместо этого. Обратите внимание на порты и сети.

Установите VirtualBox

Следуйте инструкциям по установке VirtualBox.

Установить Vagrant

Следуйте инструкциям по установке Vagrant

Создать кластер RabbitMQ

Вот Vagrantfile, который создаст локальный трехузловой кластер на вашем компьютере. ОС Ubuntu 14.04 (Trusty).

ruby # -*- mode: ruby -*- # vi: set ft=ruby : hosts = { "rabbit-1" => "192.168.77.10", "rabbit-2" => "192.168.77.11", "rabbit-3" => "192.168.77.12" } Vagrant.configure("2") do |config| config.vm.box = "trusty64" hosts.each_with_index do |(name, ip), i| rmq_port = 5672 + i admin_port = 15672 + i config.vm.define name do |machine| machine.vm.network :private_network, ip: ip config.vm.hostname = "rabbit-%d" % [i + 1] config.vm.network :forwarded_port, guest: 5672, guest_ip: ip, host: rmq_port config.vm.network :forwarded_port, guest: 15672, guest_ip: ip, host: admin_port machine.vm.provider "virtualbox" do |v| v.name = name end end end end

Чтобы создать пустой кластер, введите: vagrant up.

Настройка SSH

Чтобы упростить ssh для узлов кластера, введите: vagrant ssh-config >> ~ / .ssh / config.

Если вы наберете: cat ~ / .ssh / config, вы должны увидеть записи для rabbit-1, rabbit-2 и rabbit-3.

Теперь вы можете использовать ssh на каждой виртуальной машине по имени: ssh rabbit-1.

Убедитесь, что узлы достижимы по имени

Самый простой способ - отредактировать файл /etc/hosts. Например, для rabbit-1 добавьте адреса rabbit-2 и rabbit-3.

plain 192.168.77.11 rabbit-2 192.168.77.12 rabbit-3

Повторите процесс для всех узлов.

Установка RabbitMQ

Я буду использовать apt-get здесь для операционных систем Debian/Ubuntu. Если ваш кластер работает в другой ОС, следуйте инструкциям на странице установки RabbitMQ.

Обратите внимание, что иногда довольно устаревшая версия RabbitMQ доступна по умолчанию. Если вы хотите установить самую последнюю и лучшую версию, вы можете загрузить пакет .deb напрямую или добавить apt-репозиторий RabbitMQ, используя эти инструкции.

Текущая версия RabbitMQ на Ubuntu 14.04 - 3.2, что достаточно для наших целей. Убедитесь сами, набрав: apt-cache show rabbitmq-server.

Давайте продолжим и установим его на каждую машину:

plain sudo apt-get update sudo apt-get install rabbitmq-server -y

Не стесняйтесь использовать ваши любимые инструменты управления конфигурацией, такие как Chef или Ansible, если вы предпочитаете.

Обратите внимание, что Erlang будет установлен первым в качестве предварительного условия.

Включваем плагин Management RabbitMQ

Плагин управления действительно классный. Он предоставляет вам API на основе HTTP, а также веб-интерфейс и инструмент командной строки для управления кластером. Вот как это сделать:

plain sudo rabbitmq-plugins enable rabbitmq_management

Получаем инструмент командной строки управления

Загрузите его с http://192.168.77.10:15672/cli/rabbitmqadmin. Обратите внимание, что документация RabbitMQ неверна и требует загрузки с http://:15672/cli/.

Это HTTP-клиент на основе Python для API-интерфейса управления RabbitMQ. Это очень удобно для сценариев кластеров RabbitMQ.

Основные понятия RabbitMQ

RabbitMQ реализует стандарт AMQP 0.9.1 (расширенный протокол очереди сообщений). Обратите внимание, что уже существует стандарт AMQP 1.0, и RabbitMQ имеет плагин для его поддержки, но он считается прототипом из-за недостаточного использования в реальных условиях.

В модели AMQP издатели отправляют сообщения посреднику сообщений (в данном случае RabbitMQ - посредник сообщений) через обменник. Посредник сообщений распределяет сообщения в очереди на основе метаданных, связанных с сообщением. Потребители потребляют сообщения из очередей. Сообщения могут быть или не быть подтверждены. RabbitMQ поддерживает множество моделей программирования на основе этих концепций, таких как рабочие очереди, публикация-подписка и RPC.

Управление вашим кластером

Для управления кластером используются три сценария. Скрипт rabbitmq-server запускает сервер RabbitMQ (запускает его). Rabbitmqctl используется для управления кластером (остановка, сброс, объединение узлов кластера и получение статуса). Rabbitmqadmin, который вы скачали ранее, используется для настройки и администрирования кластера (объявление vhosts, пользователей, обменов и очередей). Создание кластера включает в себя только rabbitmq-server и rabbitmqctl.

Во-первых, давайте запустим rabbitmq-сервер как сервис (демон) на каждом из наших хостов rabbit-1, rabbit-2 и rabbit-3.

plain sudo service rabbitmq-server start

Это запустит виртуальную машину Erlang и приложение RabbitMQ, если узел не работает. Чтобы убедиться, что он работает правильно, введите:

plain sudo rabbitmqctl cluster_status

Вывод должен быть таким (для rabbit-1):

plain Cluster status of node 'rabbit@rabbit-1' ... [{nodes,[{disc,['rabbit@rabbit-1']}]}, {running_nodes,['rabbit@rabbit-1']}, {partitions,[]}] ...done.

Это означает, что узел еще не кластеризован ни с какими другими узлами и является дисковым узлом. Он также работает, как вы можете видеть, что он появляется в списке running_nodes.

Чтобы остановить сервер, введите следующую команду:

plain sudo rabbitmqctl stop_app

Затем, если вы проверите состояние кластера:

plain sudo rabbitmqctl cluster_status

Вывод должен быть таким:

plain Cluster status of node 'rabbit@rabbit-1' ... [{nodes,[{disc,['rabbit@rabbit-1']}]}] ...done.

Нет больше работающих узлов.

Вы можете повторить процесс для других узлов (rabbit-2 и rabbit-3) и увидеть, что они знают только себя.

Эрланг Cookie

Прежде чем вы сможете создать кластер, все узлы в кластере должны иметь один и тот же файл cookie. Файл cookie - это файл, который среда исполнения Erlang использует для идентификации узлов. Он находится в /var/lib/rabbitmq/.erlang.cookie. Просто скопируйте содержимое с rabbit-1 на rabbit-2 и rabbit-3.

Узлы кластеризации вместе

Чтобы сгруппировать эти отдельные узлы в единый кластер, требуется определенная работа. Вот процедура:

  • Работает один узел (например, rabbit-1).
  • Остановите другой узел (например, rabbit-2).
  • Сброс остановленного узла (rabbit-2).
  • Кластеризация другого узла в корневой узел.
  • Запустите остановленный узел.

Давай сделаем это. ssh в rabbit-2 и выполните следующие команды:

plain sudo rabbitmqctl stop_app sudo rabbitmqctl reset sudo rabbitmqctl join_cluster rabbit@rabbit-1

Теперь наберите: sudo rabbitmqctl cluster_status.

Вывод должен быть следующим:

```plain Cluster status of node ‘rabbit@rabbit-2’ … [{nodes,[{disc,[‘rabbit@rabbit-1’,’rabbit@rabbit-2’]}]}] …Done. As you can see both nodes are now clustered. If you repeat this on rabbit-1 you’ll get following output:

Теперь вы можете начать rabbit-2.

plain sudo rabbitmqctl start_app

Если вы проверите статус снова, оба узла будут работать:

plain Cluster status of node 'rabbit@rabbit-2' ... [{nodes,[{disc,['rabbit@rabbit-1','rabbit@rabbit-2']}]}, {running_nodes,['rabbit@rabbit-1','rabbit@rabbit-2']}, {partitions,[]}] ...done.

Обратите внимание, что оба узла являются узлами диска, что означает, что они хранят свои метаданные на диске. Давайте добавим rabbit-3 в качестве узла RAM. ssh to rabbit-3 и выполните следующие команды:

plain sudo rabbitmqctl stop_app sudo rabbitmqctl reset sudo rabbitmqctl join_cluster --ram rabbit@rabbit-2 sudo rabbitmqctl start_app

Проверка состояния показывает:

plain Cluster status of node 'rabbit@rabbit-3' ... [{nodes,[{disc,['rabbit@rabbit-2','rabbit@rabbit-1']}, {ram,['rabbit@rabbit-3']}]}, {running_nodes,['rabbit@rabbit-1','rabbit@rabbit-2','rabbit@rabbit-3']}, {partitions,[]}] ...done.

Все узлы кластера работают. Узлы диска - это rabbit-1 и rabbit-2, а узел ОЗУ - rabbit-3.

Поздравляем! У вас есть работающий кластер RabbitMQ.

Реальные осложнения

Что произойдет, если вы захотите изменить конфигурацию своего кластера? Вам придется использовать хирургическую точность при добавлении и удалении узлов из кластера.

Что произойдет, если узел еще не перезапущен, но вы пытаетесь продолжить с помощью stop_app, reset и start_app? Что ж, команда stop_app якобы будет успешной и вернет «готово», даже если целевой узел не работает. Однако последующая команда сброса завершится неудачно с неприятным сообщением. Я потратил много времени ломая голову, пытаясь понять это, поскольку предполагал, что проблема заключается в некотором параметре конфигурации, который влияет только на сброс.

Другой недостаток заключается в том, что если вы хотите сбросить последний узел диска, вы должны использовать force_reset. Попытка выяснить в общем случае, какой узел был последним узлом диска, не тривиальна.

RabbitMQ также поддерживает кластеризацию через файлы конфигурации. Это замечательно, когда ваши дисковые узлы работают, потому что перезапущенные узлы ОЗУ будут просто кластеризоваться на основе файла конфигурации без необходимости их явной кластеризации. Опять же, это не взлетит, когда вы пытаетесь восстановить сломанный кластер.

Надежная кластеризация RabbitMQ

Это сводится к следующему: вы не знаете, какой последний дисковый узел вышел из строя. Вы не знаете метаданные кластеризации каждого узла (возможно, они были сброшены во время сброса). Чтобы запустить все узлы, я использую следующий алгоритм:

  • Запустите все узлы (по крайней мере, последний дисковый узел должен быть в состоянии начать).
  • Если даже ни один узел не может запуститься, вы попали в точку. Просто выручите.
  • Отслеживайте все узлы, которые не удалось запустить.
  • Попробуйте запустить все неисправные узлы.
  • Если некоторые узлы не удалось запустить во второй раз, вы попали в шланг. Просто выручите.

Этот алгоритм будет работать до тех пор, пока ваш последний узел диска физически исправен.

После того, как все узлы кластера подключены, вы можете переконфигурировать их (помните, что вы не уверены, на каком узле какие метаданные). Ключ заключается в принудительном сбросе каждого узла. Это гарантирует, что любой след предыдущей конфигурации кластера будет удален со всех узлов. Сначала сделайте это для одного дискового узла:

plain stop_app force_reset start_app

Затем для каждого другого узла (диска или ОЗУ):

plain stop_app force_reset join_cluster [list of disc nodes] start_app

Удаленное управление кластером

Вы можете ввести SSH в каждый блок и выполнить вышеупомянутые шаги для каждого блока вручную. Это работает, но очень быстро устаревает. Кроме того, это нецелесообразно, если вы хотите построить и разрушить кластер как часть автоматизированного теста.

Одним из решений является использование Fabric. Одна серьезная ошибка, с которой я столкнулся, заключается в том, что когда я выполнял алгоритм кластера сборки вручную, он работал отлично, но когда я использовал Fabric, он таинственным образом не работал. После некоторой отладки я заметил, что узлы запустились успешно, но к тому времени, когда я попытался stop_app, узлы были недоступны. Это оказалось ошибкой новичка Fabric с моей стороны. Когда вы запускаете удаленную команду с помощью Fabric, она запускает новую оболочку на удаленном компьютере. Когда команда завершена, оболочка закрывается, отправляя сигнал SIGHUP (сигнал зависания) всем его подпроцессам, включая узел Erlang. Использование nohup позаботится об этом. Другой более надежный вариант - запуск RabbitMQ в качестве службы (демона).

Программное администрирование кластера

Администрирование означает создание виртуальных хостов, пользователей, бирж и очередей, настройку разрешений и привязку очередей к биржам. Первое, что вы должны сделать, если вы еще этого не сделали, это установить плагины управления. Я не уверен, почему вы должны включить его самостоятельно. Это должно быть включено по умолчанию.

Веб-интерфейс фантастический, и вы должны обязательно ознакомиться с ним. Однако для удаленного администрирования кластера можно использовать API-интерфейс управления RESTful. Существует также инструмент командной строки Python с именем rabbitmqadmin, для которого требуется Python 2.6+. Использовать rabbitmqadmin довольно просто. Единственная проблема, которую я обнаружил, это то, что я мог использовать только гостевую учетную запись по умолчанию для администрирования кластера. Я создал другого пользователя-администратора с именем «admin», установил его разрешения для всех (настройка/чтение/запись) и присвоил ему тег «администратор» (дополнительное требование API управления), но я продолжал получать ошибки разрешения.

Проект Elmer позволяет вам указать конфигурацию кластера как структуру данных Python (см. sample_config.py) и настроит все для вас.

Выводы

  1. RabbitMQ это круто.
  2. История администратора кластера не герметична.
  3. Программное администрирование является ключевым.
  4. Fabric - отличный инструмент для удаленного управления несколькими Unix-системами.
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.