Кластер с резервным узлом
Два сервера с одинаковой установкой используют одну базу данных PostgreSQL, но платформа работает только на одном из них. Если основной узел выходит из строя, платформу запускают на резервном, и он продолжает работу с теми же данными. Общие требования к кластеру и сравнение с вариантом распределения нагрузки — в разделе Установка в режиме кластера. Если диалогов больше, чем выдерживает один сервер, используйте распределение нагрузки.
В этой схеме платформа работает только на одном узле. Если запустить её на обоих, каждый экземпляр будет держать ботов и настройки в собственной памяти и не узнает об изменениях, сделанных на другом. Если вы случайно запустили платформу на обоих узлах, остановите резервный и перезапустите основной.
Схема
Сплошные линии показывают рабочие связи, пунктирные — связи резервного узла и реплики, которые включаются при отказе.
| Элемент | Назначение |
|---|---|
| Узел 1 и узел 2 | Одинаковые установки iQBot с языковым сервером. Служба iqbot запущена только на основном узле. |
| Единый адрес (VIP) | Адрес, по которому работают iQChannels и администраторы. Он переходит на тот узел, где запущена платформа. Это значение IQB_EXTERNAL_URL. |
| Единый адрес базы данных | Адрес, который всегда указывает на текущий основной сервер PostgreSQL. |
| PostgreSQL | Основной сервер и реплика. В базе лежат боты, диалоги, пользователи и модели NLU, поэтому узлы iQBot не хранят ничего своего. |
Что нужно подготовить
- Два сервера Linux x64 одинаковой конфигурации, подходящей под требования. Память языкового сервера нужна на каждом узле.
- Отказоустойчивая PostgreSQL 13 или новее с единым адресом записи, см. общие требования.
- Виртуальный IP-адрес и DNS-имя для него, например
bot.example.com. - Дистрибутив и файлы языковых моделей, одинаковой версии на обоих узлах.
Шаг 1. Отказоустойчивая база данных
Подготовьте PostgreSQL с репликацией и единым адресом записи, как описано в разделе Установка в режиме кластера. Базу и пользователя создайте на основном сервере, как в шаге 1 раздела Установка iQBot на Linux.
Шаг 2. Установите основной узел
Выполните шаги 2–7 раздела Установка iQBot на Linux. В файле .env задайте общие для кластера значения:
IQB_DATABASE_URL=postgres://iqbot:<пароль>@db.example.com:5432/iqbot
IQB_IQBFS_STORAGE=database
IQB_PRODUCTION=true
IQB_EXTERNAL_URL=https://bot.example.com
IQB_ADMIN_EMAIL=admin@example.com
IQB_ADMIN_PASSWORD=<стойкий пароль>
Здесь db.example.com — единый адрес базы данных, bot.example.com — имя виртуального адреса iQBot. Режим IQB_IQBFS_STORAGE=database обязателен: в нём боты, настройки и ключ подписи токенов хранятся в базе, а не на диске узла. Если в каталоге data/bots дистрибутива уже есть боты, при первом запуске на пустую базу они попадут в базу.
Проверьте, что платформа поднялась:
curl http://localhost:3000/status
Все компоненты должны быть в состоянии up. Затем создайте тестового бота и убедитесь, что вход в консоль работает.
Шаг 3. Установите резервный узел
-
Повторите шаги 2–5 и 7 раздела Установка iQBot на Linux на втором сервере. Файл
.envскопируйте с первого узла без изменений. В шаге 7 включите только службуiqbot-lang, службуiqbotне включайте. Языковой сервер на резервном узле оставьте запущенным, он занимает память, но ускоряет переключение. -
Выполните пробный запуск. Остановите службу на основном узле, запустите на резервном и откройте консоль:
# на узле 1
sudo systemctl stop iqbot
# на узле 2
sudo systemctl start iqbot
curl http://localhost:3000/statusВ консоли должны быть все боты, созданные через первый узел, а вход под той же учётной записью работать без повторной настройки. Токен, выданный первым узлом, второй узел тоже принимает.
-
Остановите службу на резервном узле и отключите её автозапуск на обоих узлах: запуском теперь управляет схема переключения, а не загрузка сервера.
sudo systemctl stop iqbot
sudo systemctl disable iqbot -
Запустите службу на основном узле. Если вы используете keepalived, это сделает скрипт запуска, см. ниже.
Языковой сервер и NLU установлены на обоих узлах, но под нагрузкой работает только один. Не планируйте на резервном узле меньше ресурсов, чем на основном: после отказа он принимает всю нагрузку.
Шаг 4. Единый адрес и HTTPS
Обратный прокси-сервер (NGINX) с сертификатом для bot.example.com установите на оба узла. Он слушает все адреса сервера и передаёт запросы на http://127.0.0.1:3000. На резервном узле платформа не запущена, и прокси отвечает ошибкой 502, пока узел не станет основным. Подробности настройки HTTPS — в разделе Безопасность iQBot.
Виртуальный адрес должен принадлежать только тому узлу, где запущена платформа. Как переключать его, решает ваша инфраструктура: балансировщик с проверкой состояния, ручное переключение или keepalived.
Переключение на резервный узел вручную
Порядок одинаков для отказа и для плановых работ:
- Убедитесь, что платформа на основном узле остановлена:
sudo systemctl stop iqbot. Если сервер недоступен, отключите его от сети или выключите, чтобы он не вернулся с запущенной платформой. - Переведите виртуальный адрес на резервный узел.
- Запустите платформу на резервном узле:
sudo systemctl start iqbot. - Дождитесь, когда
curl http://localhost:3000/statusпокажетupдля всех компонентов. Запуск занимает меньше минуты. - Проверьте, что бот отвечает в iQChannels.
Состояние диалогов хранится в базе данных, поэтому после переключения диалог клиента продолжается. Сообщения, отправленные во время переключения, могут остаться без ответа.
Автоматическое переключение с keepalived
Если переключение должно происходить без участия человека, виртуальным адресом и запуском службы управляет keepalived. Ниже пример для двух узлов. Замените адреса, имя сетевого интерфейса и пароль своими значениями и проверьте схему на тестовом контуре, прежде чем использовать её в продуктиве.
Скрипт проверки /etc/keepalived/iqbot-check.sh (на обоих узлах, chmod +x):
#!/bin/bash
VIP=10.0.0.100
# Резервному узлу платформа не нужна: проверка проходит
ip -4 addr show | grep -q " $VIP/" || exit 0
# После запуска платформе даётся три минуты
F=/run/iqbot-promoted
[ -f $F ] && [ $(( $(date +%s) - $(stat -c %Y $F) )) -lt 180 ] && exit 0
curl -fs -m 3 http://127.0.0.1:3000/status > /dev/null
Скрипт запуска и остановки /etc/keepalived/iqbot-notify.sh (на обоих узлах, chmod +x):
#!/bin/bash
case "$1" in
master) touch /run/iqbot-promoted; systemctl start iqbot ;;
backup) systemctl stop iqbot ;;
esac
Файл /etc/keepalived/keepalived.conf. На втором узле значение priority задайте 90:
vrrp_script chk_iqbot {
script "/etc/keepalived/iqbot-check.sh"
interval 5
fall 3
rise 2
weight -60
}
vrrp_instance IQBOT {
state BACKUP
nopreempt
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass <пароль>
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
chk_iqbot
}
notify_master "/etc/keepalived/iqbot-notify.sh master"
notify_backup "/etc/keepalived/iqbot-notify.sh backup"
notify_fault "/etc/keepalived/iqbot-notify.sh backup"
notify_stop "/etc/keepalived/iqbot-notify.sh backup"
}
Как это работает. Узел, получивший виртуальный адрес, запускает платформу, а узел, потерявший его, останавливает. Если на узле с адресом /status перестаёт отвечать, его приоритет падает ниже приоритета второго узла, и адрес переходит туда. Параметр nopreempt не даёт адресу вернуться на исправившийся узел сам, чтобы платформа не переключалась туда и обратно.
Проверка отказоустойчивости
Проверьте схему до выхода в продуктив:
- Создайте тестового бота через основной узел и запомните его идентификатор.
- Остановите основной узел так, как это сделает отказ: выключите сервер или остановите службу.
- Дождитесь переключения. Откройте консоль по
https://bot.example.com/admin/, тестовый бот должен быть в списке. - Отправьте сообщение боту из iQChannels и убедитесь, что ответ пришёл.
- Верните основной узел в строй. Он должен стать резервным и не запускать платформу.
Обновление кластера
Обновлять нужно оба узла до одной версии. Платформа меняет структуру базы при обновлении, поэтому на время миграции работа прекращается.
- Сделайте резервную копию базы данных, см. Резервное копирование и обновление.
- Остановите автоматическое переключение (
sudo systemctl stop keepalivedна обоих узлах) и службуiqbotна основном узле. - Замените дистрибутив на обоих узлах.
- На основном узле один раз запустите платформу с
IQB_AUTO_MIGRATE=true, проверьте/statusи работу одного бота, затем уберите переменную. - Верните автоматическое переключение. Резервный узел останется остановленным.
Что не входит в схему
- Распределение нагрузки и работа нескольких экземпляров одновременно: см. Кластер с распределением нагрузки.
- Общее хранилище файлов: платформа в режиме
IQB_IQBFS_STORAGE=databaseхранит всё в базе, общий диск не нужен. - Резервирование iQChannels и iQGPT: они настраиваются отдельно в своих продуктах.