При работе с AWS, чтобы иметь высокодоступную настройку, необходимо иметь экземпляры в более чем одной зоне доступности (AZ ≈ дата-центр). Если один AZ умирает (что может случиться), ваше приложение должно продолжать обслуживать запросы.
Просто настроить узлы вашего приложения в нескольких AZ (если они правильно написаны так, что они не сохраняют состояние), но сложнее для баз данных, очередей сообщений и всего, что имеет состояние. Итак, давайте посмотрим, как настроить RabbitMQ. Первые шаги относятся не только к RabbitMQ, но и к любому постоянному решению для данных.
Во-первых (независимо от того, используете ли вы CloudFormation или ручную настройку), вы должны:
- Есть VPC. Это может быть возможно без VPC, но я не могу этого гарантировать, особенно имена хостов DNS, как описано ниже
- Объявите частные подсети (для каждого AZ)
- Объявите группу автоматического масштабирования RabbitMQ (рекомендуется иметь одну) для охвата нескольких AZ, используя:
12345
"AvailabilityZones"
: {
"Fn::GetAZs"
: {
"Ref"
:
"AWS::Region"
}
}
- Объявите группу автоматического масштабирования RabbitMQ, чтобы охватить несколько подсетей, используя свойство
VPCZoneIdentifier
- Объявите LoadBalancer перед вашими узлами RabbitMQ (это самый простой способ обеспечить равномерное распределение нагрузки на кластер Rabbit), чтобы охватить все подсети.
- Объявить LoadBalancer как
"CrossZone": true
Затем идет конкретная конфигурация RabbitMQ. Как правило, у вас есть два варианта:
Кластеризация не рекомендуется в случае WAN, но соединение между зонами доступности можно рассматривать (возможно, немного оптимистично) как локальную сеть (в этом подробном посте предполагается иное, но этот поток намекает на то, что использование кластера с несколькими AZ хорошо).
С помощью федерации вы объявляете свои биржи для отправки всех сообщений, которые они получают, на биржу другого узла. Это очень полезно в глобальной сети, где отключение от сети является обычным делом, а скорость не так важна. Но это все еще может быть применимо в сценарии с несколькими AZ, поэтому стоит исследовать. Вот пример с точными командами для выполнения, как этого добиться, используя плагин объединения . Сложной частью федерации является автоматическое масштабирование — всякий раз, когда вам нужно добавить новый узел, вы должны изменить (некоторые из) конфигурацию существующих узлов, чтобы установить новый узел в качестве восходящего. Вам также может понадобиться разрешить другим компьютерам подключаться в качестве гостя к rabbitmq ( [{rabbit, [{loopback_users, []}]}]
в файле conf rabbitmq) или найти способ настроить пользовательскую пару имя пользователя / пароль для федерации работать.
С кластеризацией это немного по-другому, и на самом деле проще в настройке. Все, что вам нужно сделать, это написать скрипт для автоматического присоединения к кластеру при запуске. Это может быть сценарий оболочки или сценарий python, использующий AWS SDK. Основные шаги в таком сценарии (что, честно говоря, не так просто):
- Найдите все запущенные экземпляры в группе автоматического масштабирования RabbitMQ (используя параметры фильтрации AWS API)
- Если это первый узел (порядок случайный и не имеет значения), предположим, что это «начальный» узел для кластера, и все остальные узлы будут подключаться к нему
- Если это не первый узел, подключитесь к первому узлу (используя
rabbitmqctl join_cluster rabbit@{node}
), где {node} — это частное DNS-имя экземпляра (доступно через SDK) - Остановите RabbitMQ при выполнении всех настроек, запустите его после завершения
Во всех случаях (кластеризация или федерация) RabbitMQ использует доменные имена. Самый простой способ заставить его работать — включить DNS- "EnableDnsHostnames": true
хостов в вашем VPC: "EnableDnsHostnames": true
. Здесь есть небольшой взлом, когда речь идет о присоединении к кластеру — API AWS может вернуть полное доменное имя, которое включает в себя что-то вроде «.eu-west-1.compute.internal» в дополнение к ip-xxx-xxx -xxx-xxx часть. Поэтому, присоединяясь к кластеру RabbitMQ, вы должны удалить этот суффикс, иначе он не будет работать.
Конечные результаты должны учитывать кластер, где, если один узел умирает, а другой создается (группой автоматического масштабирования), кластер должен функционировать должным образом.
Сравнение двух подходов с PerfTest дает лучшую пропускную способность для опции кластеризации — с федерацией обрабатывалось примерно на 1/3 меньше сообщений, а также была немного большая задержка. Тесты должны выполняться от узла приложения к ELB RabbitMQ (в противном случае вы тестируете только один узел). Вы можете получить PerfTest и выполнить его примерно так (где адрес amqp — это DNS-имя балансировщика нагрузки RabbitMQ):
1
2
3
4
|
wget http: //www .rabbitmq.com /releases/rabbitmq-java-client/v3 .3.4 /rabbitmq-java-client-bin-3 .3.4. tar .gz tar -xvf rabbitmq-java-client-bin-3.3.4. tar .gz cd rabbitmq-java-client-bin-3.3.4 sudo sh runjava.sh com.rabbitmq.examples.PerfTest -x 10 -y 10 -z 10 -h amqp: //internal-foo-RabbitMQEl-1GM6IW33O-1097824 .eu-west-1.elb.amazonaws.com:5672 |
Какой из двух подходов вы выберете, зависит от вашего конкретного случая, но я бы обычно рекомендовал вариант кластеризации. Немного более производительно и немного проще в настройке и поддержке в облачной среде, где узлы часто появляются и умирают.
Ссылка: | RabbitMQ в нескольких зонах доступности AWS от нашего партнера JCG Божидара Божанова в техническом блоге Bozho. |