Содержание
Коротко
На «Хабре» разбирают перенос рабочей системы на Totum с одной виртуальной машины на схему из двух основных серверов и маленького свидетеля. Третью полноценную машину покупать не хотели, но кворум для хранилища конфигурации без неё не собрать. База переключается сама, приложение пишет только на текущем ведущем узле, файлы едут в одну сторону, а внешний балансировщик смотрит на проверку здоровья и не требует ручной смены DNS.
Что произошло
Totum — платформа с открытым размещением у себя для внутренних веб-приложений: учёт, кабинеты, прикладные таблицы и своя логика, плюс исходящие запросы по HTTP. В статье это уже не стенд, а боевая система с PostgreSQL, файлами пользователей и интеграциями. Условия были жёсткие и бытовые: падение одной основной машины не останавливает систему, база переключается сама, приложение знает, где ему можно писать, файлы доступны после переключения, DNS руками не трогают, всё раскатывается через Ansible.
Свидетель почти не несёт прикладную нагрузку. Он нужен, чтобы у etcd был кворум. PostgreSQL ведут через Patroni: выбор ведущего и асинхронная реплика. Роль приложения привязана к этому ведущему. Проверка смотрит, является ли текущий узел основным у Patroni; если да — создаётся признак активного узла, если нет — признак снимается. Идея короткая: кто держит базу на запись, тот и есть единственное живое приложение.
Балансировщик седьмого уровня знает оба узла Totum, но здоровье спрашивает у GET /ha-health. Активный отвечает HTTP 200, пассивный — HTTP 503. Когда Patroni меняет ведущего, проверка роли обновляет признак, балансировщик видит новую картину и уводит людей на другой узел. Имена в DNS при этом не переписывают.
Файлы через Patroni не едут. Их синхронизируют lsyncd и rsync, и только в одну сторону: с активного на пассивный. После переключения направление разворачивается вместе с ролью. Двустороннее копирование автор называет опасным: обе машины начнут писать друг другу и получат конфликты. Поэтому принимать изменения может только пассивный узел — это и есть ограждение.
Отдельно всплыла не база, а пул PHP-FPM. Медленные исходящие вызовы через curl держали рабочих процессов, новые запросы ждали, и интерфейс выглядел мёртвым целиком. Временный медленный журнал с порогом 2 секунды и глубиной следа 50 показал зависания на внешних вызовах, длинном опросе и проверке уведомлений. Замер вокруг curl разложил время: соединение около 0,01 секунды, а время до первого байта — 76,4 и 15,6 секунды. Ждали не сеть до соседа, а чужой ответ. Пул увеличили: до 40 детей, старт и запас по 20, потолок запаса 40. Отдельный медленный запрос остался медленным, но перестал класть весь Totum.
Почему это важно
Классическая картинка отказоустойчивости — три больших сервера, кластер и хранилище «как в учебнике». Здесь третью машину оставили маленькой и честно назвали схему компромиссом. Для внутренней системы, которую надо увести с единственной точки отказа и не раздувать счёт, это полезнее схемы, которую не на чем развернуть. Граница проведена ясно: кворум есть, прикладная запись одна, файлы не спорят друг с другом.
Второй урок шире Totum. Переключение базы не лечит пул, который весь ушёл в чужой HTTP. Пока рабочие процессы кончились, пользователю всё равно, что PostgreSQL жив. Замер до первого байта отделил «медленно соединяемся» от «сосед долго думает», а рост пула локализовал вред, не ускорив чужой API. Это разные починки, и их легко спутать, если смотреть только на жалобу «всё лежит».
На практике
Статья — опыт одной установки, не универсальный чертёж. Асинхронная реплика значит, что при жёстком падении ведущего последние записи можно потерять; автор выбирает автоматическое переключение, а не синхронную запись на оба узла. Прежде чем копировать числа пула, стоит снять свой медленный журнал: 40 процессов помогли им, потому что узким местом был чужой ответ, а не процессор.
Ограждение файлов легко сломать «удобным» двусторонним rsync. Если оба узла на минуту считают себя активными, копии разъедутся. Признак активности должен иметь один источник — у них это ведущий Patroni, — и проверка здоровья должна смотреть на него, а не на то, что процесс просто запущен.
- Заложите свидетеля под кворум
etcd, если не готовы покупать третий полноценный сервер. - Привяжите право писать в приложение к ведущему
PostgreSQL, а не к факту, что веб-процесс жив. - Отдавайте балансировщику
HTTP 200только с активного узла иHTTP 503с пассивного, без ручногоDNS. - Синхронизируйте файлы в одну сторону и переворачивайте направление вместе с ролью.
- Если «всё медленно», снимите след долгих запросов и время до первого байта внешнего вызова до того, как увеличивать пул.
Итог
Схема «два сервера и свидетель» уводит Totum с одной машины, не превращая третий узел в ещё одну копию приложения. Живая запись одна, файлы следуют за ней, люди приходят туда, где проверка здоровья зелёная. Рядом оказался отдельный контур: чужие долгие ответы клали пул, и это лечилось измерением и запасом процессов, а не ещё одним сервером базы.



Комментарии