Введение в кластер
1.1 Архитектура кластера
Когда способность одного сервера RabbitMQ обрабатывать сообщения становится узким местом, его можно расширить с помощью кластера RabbitMQ для достижения цели повышения пропускной способности. Кластер RabbitMQ представляет собой логическую группу из одного или нескольких узлов, каждый узел в кластере является одноранговым, и каждый узел совместно использует всех пользователей, виртуальные хосты, очереди, обмены, привязки, параметры времени выполнения и другие состояния распределений и т. д. Кластерная архитектура RabbitMQ с высокой доступностью и балансировкой нагрузки должна выглядеть примерно так, как показано на следующей схеме:
Здесь объясните приведенную выше архитектуру кластера:
Во-первых, базовый кластер RabbitMQ не отличается высокой доступностью, несмотря на общую очередь кластера, но по умолчанию сообщение будет маршрутизироваться в соответствии с условием узла в очереди и не будет синхронизироваться с той же очередью на других узлах. . Предполагая, что сообщение направляется в очередь my-queue node1, node1, но внезапно выходит из строя, сообщение будет потеряно, чтобы решить эту проблему, вам нужно открыть зеркало очереди, зеркально отразить друг друга в очереди кластера, сообщение в это время он будет скопирован во все очереди в том же пакете в зеркале.
Во-вторых, в самом кластере RabbitMQ не предусмотрена функция балансировки нагрузки, то есть для трехузлового кластера нагрузка на каждую ноду может быть разной, для решения этой проблемы можно использовать аппаратную балансировку нагрузки или программную нагрузку балансировка. , здесь мы решили использовать HAProxy для балансировки нагрузки, конечно, также можно использовать другое промежуточное ПО для балансировки нагрузки, такое как LVS. HAProxy поддерживает балансировку нагрузки как на уровне 4, так и на уровне 7 и основан на модели, управляемой событиями, с одним процессом, поэтому он может поддерживать очень большое количество правильно оформленных соединений.
Затем предположим, что мы используем только один HAProxy, тогда у него очевидная проблема с единой точкой отказа, поэтому необходимы по крайней мере два HAProxy и требуется автоматическое переключение между двумя HAProxy.Обычным решением является KeepAlived. KeepAlived использует VRRP (протокол резервирования виртуального маршрутизатора, протокол резервирования виртуального маршрутизатора) для решения проблемы единой точки отказа.Обычно он состоит из набора из двух узлов, одного резервного и двух узлов.В то же время только главный узел будет предоставлять внешние услуги и в то же время предоставлять виртуальный IP-адрес (виртуальный адрес интернет-протокола, называемый VIP). Если основной узел выходит из строя, резервный узел автоматически принимает на себя роль виртуального IP-адреса и становится новым основным узлом до тех пор, пока исходный основной узел не будет восстановлен.
Наконец, любой клиент, который хочет подключиться к кластеру RabbitMQ, должен подключиться только к виртуальному IP-адресу, независимо от архитектуры кластера.Вот пример:
ConnectionFactory factory = new ConnectionFactory();
// 假设虚拟ip为 192.168.0.200
factory.setHost("192.168.0.200");
1.2 Ситуация с развертыванием
Приступим к сборке. Здесь для демонстрации я использую три хоста. Имена хостов - hadoop001, 002 и 003, а назначение их функций следующее:
- Hadoop001 сервер: развертывание RabbitMQ + HAProxy + KeepAlived;
- сервер hadoop002: развертывание RabbitMQ + HAProxy + KeepAlived;
- сервер hadoop003: развернуть RabbitMQ
Я установил RabbitMQ более чем на трех хостах, о шагах установки RabbitMQ можно узнать здесь:Создание автономной среды RabbitMQ
2. Создание кластера RabbitMQ
Во-первых, создайте кластер RabbitMQ.Конкретные шаги заключаются в следующем:
2.1 Копировать файлы cookie
будет иметь oop001 на.erlang.cookie
Файлы копируются на два других хоста. Файл cookie эквивалентен токену ключа.Узлы RabbitMQ в кластере должны обмениваться токенами ключа для получения взаимной аутентификации.Поэтому все узлы в одном кластере должны иметь один и тот же токен ключа, иначе система появится при построении процесс Ошибка аутентификации.
Когда начинается служба RabbitMQ, VM Erlang VM автоматически создаст файл cookie. Путь хранения по умолчанию/var/lib/rabbitmq/.erlang.cookie
или$HOME/.erlang.cookie
, файл является скрытым и должен использоватьсяls -al
команда для просмотра. Здесь я использую учетную запись root, каталог $HOME — это каталог /root, а соответствующая команда копирования выглядит следующим образом:
scp /root/.erlang.cookie root@hadoop002:/root/
scp /root/.erlang.cookie root@hadoop003:/root/
Поскольку вы можете работать с разными учетными записями на трех хостах, чтобы впоследствии избежать проблемы с недостаточными разрешениями, рекомендуется изменить исходное разрешение 400 файла cookie на 777, и команда выглядит следующим образом:
chmod 777 /root/.erlang.cookie
Примечание. Содержимое файла cookie представляет собой строку случайных строк, которую можно просмотреть с помощью команды cat.
2.2 Запуск службы
Выполните следующие команды на всех трех хостах, чтобы запустить службу RabbitMQ:
rabbitmq-server start -detached
Здесь заранее: эта команда одновременно инициирует виртуальные машины Erlang и службы приложений RabbitMQ. Заднийrabbitmqctl start_app
Запустит только службу приложений RabbitMQ,rabbitmqctl stop_app
Будет остановлена только служба RabbitMQ.
2.3 Строительство кластера
Чтобы построить кластер RabbitMQ, вам нужно выбрать любой из узлов в качестве эталона и постепенно добавлять другие узлы. Здесь мы используем Hadoop001 в качестве базового узла и добавляем в кластер Hadoop002 и Hadoop003. Выполните следующие команды на hadoop002 и hadoop003:
# 1.停止服务
rabbitmqctl stop_app
# 2.重置状态
rabbitmqctl reset
# 3.节点加入
rabbitmqctl join_cluster --ram rabbit@hadoop001
# 4.启动服务
rabbitmqctl start_app
join_cluster
команда имеет необязательный параметр--ram
Этот параметр указывает, что вновь добавленный узел является узлом памяти, по умолчанию это узел диска. Если это узел памяти, все очереди, коммутаторы, отношения привязки, пользователи, права доступа и метаданные VHOST будут храниться в памяти, а если это дисковый узел, хранить их на диске. Узлы памяти могут иметь более высокую производительность, но вся информация о конфигурации будет потеряна после перезагрузки, поэтому для RabBitmq требуется как минимум один дисковый узел в кластере, а другие узлы могут быть узлом памяти. Когда узел памяти покидает кластер, он может уведомить об изменении по крайней мере один дисковый узел, затем при перезапуске он подключается к дисковому узлу для получения метаданных. Если для RPC не используется Rabbitmq, для этого требуется сверхнизкая задержка, в большинстве случаев производительности Rabbitmq достаточно, и можно использовать дисковый узел по умолчанию. Вот, чтобы продемонстрировать, Hadoop002 я настроен на узлы памяти.
Кроме того, если узел присоединяется как дисковый узел, вам необходимо использоватьreset
Команда для сброса перед присоединением к существующему кластеру, сброс узла удалит все исторические ресурсы и данные, существующие на этом узле. Его можно пропустить при объединении в виде узлов памятиreset
Этот шаг, потому что данные в памяти сами по себе не являются постоянными.
2.4 Просмотр состояния кластера
1. Вид командной строки
После выполнения вышеуказанных команд на hadoop002 и 003 кластер был успешно построен и может использоваться на любом узле в это время.rabbitmqctl cluster_status
Команда для просмотра состояния кластера, вывод выглядит следующим образом:
[root@hadoop001 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@hadoop001 ...
[{nodes,[{disc,[rabbit@hadoop001,rabbit@hadoop003]},{ram,[rabbit@hadoop002]}]},
{running_nodes,[rabbit@hadoop003,rabbit@hadoop002,rabbit@hadoop001]},
{cluster_name,<<"rabbit@hadoop001">>},
{partitions,[]},
{alarms,[{rabbit@hadoop003,[]},{rabbit@hadoop002,[]},{rabbit@hadoop001,[]}]}]
Вы можете видеть, что информация обо всех узлах отображается под узлами.Узлы на hadoop001 и hadoop003 имеют дисковый тип, то есть дисковые узлы, а узлы на hadoop002 — оперативные, то есть узлы памяти. На данный момент кластер успешно построен. Имя_кластера по умолчанию — rabbit@hadoop001. Если вы хотите изменить его, вы можете использовать следующую команду:
rabbitmqctl set_cluster_name my_rabbitmq_cluster
2. Вид пользовательского интерфейса
Помимо использования командной строки, вы также можете использовать интерфейс пользовательского интерфейса, чтобы открыть любой узел для просмотра, как показано ниже:
2.5 Настройка зеркальной очереди
1. Откройте очередь зеркал
Здесь мы включаем настройку зеркалирования для всех очередей, синтаксис следующий:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
2. Основной коэффициент
Выше мы указали значение ha-mode как all, что означает, что сообщение будет синхронизировано в одну и ту же очередь на всех узлах. Причина, по которой мы настроили это здесь, заключается в том, что у нас всего три узла, поэтому накладные расходы на производительность операции репликации относительно невелики. Если в вашем кластере много узлов, то затраты производительности на репликацию относительно велики, и вам необходимо выбрать соответствующий коэффициент репликации. Обычно можно следовать принципу перезаписи, то есть для кластера с n узлами необходимо синхронизировать только n/2+1 узлов. В это время вам нужно изменить политику зеркалирования на точно и указать коэффициент репликации ha-params.Пример команды выглядит следующим образом:
rabbitmqctl set_policy ha-two "^" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
Кроме того, RabbitMQ также поддерживает использование регулярных выражений для фильтрации очередей, которые необходимо отразить, например:
rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}'
В настоящее время зеркалироваться будут только очереди, начинающиеся с ha. Дополнительные инструкции по настройке зеркальной очереди вы можете найти в официальной документации:Highly Available (Mirrored) Queues
3. Проверьте состояние зеркала
После завершения настройки вы можете просмотреть состояние зеркального отображения любой очереди через интерфейс веб-интерфейса следующим образом:
2.6 Узел в автономном режиме
Описанный выше процесс построения кластера — это процесс расширения сервиса.Если вы хотите уменьшить сервис, то есть хотите удалить узел из кластера, есть два варианта:
Первый: можно использовать первымrabbitmqctl stop
Остановите службу на этом узле и запустите ее на любом другом узле.forget_cluster_node
Заказ. Вот пример удаления службы на hadoop003.В это время вы можете выполнить следующую команду на hadoop001 или 002:
rabbitmqctl forget_cluster_node rabbit@hadoop003
Второй способ: использовать первыйrabbitmqctl stop
Остановите службу на этом узле, а затем выполнитеrabbitmqctl reset
Это очищает все исторические данные на узле и активно информирует другие узлы в кластере о том, что он собирается покинуть кластер.
2.7 Выключение и перезапуск кластера
Прямой команды на выключение всего кластера нет, его нужно выключать по одному. Однако необходимо следить за тем, чтобы при перезапуске узел, который был выключен последним, запускался первым. Если первый запускаемый узел не является последним остановленным узлом, то узел будет ожидать запуска последнего остановленного узла.По умолчанию выполняется 10 попыток подключения, а период ожидания составляет 30 секунд. Если он по-прежнему не ждет, узел не запускается.
Одна из проблем заключается в том, что в кластере из трех узлов порядок завершения работы следующий: узел 1, узел 2 и узел 3. Если узел 1 не может быть временно восстановлен из-за сбоя, узел 2 и узел 3 не могут быть запущены в это время. Чтобы решить эту проблему, вы можете сначала удалить узел node1, команда выглядит следующим образом:
rabbitmqctl forget_cluster_node rabbit@node1 -offline
необходимо добавить-offline
параметр, который позволяет узлу отбрасывать другие узлы без запуска самого себя.
3. Создание среды HAProxy
3.1 Скачать
Официальный адрес загрузки HAProxy:www.haproxy.org/#down, если этот сайт недоступен, вы также можете получить к нему доступ издвуспальная кровать Fedora project.org/repo/parker company/also…скачать на . Здесь я скачал версию 2.x и разархивировал ее после скачивания:
tar -zxvf haproxy-2.0.3.tar.gz
3.2 Компиляция
Войдите в разархивированный корневой каталог и выполните следующую команду компиляции:
make TARGET=linux-glibc PREFIX=/usr/app/haproxy-2.0.3
make install PREFIX=/usr/app/haproxy-2.0.3
3.3 Настройка переменных среды
Настройте переменные среды:
vim /etc/profile
export HAPROXY_HOME=/usr/app/haproxy-2.0.3
export PATH=$PATH:$HAPROXY_HOME/sbin
Сделайте так, чтобы настроенные переменные среды вступили в силу немедленно:
source /etc/profile
3.4 Конфигурация балансировки нагрузки
Новый файл конфигурацииhaproxy.cfg
, вот мое новое местоположение: /etc/haproxy/haproxy.cfg, содержимое файла следующее:
# 全局配置
global
# 日志输出配置、所有日志都记录在本机,通过 local0 进行输出
log 127.0.0.1 local0 info
# 最大连接数
maxconn 4096
# 改变当前的工作目录
chroot /usr/app/haproxy-2.0.3
# 以指定的 UID 运行 haproxy 进程
uid 99
# 以指定的 GID 运行 haproxy 进程
gid 99
# 以守护进行的方式运行
daemon
# 当前进程的 pid 文件存放位置
pidfile /usr/app/haproxy-2.0.3/haproxy.pid
# 默认配置
defaults
# 应用全局的日志配置
log global
# 使用4层代理模式,7层代理模式则为"http"
mode tcp
# 日志类别
option tcplog
# 不记录健康检查的日志信息
option dontlognull
# 3次失败则认为服务不可用
retries 3
# 每个进程可用的最大连接数
maxconn 2000
# 连接超时
timeout connect 5s
# 客户端超时
timeout client 120s
# 服务端超时
timeout server 120s
# 绑定配置
listen rabbitmq_cluster
bind :5671
# 配置TCP模式
mode tcp
# 采用加权轮询的机制进行负载均衡
balance roundrobin
# RabbitMQ 集群节点配置
server node1 hadoop001:5672 check inter 5000 rise 2 fall 3 weight 1
server node2 hadoop002:5672 check inter 5000 rise 2 fall 3 weight 1
server node3 hadoop003:5672 check inter 5000 rise 2 fall 3 weight 1
# 配置监控页面
listen monitor
bind :8100
mode http
option httplog
stats enable
stats uri /stats
stats refresh 5s
Основная конфигурация балансировки нагрузки находится вlisten rabbitmq_cluster
Далее здесь указывается метод балансировки нагрузки как взвешенный циклический перебор и определяется механизм проверки работоспособности:
server node1 hadoop001:5672 check inter 5000 rise 2 fall 3 weight 1
Приведенная выше конфигурация означает, что узел node1 с адресом hadoop001:5672 будет выполнять проверку работоспособности каждые 5 секунд.Если результаты двух последовательных проверок в норме, узел считается доступным, и запрос клиента может быть опрошен. к узлу в это время. Если результат 3-х последовательных проверок не является нормальным, узел считается недоступным. weight используется для указания веса узла в процессе опроса.
3.5 Запустите службу
Вышеупомянутые этапы построения точно такие же для hadoop001 и hadoop002.После завершения построения используйте следующую команду для запуска службы:
haproxy -f /etc/haproxy/haproxy.cfg
После запуска вы можете просмотреть его на странице мониторинга, порт является набором 8100, а полный адрес:http://hadoop001:8100/stats, ситуация со страницей следующая:
Все узлы зеленые, что означает, что узел исправен. На данный момент это доказывает, что HAProxy был успешно собран и кластер RabbitMQ отслеживался.
4. Создание среды KeepAlived
Затем вы можете собрать Keepalived, чтобы решить проблему отказоустойчивости HAProxy. Здесь я установил KeepAlived на hadoop001 и hadoop002.Этапы сборки на двух хостах абсолютно одинаковы, но некоторые конфигурации немного отличаются, а именно:
4.1 Скачать
Скачиваем нужную версию прямо с официального Keepalived, здесь я скачал версию 2.x. Распаковать после скачивания:
wget https://www.keepalived.org/software/keepalived-2.0.18.tar.gz
tar -zxvf keepalived-2.0.18.tar.gz
4.2 Компиляция
Скомпилируйте после установки соответствующих зависимостей:
# 安装依赖
yum -y install libnl libnl-devel
# 编译安装
./configure --prefix=/usr/app/keepalived-2.0.18
make && make install
4.3 Конфигурация среды
Поскольку он устанавливается не yum, а сжатым пакетом, в настоящее время требуется настройка среды следующим образом:
Keepalived по умолчанию/etc/keepalived/keepalived.conf
Путь считывает файл конфигурации, поэтому вам нужно скопировать установленный файл конфигурации по этому пути:
mkdir /etc/keepalived
cp /usr/app/keepalived-2.0.18/etc/keepalived/keepalived.conf /etc/keepalived/
Скопируйте все скрипты Keepalived в каталог /etc/init.d/:
# 编译目录中的脚本
cp /usr/software/keepalived-2.0.18/keepalived/etc/init.d/keepalived /etc/init.d/
# 安装目录中的脚本
cp /usr/app/keepalived-2.0.18/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/app/keepalived-2.0.18/sbin/keepalived /usr/sbin/
Настройте загрузку на автоматический запуск:
chmod +x /etc/init.d/keepalived
chkconfig --add keepalived
systemctl enable keepalived.service
4.4 Настройка проверки HAProxy
Здесь сначала измените файл конфигурации keepalived.conf на hadoop001.Полное содержание выглядит следующим образом:
global_defs {
# 路由id,主备节点不能相同
router_id node1
}
# 自定义监控脚本
vrrp_script chk_haproxy {
# 脚本位置
script "/etc/keepalived/haproxy_check.sh"
# 脚本执行的时间间隔
interval 5
weight 10
}
vrrp_instance VI_1 {
# Keepalived的角色,MASTER 表示主节点,BACKUP 表示备份节点
state MASTER
# 指定监测的网卡,可以使用 ifconfig 进行查看
interface enp0s8
# 虚拟路由的id,主备节点需要设置为相同
virtual_router_id 1
# 优先级,主节点的优先级需要设置比备份节点高
priority 100
# 设置主备之间的检查时间,单位为秒
advert_int 1
# 定义验证类型和密码
authentication {
auth_type PASS
auth_pass 123456
}
# 调用上面自定义的监控脚本
track_script {
chk_haproxy
}
virtual_ipaddress {
# 虚拟IP地址,可以设置多个
192.168.0.200
}
}
Приведенная выше конфигурация определяет узел Keepalived на hadoop001 как ГЛАВНЫЙ узел и устанавливает виртуальный IP-адрес для внешних служб равным 192.168.0.200. Кроме того, главное – определитьhaproxy_check.sh
Для мониторинга HAProxy нам необходимо создать этот скрипт, содержание которого выглядит следующим образом:
#!/bin/bash
# 判断haproxy是否已经启动
if [ ${ps -C haproxy --no-header |wc -l} -eq 0 ] ; then
#如果没有启动,则启动
haproxy -f /etc/haproxy/haproxy.cfg
fi
#睡眠3秒以便haproxy完全启动
sleep 3
#如果haproxy还是没有启动,此时需要将本机的keepalived服务停掉,以便让VIP自动漂移到另外一台haproxy
if [ ${ps -C haproxy --no-header |wc -l} -eq 0 ] ; then
systemctl stop keepalived
fi
После создания дайте ему разрешение на выполнение:
chmod +x /etc/keepalived/haproxy_check.sh
Этот сценарий в основном используется для оценки нормальности службы HAProxy.Если она ненормальна и не может быть запущена, необходимо отключить локальный Keepalived, чтобы виртуальный IP-адрес можно было сместить на резервный узел. Конфигурация резервного узла в основном такая же, как и у главного узла, но его состояние нужно изменить на BACKUP, при этом его приоритет должен быть ниже, чем у главного узла. Полная конфигурация выглядит следующим образом:
global_defs {
# 路由id,主备节点不能相同
router_id node2
}
vrrp_script chk_haproxy {
script "/etc/keepalived/haproxy_check.sh"
interval 5
weight 10
}
vrrp_instance VI_1 {
# BACKUP 表示备份节点
state BACKUP
interface enp0s8
virtual_router_id 1
# 优先级,备份节点要比主节点低
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_haproxy
}
virtual_ipaddress {
192.168.0.200
}
}
4.5 Запуск службы
Запустите службу KeepAlived на Hadoop001 и Hadoop002 соответственно с помощью следующих команд:
systemctl start keepalived
После запуска hadoop001 становится главным узлом и может использоваться на hadoop001.ip a
Команда для просмотра виртуального IP:
В настоящее время на Hadoop001 есть только виртуальный IP-адрес, а на Hadoop002 нет виртуального IP-адреса.
4.6 Проверка аварийного переключения
Здесь мы проверяем отработку отказа, потому что, согласно нашему скрипту обнаружения выше, служба KeepAlived остановится, если HAProxy остановлен и не может быть перезапущен.Здесь мы напрямую используем следующую команду для остановки службы Keepalived:
systemctl stop keepalived
использовать сноваip a
Глядя на них по отдельности, можно обнаружить, что VIP на hadoop001 сместился на hadoop002.Ситуация следующая:
В это время виртуальный IP-адрес внешней службы все еще доступен, что означает, что отработка отказа была успешно выполнена. На данный момент кластер успешно построен. Любая клиентская служба, которая должна отправлять или получать сообщения, должна только подключиться к виртуальному IP-адресу. Пример выглядит следующим образом:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.0.200");
использованная литература
- Чжу Чжунхуа, Практическое руководство RabbitMQ, Electronic Industry Press, 1 ноября 2017 г.
- Официальная документация RabbitMQ — Руководство по кластеру:woohoo.rabbitcurrent.com/clustering. …
- Официальная документация RabbitMQ - Зеркальная очередь высокой доступности:www.rabbitmq.com/ha.html
- Официальное руководство по настройке HAProxy:Бернетт Чен.GitHub.io/haproxy-Investigate о...
- Официальное руководство по настройке KeepAlived:.org/ довольно страшный.htm от Woohoo.keepalive…
Дополнительные статьи см. в [Full Stack Engineer Manual], адрес GitHub:GitHub.com/Black and WhiteShould/…