Skip to main content

Пошаговая настройка резервирования

Статья описывает настройку резервированной установки ТехноДок на операционной системе Debian 12: два сервера приложений с общим виртуальным адресом и два сервера базы данных с репликацией. После каждого шага приведена проверка, по которой видно, что настройка выполнена верно.

Принцип работы​

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

У схемы два ограничения. Пользователи работают на одном сервере приложений — том, который держит виртуальный адрес; второй сервер обслуживает только периодические задачи, поэтому обычная нагрузка между серверами не распределяется. Как её распределить, описано в разделе Распределение нагрузки на nginx. При переезде виртуального адреса запрос, который выполнялся в этот момент, обрывается, и действие нужно повторить; входить заново не требуется, потому что адрес в браузере не меняется.

Машины и имена хостов​

Имя хостаАдресЧто установленоРоль
app.server1192.168.0.11ТехноДок, keepalivedСервер приложений
app.server2192.168.0.12ТехноДок, keepalivedСервер приложений
db.primary-server192.168.0.101MariaDB или PostgreSQLОсновной сервер базы данных
db.standby-server192.168.0.102MariaDB или PostgreSQLРезервный сервер базы данных

Кроме адресов самих машин схеме нужен ещё один, пятый адрес — виртуальный, в примерах это 192.168.0.20. Он не назначается ни одной машине заранее: его выдаёт себе тот сервер приложений, который сейчас обслуживает пользователей. Адрес должен принадлежать той же подсети, что и серверы приложений, и не должен быть занят другим оборудованием или выдаваться сервером DHCP. Имена хостов и адреса в примерах условные: замените их на свои везде, где они встречаются в командах и файлах конфигурации.

Сетевые требования​

Между машинами должны быть открыты следующие порты и протоколы.

ОткудаКудаПорт или протоколЗачем
Рабочие места пользователейВиртуальный адрес 192.168.0.208003/TCPРабота пользователей в браузере
app.server1, app.server2Групповой адрес 224.0.0.18VRRP, протокол 112Переезд виртуального адреса
app.server1, app.server2db.primary-server, db.standby-server3306/TCP или 5432/TCPПодключение к базе данных
db.primary-serverdb.standby-server3306/TCP или 5432/TCPРепликация
db.standby-serverdb.primary-server3306/TCP или 5432/TCPРепликация

Серверы приложений должны находиться в одной подсети: виртуальный адрес переезжает между машинами только внутри неё. Порт базы данных зависит от выбранной СУБД: 3306 у MariaDB, 5432 у PostgreSQL. Каждая машина должна разрешать имена всех остальных машин схемы. Если в сети нет своего сервера DNS, задайте имена в файле /etc/hosts — это делается на шаге 1.

Шаг 1. Подготовка машин​

Шаг выполняется на всех четырёх машинах.

  • Задайте машине её имя хоста. На app.server1 это делается так:
sudo hostnamectl set-hostname app.server1
  • Добавьте в файл /etc/hosts имена и адреса всех машин схемы:
sudo tee -a /etc/hosts > /dev/null <<'EOF'
192.168.0.11 app.server1
192.168.0.12 app.server2
192.168.0.101 db.primary-server
192.168.0.102 db.standby-server
EOF
  • Установите службу синхронизации времени: репликация и сроки действия токенов доступа опираются на системное время машин.
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
  • Если на машине включён брандмауэр ufw, разрешите обмен с остальными машинами схемы. На app.server1 это делается так:
sudo ufw allow from 192.168.0.12
sudo ufw allow to any port 8003 proto tcp

Первая команда разрешает любой обмен со вторым сервером приложений, включая VRRP: у ufw нет отдельного имени для этого протокола. Вторая открывает порт сервера приложений для рабочих мест пользователей. Состояние брандмауэра показывает команда sudo ufw status; в Debian ufw по умолчанию выключен, и тогда открывать ничего не нужно.

Проверка. Команда ping -c 1 db.primary-server с любой машины возвращает ответ, а команда chronyc tracking показывает строку Leap status : Normal.

Шаг 2. Серверы базы данных​

Установите СУБД на обе машины базы данных и настройте между ними репликацию. Порядок действий зависит от выбранной СУБД:

  • Резервирование MariaDB — репликация Master-Master, запись принимают оба сервера, переключение между ними выполняет сам ТехноДок. Рекомендуемый вариант.
  • Резервирование PostgreSQL — потоковая репликация, запись принимает один сервер. Резервный сервер повышается до основного вручную или менеджером кластера Patroni.

Базу данных ТехноДок на этом шаге создавать не нужно: её создаёт скрипт run-migrator на шаге 4, уже поверх настроенной репликации.

Проверка. С любого сервера приложений команда nc -zv db.primary-server 3306 для MariaDB или nc -zv db.primary-server 5432 для PostgreSQL сообщает об успешном подключении. Репликация проверяется по статье выбранной СУБД.

Шаг 3. Установка ТехноДок​

Шаг выполняется на обеих машинах серверов приложений: app.server1 и app.server2.

  • Распакуйте дистрибутив ТехноДок, как описано в разделе Установка статьи «Установка и обновление»:
sudo mkdir -p /opt/SMS-Automation/TechnoDoc \
&& sudo unzip "[Путь до архива ТехноДок]" -d "/opt/SMS-Automation/TechnoDoc" \
&& sudo chown -R $USER: /opt/SMS-Automation/TechnoDoc
  • Убедитесь, что на обеих машинах распакована одна и та же версия ТехноДок. Разные версии в одном кластере не работают.

Проверка. Команда ls /opt/SMS-Automation/TechnoDoc показывает содержимое дистрибутива, в том числе каталоги bin, data и scripts.

Шаг 4. Подключение к базам данных​

Шаг выполняется на обеих машинах серверов приложений.

  • Откройте файл /opt/SMS-Automation/TechnoDoc/data/application.conf. В поставке все его строки закомментированы: настройка сводится к тому, чтобы задать нужные ключи в соответствующих секциях.

  • Задайте подключение к базе данных. Секции зависят от выбранной СУБД и одинаковы на обоих серверах приложений.

    MariaDB. Запись принимают оба сервера, поэтому подключения задаются парой: основное и резервное.

    [Database]
    FailoverStrategy = RoundRobin # Разрешить возврат на основную базу данных

    [Database:Connections:Primary]
    Type = MariaDb
    ConnectionString = Server=db.primary-server;Database=technodoc;Uid=technodoc;Password=technodoc_password

    [Database:Connections:Standby]
    Type = MariaDb
    ConnectionString = Server=db.standby-server;Database=technodoc;Uid=technodoc;Password=technodoc_password

    PostgreSQL. Резервный сервер доступен только на чтение, поэтому оба сервера перечисляются в одной строке соединения, а параметр Target Session Attributes=primary выбирает тот, что открыт на запись. Секция Standby не задаётся.

    [Database:Connections:Primary]
    Type = PostgreSql
    ConnectionString = Host=db.primary-server:5432,db.standby-server:5432;Database=technodoc;User Id=postgres;Password=technodoc_password;SearchPath=td;Target Session Attributes=primary
  • Создайте базу данных. Запустите на одном сервере приложений скрипт run-migrator:

cd /opt/SMS-Automation/TechnoDoc/scripts && sh run-migrator.sh

Скрипт создаёт базу данных, её структуру и начальные данные на основном сервере базы данных. На резервный сервер базу данных переносит репликация, поэтому запускать скрипт на втором сервере приложений не нужно.

Проверка. На обоих серверах базы данных появилась база данных technodoc с одинаковым набором таблиц, а репликация работает без ошибок. Для MariaDB это показывают команды sudo mysql -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'technodoc'" и sudo mysql -e "SHOW SLAVE STATUS\G", для PostgreSQL — sudo -u postgres psql -d technodoc -c "\dt td.*" на каждом сервере и sudo -u postgres psql -c "SELECT * FROM pg_stat_replication" на основном сервере.

Шаг 5. Запуск серверов приложений​

Шаг выполняется на обеих машинах серверов приложений.

cd /opt/SMS-Automation/TechnoDoc/scripts/service
sh create.sh
sudo sh start.sh

Проверка. Команда curl http://app.server1:8003/health возвращает Healthy; то же самое возвращает curl http://app.server2:8003/health. Если сервер не отвечает, посмотрите последние записи в файлах каталога /opt/SMS-Automation/TechnoDoc/logs.

Шаг 6. Виртуальный адрес​

Виртуальный адрес выдаёт себе один из серверов приложений, а вторая машина следит за первой и забирает адрес, когда та перестаёт отвечать. Договариваются машины между собой по протоколу VRRP, а занимается этим служба keepalived.

Примечание

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

Шаг выполняется на обеих машинах серверов приложений.

  • Установите keepalived:
sudo apt update && sudo apt install -y keepalived
  • Узнайте имя сетевого интерфейса, через который машина работает в подсети серверов приложений:
ip -brief address

В выводе найдите строку с адресом машины, например 192.168.0.11/24, и запомните имя интерфейса из первого столбца. В примерах ниже это ens18: замените его на имя, полученное на каждой машине, — на разных машинах оно может отличаться.

  • Создайте файл /etc/keepalived/keepalived.conf. На app.server1:
# Проверка сервера приложений: адрес переезжает и при отказе машины, и при остановке ТехноДок
vrrp_script check_technodoc {
script "/usr/bin/curl --fail --silent http://127.0.0.1:8003/health"
interval 2
timeout 2
fall 2
rise 2
weight -30
}

vrrp_instance technodoc {
state MASTER
interface ens18
virtual_router_id 51
priority 100
advert_int 1

authentication {
auth_type PASS
auth_pass td-vrrp1
}

virtual_ipaddress {
192.168.0.20/24
}

track_script {
check_technodoc
}
}

На app.server2 файл отличается двумя значениями:

state BACKUP
priority 90
  • Запустите службу и включите её автозапуск:
sudo systemctl enable --now keepalived

Проверка. На app.server1 команда ip -brief address show ens18 показывает два адреса: собственный адрес машины и виртуальный. На app.server2 виртуального адреса быть не должно — его держит только одна машина. Команда curl http://192.168.0.20:8003/health с рабочего места пользователя возвращает Healthy.

Примечание

Пользователи открывают ТехноДок по виртуальному адресу напрямую: http://192.168.0.20:8003. Если зоной DNS можно управлять, задайте в ней имя и укажите в записи виртуальный адрес — тогда при смене адреса схемы закладки пользователей останутся рабочими.

Шаг 7. Первый вход​

  • Откройте в браузере собственный адрес первого сервера приложений: http://app.server1:8003.
  • Введите лицензионный ключ. Демо-лицензию можно получить кнопкой «Запросить демо-лицензию», долгосрочную — запросить по адресу technodoc@sms-a.ru.
  • Войдите с логином и паролем admin / admin и смените пароль администратора.
  • Повторите первые два действия на втором сервере приложений, открыв его собственный адрес http://app.server2:8003.

Собственные адреса серверов нужны только для первого входа. Дальше пользователи и администратор открывают ТехноДок по виртуальному адресу http://192.168.0.20:8003.

Проверка. Откройте страницу «Администрирование» → «Диагностика» → «Сервер» и посмотрите блок «База данных»: для MariaDB в нём две строки, «Основная» с пометкой «Используется» и «Резервная», обе со значением «Доступна» в столбце «Состояние»; для PostgreSQL — одна строка «Основная» с теми же пометками. Для MariaDB там же виден блок «Репликация БД»: для каждой базы данных значение «Да» в строке «Активна» и пустые строки «Ошибка чтения/записи» и «Ошибка запроса». Для PostgreSQL этот блок не выводится — состояние репликации смотрите средствами СУБД.

Встроенное переключение вместо виртуального адреса​

Встроенное переключение заменяет виртуальный адрес там, где развернуть его нельзя: серверы приложений находятся в разных подсетях или сеть не пропускает VRRP. Настройка сети для него не требуется, но отказ сервера пользователь заметит.

Если сервер, с которым работает пользователь, перестал отвечать, ТехноДок несколько раз пытается отправить запрос повторно и лишь через несколько секунд показывает окно «Сервис недоступен». Пока окно открыто, работать в приложении нельзя. ТехноДок продолжает проверять доступность сервера и закрывает окно сам, как только сервер ответит, поэтому при коротком сбое достаточно подождать. Пользователь может сразу подключиться к другому серверу, тогда откроется первый доступный сервер из списка. Действие, на котором оборвалась связь, нужно будет повторить.

Единого адреса в этой схеме нет: пользователи открывают серверы по их собственным адресам, например http://app.server1:8003. Когда сервер перестаёт отвечать, ТехноДок предлагает перейти на второй сервер; пользователь подтверждает переход и входит заново.

Настройка выполняется на обеих машинах серверов приложений вместо шага 6.

  • Задайте в файле /opt/SMS-Automation/TechnoDoc/data/application.conf адреса остальных серверов кластера. Файл на app.server1:
[Cluster]
ServersAddresses:0 = http://app.server2:8003 # Адрес второго сервера кластера

На app.server2 в той же секции задайте адрес первого сервера:

[Cluster]
ServersAddresses:0 = http://app.server1:8003 # Адрес первого сервера кластера

Текущий сервер в списке не указывают.

  • Перезапустите оба сервера приложений командой sudo systemctl restart technodoc.
Примечание

Рабочее место должно разрешать имена всех серверов кластера. Если своего сервера DNS в сети нет, задайте в списке IP-адреса вместо имён хостов.

Проверка. Откройте ТехноДок по адресу http://app.server1:8003 и войдите в систему. На странице «Администрирование» → «Диагностика» → «Сервер» в таблице «Кластер серверов» указан http://app.server2:8003 со значением «Доступен» в столбце «Состояние». Текущий сервер в таблице не выводится: в ней перечислено то, что задано в секции [Cluster].

У встроенного переключения есть ряд ограничений:

  • Переход возможен, только если ТехноДок уже открыт в браузере. Если сервер недоступен в момент первого обращения, пользователь увидит стандартную ошибку браузера.
  • Переход выполняется только после подтверждения пользователем и меняет адрес в браузере: несохранённые данные на открытых формах теряются, а на новом сервере потребуется войти заново.
  • Все пользователи переходят на первый доступный сервер из списка и остаются на нём: нагрузка между серверами не распределяется, а после восстановления прежнего сервера пользователи на него не возвращаются.
  • Предпочтения пользователя — адресаты рассылки, фильтры в дереве тегов — не сохраняются.

Распределение нагрузки на nginx​

В схеме, собранной выше, пользователи работают на одном сервере приложений — том, который держит виртуальный адрес. Обратный прокси nginx распределяет запросы между обоими серверами. Настраивать его стоит, когда одного сервера не хватает на всех пользователей.

nginx ставится на обе машины серверов приложений и работает на той из них, которая держит виртуальный адрес. Пользователи обращаются к порту 80, nginx распределяет запросы между app.server1 и app.server2 и перестаёт отправлять их на сервер, который не отвечает.

Шаг выполняется на обеих машинах серверов приложений.

  • Установите nginx:
sudo apt update && sudo apt install -y nginx
  • Создайте файл /etc/nginx/conf.d/technodoc.conf. Он одинаков на обеих машинах:
# В журнал доступа добавляется адрес сервера приложений, обработавшего запрос
log_format technodoc '$remote_addr -> $upstream_addr $status "$request" $request_time';

upstream technodoc {
zone technodoc 64k;

server app.server1:8003 max_fails=2 fail_timeout=10s;
server app.server2:8003 max_fails=2 fail_timeout=10s;

keepalive 32;
}

server {
listen 80;
server_name _;

access_log /var/log/nginx/technodoc-access.log technodoc;
error_log /var/log/nginx/technodoc-error.log;

# Размер вложений и импортируемых файлов ТехноДок не ограничивает
client_max_body_size 0;

location / {
proxy_pass http://technodoc;

proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_connect_timeout 5s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;

# Если сервер приложений не ответил, запрос повторяется на втором сервере
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 2;
}
}
  • Удалите сайт по умолчанию. В Debian после установки nginx обслуживает порт 80 своим сайтом из поставки, и до конфигурации ТехноДок запросы не доходят: вместо приложения открывается страница «404 Not Found».
sudo rm /etc/nginx/sites-enabled/default
Предупреждение

Настраивайте распределение нагрузки на машинах, где nginx не обслуживает другие сайты. Удаление сайта по умолчанию и занятый ТехноДок порт 80 нарушат работу остальных сайтов на этом nginx.

  • Проверьте синтаксис файла конфигурации и примените его:
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl enable nginx
  • Переведите проверку keepalived на nginx: теперь пользователей обслуживает он, а сервер приложений может работать и на соседней машине. В файле /etc/keepalived/keepalived.conf на обеих машинах замените строку script на следующую и перезапустите службу командой sudo systemctl restart keepalived:
script "/usr/bin/curl --fail --silent http://127.0.0.1/health"
  • Откройте на серверах приложений порт 80 для рабочих мест пользователей. Если включён ufw, это делается так:
sudo ufw allow to any port 80 proto tcp
Примечание

Если на серверах приложений задан список серверов кластера, как в разделе Встроенное переключение вместо виртуального адреса, добавьте в него адрес, по которому пользователи теперь открывают ТехноДок. Сервер приложений принимает обращения браузера только с адресов из своего списка, и без такой записи соседний сервер будет показан как «Недоступен». Задайте запись в секции [Cluster] файла application.conf на обеих машинах и перезапустите серверы командой sudo systemctl restart technodoc:

[Cluster]
ServersAddresses:1 = http://192.168.0.20 # Виртуальный адрес, по которому работают пользователи

Проверка. Команда curl http://192.168.0.20/health с рабочего места пользователя возвращает Healthy. Выполните её несколько раз подряд и посмотрите журнал командой sudo tail /var/log/nginx/technodoc-access.log на машине с виртуальным адресом: в столбце после стрелки должны встретиться адреса обоих серверов приложений. Пользователи теперь открывают адрес без порта, например http://192.168.0.20.