Высокая доступность
Высокая доступность ТехноДок складывается из двух частей: резервирования серверов приложений и резервирования базы данных.
Резервирование серверов приложений. ТехноДок устанавливается на несколько серверов, подключённых к общей базе данных. Серверы равноправны: пользователи могут подключиться к любому из них, а каждая периодическая задача выполняется только на одном сервере.
Резервирование базы данных. В настройках сервера приложений задаются два подключения: к основной и резервной базам данных. Пока основная база данных отвечает, сервер работает с ней, а когда она перестаёт отвечать, продолжает работу с резервной.
Переключение с основной базы данных на резервную и распределение периодических задач между серверами выполняет ТехноДок. Репликацию между серверами баз данных и распределение пользователей между серверами приложений администратор должен настроить средствами СУБД и сетевой инфраструктуры.
Резервирование серверов приложений
Принцип работы
Серверы приложений в кластере равноправны: ведущего и резервного сервера нет, любой из них обслуживает пользователей наравне с остальными. Настройки и данные хранятся в базе данных, общей для всего кластера: все серверы должны быть подключены к ней. Периодические задачи остаются включёнными на всех серверах кластера, отключать их на отдельных серверах не нужно.
Выбор схемы подключения
Администратор должен выбрать и настроить одну из схем подключения, перечисленных в таблице ниже, чтобы пользователи могли подключиться к доступному серверу ТехноДок. Рекомендуется использовать обратный прокси с единой точкой входа. Пользователи открывают в браузере адрес прокси, а он распределяет запросы между доступными серверами приложений.
| Вариант | Когда подходит |
|---|---|
| Обратный прокси, например nginx или HAProxy | Рекомендуемый вариант. Подходит, когда есть отдельный сервер для прокси и его тоже можно зарезервировать: отказ сервера приложений пользователи не замечают, а обычная нагрузка распределяется между серверами. |
Виртуальный IP-адрес, например keepalived в Linux или Network Load Balancing в Windows Server | Подходит, когда серверы стоят в одной подсети, а отдельный сервер для прокси развернуть нельзя. Отказ сервера пользователи не замечают, но обычная нагрузка между серверами не распределяется. |
| Запись DNS с небольшим временем жизни | Подходит, когда доступно управление зоной DNS, а прокси и виртуальный IP-адрес развернуть нельзя. После отказа работа возобновляется не сразу: браузер и операционная система могут держать прежний адрес дольше указанного времени жизни записи. |
| Встроенное переключение в ТехноДок | Подходит, когда настроить сеть невозможно. Работает, только когда приложение открыто в браузере: пользователь подтверждает переход и входит на новом сервере заново. |
Встроенное переключение
Встроенное переключение применяется там, где развернуть балансировщик или управлять записями DNS невозможно: настройка сети для него не нужна. Единую точку входа и встроенное переключение можно настроить одновременно.
Поведение при отказе сервера
Если сервер, с которым работает пользователь, перестал отвечать, ТехноДок несколько раз пытается отправить запрос повторно и лишь через несколько секунд показывает окно «Сервис недоступен». Пока окно открыто, работать в приложении нельзя. ТехноДок продолжает проверять доступность сервера и закрывает окно сам, как только сервер ответит, поэтому при коротком сбое достаточно подождать. Пользователь может сразу подключиться к другому серверу, тогда откроется первый доступный сервер из списка Cluster:ServersAddresses. Действие, на котором оборвалась связь, нужно будет повторить.
У встроенного переключения есть ряд ограничений:
- Переход возможен, только если ТехноДок уже открыт в браузере. Если сервер недоступен в момент первого обращения, пользователь увидит стандартную ошибку браузера.
- Переход выполняется только после подтверждения пользователем и меняет адрес в браузере: несохранённые данные на открытых формах теряются, а на новом сервере потребуется войти заново.
- Все пользователи переходят на первый доступный сервер из списка и остаются на нём: нагрузка между серверами не распределяется, а после восстановления прежнего сервера пользователи на него не возвращаются.
- Предпочтения пользователя — адресаты рассылки, свёрнутые модули на главной странице, фильтры в дереве тегов — не сохраняются.
Настройка встроенного переключения
На каждом сервере выполните следующие действия.
- Убедитесь, что на сервере установлена та же версия Тех ноДок, что и на остальных серверах кластера.
- Укажите в файле
application.confв секции[Cluster]адреса остальных серверов кластера. Текущий сервер указывать не требуется.
Файл application.conf на хосте app.server1:
[Cluster]
ServersAddresses:0 = http://app.server2:8003 # Адрес второго сервера кластера
Файл application.conf на хосте app.server2:
[Cluster]
ServersAddresses:0 = http://app.server1:8003 # Адрес первого сервера кластера
- Перезапустите оба сервера приложений ТехноДок.
- Откройте страницу «Администрирование» → « Диагностика» → «Сервер» и убедитесь, что в таблице «Кластер серверов» перечислены все серверы и в столбце «Состояние» у них указано «Доступен».
Резервирование базы данных
Резервирование базы данных работает с PostgreSQL и MariaDB; сравнение этих СУБД приведено в статье Настройка базы данных. Рекомендуется использовать MariaDB, в которой репликация Master-Master позволяет обоим серверам принимать запись, поэтому переключение между ними выполняет сам ТехноДок и внешние средства не нужны. В PostgreSQL резервный сервер доступен только на чтение, и его повышение до основного настраивается отдельно.
Настройка складывается из четырёх шагов:
- Задайте подключения к базам данных в файле
application.conf. - Если база данных ещё не создана, запустите скрипт
run-migratorиз директорииscriptsна одном из серверов приложений. Он создаст базу данных и её структуру по каждому подключ ению, заданному в файлеapplication.conf. - Настройте репликацию между серверами баз данных средствами СУБД.
- Перезапустите сервер приложений и проверьте на странице «Администрирование» → «Диагностика» → «Сервер», что подключения базы данных отмечены как доступные.
Подключения и репликация настраиваются по-разному в зависимости от выбранной СУБД; оба шага описаны ниже.
Принцип работы
В файле application.conf задаются два подключения: основное в секции [Database:Connections:Primary] и резервное в секции [Database:Connections:Standby]. Сервер приложений работает с основной базой данных, а когда она перестаёт отвечать, продолжает работу с резервной. Переключение остаётся незаметным для пользователя. Если недоступны обе базы данных, пользователь увидит окно «Сервис недоступен». На странице «Администрирование» → «Диагностика» → «Сервер» показано, какая база данных активна и доступна сейчас, а для MariaDB — актуальное состояние репликации.
Настройка Database:FailoverStrategy определяет, разрешено ли серверу вернуться на основную базу данных:
RoundRobin— разрешено. Значение по умолчанию.Forbid— запрещено. Сервер, перешедший на резервную базу данных, остаётся на ней до перезапуска.
Даже при значении RoundRobin сервер не возвращается на основную базу данных сразу после её восстановления. Он проверяет её доступность только тогда, когда перестанет отвечать резервная база данных. Чтобы вернуть сервер на основную базу данных в удобное время, перезапустите его.
Резервирование MariaDB
Подключение к MariaDB
Оба сервера MariaDB принимают запись, поэтому подключения задаются парой: основное и резервное.
[Database]
FailoverStrategy = RoundRobin # Разрешить возврат на основную базу данных
[Database:Connections:Primary]
Type = MariaDb
ConnectionString = Server=db.primary-server;Database=technodoc;Uid=root;Password=password
[Database:Connections:Standby]
Type = MariaDb
ConnectionString = Server=db.standby-server;Database=technodoc;Uid=root;Password=password
Репликация MariaDB
MariaDB поддерживает репликацию Master-Master, при которой запись принимают оба сервера базы данных. Ниже приведены шаги её настройки.
На первом сервере
- Добавьте в секцию
[mysqld]файла конфигур ации MariaDB следующие настройки:
sql-mode = "ANSI_QUOTES"
datadir = путь к данным
server-id = 1
log-bin = bin-log
bind-address = 0.0.0.0
auto_increment_increment = 2
auto_increment_offset = 1
- Перезапустите службу MariaDB командой
systemctl restart mariadbв Linux илиnet start mariadbв Windows. - Подключитесь к базе данных командой
mysql -u root -p, гдеroot— имя пользователя. - Создайте пользователя, от имени которого будет выполняться репликация:
create user 'replication_user'@'%' identified by 'replication_user_password';
grant replication slave on *.* to 'replication_user'@'%';
- Посмотрите состояние двоичного журнала командой
show master status;. Значения полейFileиPositionпонадобятся при настройке второго сервера.
| File | Position
| mariadb-bin.000001 | 314
На втором сервере
- Добавьте в секцию
[mysqld]файла конфигурации MariaDB те же настройки, что и на первом сервере, изменив два значения:
server-id = 2
auto_increment_offset = 2
- Перезапустите службу MariaDB, подключитесь к базе данных и создайте пользователя для репликации так же, как на первом сервере.
- Остановите репликацию командой
stop slave;. - Укажите, откуда читать двоичный журнал первого сервера:
CHANGE MASTER TO MASTER_HOST='db.primary-server', MASTER_USER='replication_user', MASTER_PASSWORD='replication_user_password', MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=314;
Здесь MASTER_HOST — адрес первого сервера, MASTER_USER и MASTER_PASSWORD — учётные данные созданного пользователя, MASTER_LOG_FILE и MASTER_LOG_POS — имя журнала и позиция, полученные на первом сервере.
- Запустите репликацию командой
start slave;. - Проверьте состояние командой
show slave status \G. Числовые значения в поляхRead_Master_Log_PosиRelay_Log_Posозначают, что ошибок нет. - Посмотрите состояние двоичного журнала командой
show master status;. Значения полейFileиPositionпонадобятся для настройки репликации на первом сервере.
| File | Position
| mariadb-bin.000002 | 8196
Снова на первом сервере
- Остановите репликацию командой
stop slave;. - Укажите, откуда читать двоичный журнал второго сервера:
CHANGE MASTER TO MASTER_HOST='db.standby-server', MASTER_USER='replication_user', MASTER_PASSWORD='replication_user_password', MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=8196;
- Запустите репликацию командой
start slave;и проверьте её состояние командойshow slave status \G.
Состо яние репликации
Состояние репликации активного сервера базы данных отображается на странице «Администрирование» → «Диагностика» → «Сервер»: статус и состояние потока чтения журнала, время последней синхронизации и последние ошибки чтения и выполнения запросов. Если после отказа или аварийной остановки репликация не возобновилась, запустите её на этом сервере командой start slave;.
Резервирование PostgreSQL
Подключение к PostgreSQL
Резервный сервер PostgreSQL доступен только на чтение, поэтому отдельные подключения Primary и Standby для него не подходят: записать данные в резервный сервер ТехноДок не сможет. Перечислите оба сервера в одной строке соединения — параметр Target Session Attributes=primary выбирает сервер, открытый на запись.
[Database:Connections:Primary]
Type = PostgreSql
ConnectionString = Host=db.primary-server:5432,db.standby-server:5432;Database=technodoc;User Id=postgres;Password=password;SearchPath=td;Target Session Attributes=primary
Переключение между серверами в этом случае выполняет драйвер PostgreSQL, а не ТехноДок, поэтому настройка Database:FailoverStrategy на него не влияет. Сервер, открытый на запись, появляется после повышения резервного сервера до основного — автоматически или вручную, в зависимости от выбранной схемы репликации.
Репликация PostgreSQL
PostgreSQL поддерживает несколько способов организации высокой доступности; они описаны в разделе High Availability, Load Balancing, and Replication документации PostgreSQL. При потоковой репликации резервный сервер доступен только на чтение, поэтому при отказе основного сервера резервный нужно повысить до основного. Сделать это можно двумя способами.
- Менеджер кластера — Patroni, repmgr или pg_auto_failover — повышает резервный сервер автоматически. Это вариант для промышленной установки; настройка описана в документации выбранного менеджера.
- Без менеджера кластера резервный сервер повышает администратор, как описано в подразделе «Переключение резервного сервера PostgreSQL в режим основного». До этого момента ТехноДок не может записывать данные.
Ниже приведён пример ручной настройки потоковой репликации для PostgreSQL 13 и новее.
В примере используются серверы db.primary-server с адресом 192.168.0.101 и db.standby-server с адресом 192.168.0.102; замените их имена и адреса на свои.
На основном сервере
- Выполните SQL-команды:
ALTER SYSTEM SET listen_addresses TO '*';
ALTER SYSTEM SET wal_log_hints TO 'on';
SELECT * FROM pg_create_physical_replication_slot('__slot');
Значения wal_level, max_wal_senders и hot_standby менять не нужно: в PostgreSQL 13 и новее они по умолчанию подходят для потоковой репликации. Параметр wal_log_hints нужен утилите pg_rewind, слот репликации __slot — резервному серверу.
- Создайте пользователя с правом репликации:
CREATE ROLE username WITH REPLICATION LOGIN PASSWORD 'replica_password';
- Добавьте в файл
pg_hba.confследующие записи:
host all all 192.168.0.101/32 scram-sha-256
host all all 192.168.0.102/32 scram-sha-256
host replication all 192.168.0.101/32 scram-sha-256
host replication all 192.168.0.102/32 scram-sha-256
Записи host replication разрешают репликацию, записи host all нужны утилите pg_rewind: она подключается к базе данных postgres на друго м сервере.
- Перезапустите сервер PostgreSQL.
На резервном сервере
- Остановите сервер PostgreSQL. В Linux это делается командой
sudo systemctl stop postgresql, гдеpostgresql— имя службы, оно зависит от версии PostgreSQL. - Очистите каталог данных
PG_DATA. - Выполните команду
pg_basebackup -D "PG_DATA" -h ip_master -p port_master -X stream -c fast -S __slot -U username -W -R, где:pg_basebackup— утилита из поставки PostgreSQL, расположенная в каталогеbinсервера базы данных;PG_DATA— каталог данных PostgreSQL;ip_master— адрес или имя хоста основного сервера базы данных, в примере этоdb.primary-server;port_master— порт основного сервера базы данных, по умолчанию 5432;__slot— имя слота репликации, созданного на основном сервере;username— имя пользователя с правом репликации или суперпользователя.
- Запустите сервер PostgreSQL. В Linux это делается командой
sudo systemctl start postgresql.
- Не задавайте параметр
synchronous_standby_names: при синхронной репликации основной сервер ждёт подтверждения от резервного, и остановка резервного сервера остановит запись на основном. - Слот репликации удерживает журналы предзаписи на основном сервере, пока резервный сервер их не заберёт. Если резервный сервер долго не работает, журналы заполнят диск основного сервера; ограничить их объём позволяет параметр
max_slot_wal_keep_size. - Утилиту
pg_basebackupнужно выполнять от имени пользователя, от которого запускается сервер PostgreSQL. - Если команда завершается сообщением «Не удалось подключиться к серверу» или «Нет маршрута к хосту», проверьте настройки брандмауэра и файл
pg_hba.conf.
Переключение резервного сервера PostgreSQL в режим основного
При отказе основного сервера базы данных выполните на резервном сервере команды:
CHECKPOINT;
SELECT pg_promote();
SELECT * FROM pg_create_physical_replication_slot('__slot');
После повышения сервер принимает запись, и ТехноДок продолжает работу с ним. Слот репликации понадобится, когда прежний основной сервер вернётся в схему как резервный.
Возврат прежнего сервера в качестве резервного
После восстановления связи или работоспособности прежнего сервера выполните следующие действия:
- Остановите сервер штатно, если он запущен. Если сервер был остановлен аварийно, запустите его и остановите штатно, иначе
pg_rewindзавершится ошибкой. - Выполните команду
pg_rewind --target-pgdata=PG_DATA --source-server="user=username port=port_master host=master_host dbname=postgres" -R, гдеmaster_host— адрес нового основного сервера, в примере этоdb.standby-server. - Запустите сервер.
При серьёзных повреждениях данных pg_rewind завершается ошибкой. В этом случае настройте сервер заново, как описано в разделе На резервном сервере.