HighLoad-инфраструктура для портала Judo Battle
Next.js SSR + Strapi под 15 000 одновременных соединений: трёхузловая архитектура, Varnish-кэш, PM2-кластер и автономный CI/CD.
О проекте
Спортивный портал с тяжёлым фронтендом: Next.js с серверным рендерингом, 24 JS-чанка, динамический контент и CMS Strapi. Задача — выдержать 15 000 одновременных подключений при турнирных пиках без деградации для пользователей. Мы разделили монолит на изолированные узлы, выстроили умное кэширование и подтвердили KPI стресс-тестом.
От монолита к изолированной архитектуре
Nginx, Frontend, Backend и БД на одном сервере. Next.js с SSR обрабатывал каждый запрос — при 15 000 соединений CPU уходил в 100%, Strapi работал в одном потоке, сессии админов рвались, SSH был открыт для брутфорса.
Три независимых узла в закрытой сети 172.16.0.0/28: Proxy (Nginx + Varnish, 12 ГБ кэша), Frontend (PM2 cluster, 8 инстансов Next.js), Backend (4 инстанса Strapi). Внешний мир видит только 443 порт. Деплой, SSL и ротация логов — на автопилоте.
Архитектура решения

Proxy-сервер
Nginx + Varnish с кастомным VCL. Статика кэшируется на 1 год, SEO-страницы — 10 минут с учётом языковых cookie. RSC, prefetch и API обходят кэш. Grace mode отдаёт устаревшую страницу до 1 часа при падении бэкенда.
Frontend (Next.js)
PM2 Cluster Mode на все ядра CPU (8 инстансов). Автоматический CI/CD по cron: бэкап, git pull, build, безопасный рестарт через pm2safe. max_memory_restart: 1G, ротация логов при 5 МБ.
Backend (Strapi)
Кластер из 4 инстансов на портах 1337–1340 (STRAPI_WEB_CONCURRENCY: 2). Админка зафиксирована на 1337 для стабильных сессий, публичный API балансируется. systemd resurrection при перезагрузке сервера.
Ключевые решения
Умное кэширование Varnish
24 JS-чанка и статика — immutable на год. SEO-контент (новости, участники, клубы) — 10 минут. Динамика Next.js и админка идут мимо кэша, чтобы не ломать интерактив и авторизацию.
Автономный CI/CD
Скрипт каждые 5 минут опрашивает GitHub. Новый коммит → tar.gz бэкап → npm install → build → безопасный рестарт PM2. Обновления без простоя для пользователей.
PM2-кластеризация
8 инстансов Next.js + 4 Strapi с авто-рестартом при утечках памяти (1G / 2G). Падение одной ноды не останавливает сервис — остальные мгновенно подхватывают трафик.
Закрытый контур
SSH (порт 22) закрыт по умолчанию на всех серверах. Доступ только через консоль провайдера или временные скрипты. Внутренняя сеть изолирована — снаружи виден только Proxy.
Автообновление SSL
Certbot через systemd-таймер на Proxy (каждое воскресенье). На Backend — bash-скрипт с корректной остановкой Nginx в standalone-режиме. RandomizedDelaySec против пиков на Let's Encrypt.
Grace mode и самолечение
При падении или задержке бэкенда Varnish отдаёт кэшированную страницу ещё час — пользователи не видят 502/504. PM2 и systemd автоматически восстанавливают процессы.
Результаты стресс-теста
Стресс-тест Apache Bench: 15 000 одновременных соединений, 100 000 запросов на «тяжёлый» SSR-сайт. KPI проекта достигнут с большим запасом.
15 000+
одновременных соединений без отказа
100 000
запросов в одном прогоне
≤ 25%
CPU на Proxy-сервере в пике
1–3%
CPU Frontend/Backend (кэш работает)
≤ 6 ГБ
RAM на каждой машине в штатном режиме
0
502/504 для пользователей (grace mode)
Узкое горлышко: Предел достигнут не софтом, а физическим каналом хостинга (~1 Гбит/с). При полной загрузке канала начались TLS-ошибки и таймауты — CPU и RAM оставались с большим запасом.