独立站负载均衡:多实例部署、健康检查、会话保持与故障转移
1. Когда балансировка нагрузки нужна, а когда это избыточно
Балансировка нагрузки — не то, с чего стоит начинать. При трафике до 5000 визитов в день одного VPS 2 ядра / 4 ГБ с Nginx+PHP+MySQL вполне достаточно, а покупка LB за несколько сотен рублей лишь добавит сложности. Реальных сигналов к переходу на несколько экземпляров три: длительная загрузка CPU выше 60% на одной машине, простой при каждом релизе, потерянные заявки из-за отказа одной машины. Совпали два из них — тогда внедряйте LB.
独立站的典型升级路径是:单VPS跑compose(日访1万以内)→ 拆MySQL到独立机器(日访3万)→ 应用跑2台+云LB(日访5万)→ 应用3到5台+自动扩缩容(日访20万以上)。不要跳步。CDN在LB之前先扛住静态流量,源站压力能降一半,见 Глобальное ускорение CDN.
| Этап | Форма развёртывания | Число экземпляров приложения | Ориентир по трафику в день | Прирост месячных затрат |
|---|---|---|---|---|
| Начальный этап | Один VPS + compose | 1 | <10 000 | 0 |
| Этап роста | 1 экземпляр приложения + отдельная БД | 1 | 10 000–50 000 | +150 ₽ |
| Этап стабильности | 2 экземпляра приложения + облачный LB | 2 | 50 000–200 000 | +около 100 ₽ за LB |
| Пиковый период | 3–5 экземпляров приложения + автомасштабирование | 3–5 | >200 000 | +оплата по часам |
二、L4还是L7:独立站选哪一层
负载均衡分四层(L4,按TCP/IP转发)和七层(L7,按HTTP路径转发)。L4性能高、配置简单,但只能按端口转发;L7能根据域名、路径、Header做路由,还能做灰度和HTTPS卸载。独立站选L7,因为你需要按路径分流:静态文件走CDN,API走应用,后台走另一组实例。
Выбор LB у облачных провайдеров: в AWS это ALB (Application Load Balancer), в Alibaba Cloud — SLB или ALB, в Tencent Cloud — CLB. Функционально они пересекаются, цены начинаются от 100–200 юаней в месяц. Простой критерий: если задача — просто «гонять трафик между двумя машинами по кругу», берите самый дешёвый LB четвёртого уровня; если нужно маршрутизировать по путям, делать канареечные релизы или распределять по доменам — берите LB седьмого уровня.
| Параметр сравнения | Балансировка L4 TCP | Балансировка L7 HTTP |
|---|---|---|
| По чему распределяет | IP + порт | Домен / путь / Header / Cookie |
| Производительность | Очень высокая, микросекунды | Чуть ниже, миллисекунды |
| Разгрузка HTTPS | Не поддерживается | Поддерживается, сертификат на LB |
| Канареечный релиз | Не поддерживается по доле трафика | Поддерживается переключение по весам |
| 独立站适用 | Простое чередование двух машин | Маршрутизация по путям, канареечные релизы |
| Ориентир по цене в месяц | Около 80–120 юаней | Около 150–250 юаней |
III. Проверки здоровья: как настроить, чтобы не убить живые узлы
健康检查是LB的核心。配太松,挂掉的机器还在接流量;配太紧,应用刚启动慢一点就被误摘,导致雪崩。独立站的标准配置是:检查路径/health(只返回200,不查数据库,避免把DB慢传染到LB)、间隔10秒、连续3次失败才摘除、连续2次成功恢复。
Эндпоинт /health должен быть лёгким. Частая ошибка — заставить его проверять соединение с MySQL: при малейшем сбое базы все экземпляры приложения исключаются из LB, и весь сайт отдаёт 503. Правильно: /health возвращает только статус живости процесса, а здоровье базы проверяется отдельным эндпоинтом /health/db, который только мониторится и не влияет на решение об исключении. Пороги мониторинга и алертов см. в Мониторинг сайта и оповещения.
| Параметр | Рекомендуемое значение | Пояснение | Частая ошибка |
|---|---|---|---|
| Путь проверки | GET /health | Не трогает DB, возвращает только 200 | Запрос к DB приводит к массовому исключению |
| Интервал проверки | 10 секунд | Баланс между чувствительностью и ложными срабатываниями | 1 секунда — слишком агрессивно |
| Таймаут | 5 секунд | Превышение считается одной неудачей | 1 секунда — слишком мало |
| Порог нездоровья | 3 неудачи подряд | Узел исключается | Исключение после 1 неудачи |
| Здоровый порог | 2 успеха подряд | Возврат в пул | Восстановление после 1 успеха |
| Код ответа | 200 считается здоровым | Другие коды считаются неудачей | 503 считается здоровым |
IV. Привязка сессий: включайте только при крайней необходимости
Многие, впервые запуская несколько экземпляров, сразу думают: «Пользователь залогинился на машине A, а следующий запрос попадёт на B — и его выкинет», и включают привязку сессий. Это экономит время сейчас, но создаёт долг на будущее. Проблема привязки в том, что при падении машины A все привязанные к ней пользователи разом теряют сессию, и смысл отказоустойчивости наполовину теряется.
Правильный подход — вынести сессии из памяти приложения. В PHP храните сессии в Redis, в Node используйте stateless-токены JWT, всё состояние входа — в одном общем хранилище. Тогда любой экземпляр приложения может обработать запрос любого пользователя, и падение любой машины не влияет на онлайн-пользователей. Сохранение сессий включайте только в двух случаях: старая система, которую нельзя переделать, или сторонний плагин, жёстко зависящий от локальных сессий.
| Схема сессий | Расширяемость | Влияние сбоя | Стоимость миграции | Рекомендация |
|---|---|---|---|---|
| Session в локальных файлах | Плохо, обязательна sticky-привязка | Падение одной машины = пользователи отключены | Низкая | Не рекомендуется |
| Централизованная session в Redis | Хорошо | Незаметное переключение | Средняя, достаточно поменять конфигурацию | Рекомендуется |
| JWT без состояния | Лучше всего | Незаметное переключение | Высокая, придётся переделать аутентификацию | Рекомендуется для новых проектов |
| Привязка через cookie на LB | Плохо | Упадёт машина — упадёт соединение | Низкая, достаточно включить | Только как временное решение |
5. Отказоустойчивость: как проверить, что LB действительно переключит трафик
Настроить LB — ещё не значит включить отказоустойчивость. Многие команды после запуска ни разу не убивали сервер вручную и узнают о проблеме только когда он падает по-настоящему: то health check на LB не настроен, то security group не пропускает трафик. Перед запуском обязательно проведите учения: в продакшене (или на стейдже) вручную остановите приложение A и посмотрите, переведёт ли LB трафик на B в течение 30 секунд и заметят ли это пользователи.
Ещё одна частая ошибка — два экземпляра приложения на одной физической машине или в одной стойке: отключение питания стойки убьёт оба сразу. Размещайте их минимум в двух зонах доступности (AZ) или хотя бы на двух разных хостах. Полная методика резервного копирования и восстановления описана в Бэкап и восстановление сайта.
Пример из практики: у одной B2B-компании WordPress крутился на одном VPS. Ночью на хосте отключили питание на время обслуживания, сайт лежал 4 часа, за это время потеряли 3 запроса от европейских клиентов. После этого добавили второй экземпляр приложения за облачным LB, перенесли сессии в Redis и разнесли по зонам доступности. В следующее окно обслуживания экземпляр B автоматически принял весь трафик, и ни клиенты, ни отдел продаж ничего не заметили. Лишние 300 рублей в месяц за экземпляр — ничто по сравнению с ценой потерянного запроса.
| Сценарий учения | Действия | Ожидаемый результат | Что делать, если не прошли |
|---|---|---|---|
| Убить процесс приложения | systemctl stop app | LB выводит из ротации за 30 секунд, трафик уходит на B | Проверить путь health check |
| Отрезать сеть приложения | Заблокировать порт через iptables | Вывод из ротации за 10 секунд | Проверить, что security group пропускает подсеть LB |
| Перезагрузка машины | reboot | После старта автоматически возвращается в ротацию | Проверить скрипт запуска и health |
| Сбой базы данных | Внедрить медленный запрос | Приложение не выводится из ротации по ошибке | health не должен обращаться к БД |
| Весь трафик на B | Перевести вес 100 на B | B держит нагрузку 5 минут в одиночку | Проверить, выдержит ли B нагрузку |
FAQ: частые вопросы
При какой посещаемости нужен балансировщик?
Нужно ли включать привязку сессий?
Почему health check не должен обращаться к базе данных?
Можно ли разместить два экземпляра на одной физической машине?
Сколько стоит балансировщик у облачного провайдера в месяц?
Как проверить, что отказоустойчивость действительно работает?
В заключение
负载均衡对独立站的价值,一半是扛流量,另一半是扛故障。前者很多人能算清,后者常被忽略——多一台应用实例的成本,换来的是”一台机器挂了用户无感”,这在B2B询盘场景里就是钱。
Три шага внедрения: первый — сделать приложение без состояния, вынести сессии в Redis; второй — поднять второй экземпляр, подключить его к облачному балансировщику и настроить проверку здоровья; третий — провести учения с остановкой процесса и убедиться, что трафик переключается в течение 30 секунд. После этих трёх шагов архитектура с несколькими экземплярами действительно становится работоспособной. Сопутствующий мониторинг и оповещения см.Мониторинг сайта и оповещения, продвинутая настройка автомасштабирования — см.Автомасштабирование.
Фраза, которую стоит запомнить: смысл балансировки нагрузки не в распределении трафика, а в том, чтобы при падении любой машины пользователи и заявки этого не заметили.
