Как масштабировать систему для высокой нагрузки
Что проверяют
Умеете ли вы идти от цифр к решению, а не перечислять модные слова. Хороший ответ начинается с вопросов о нагрузке, а следом интервьюер обычно спрашивает: «Что у вас упадёт первым, если трафик вырастет в десять раз?»
Как отвечать
Сначала уточните требования: RPS в пике, соотношение чтения и записи, целевая задержка по p99, объём данных и скорость его роста. Без этого любая схема это гадание. Потом найдите узкое место замером: нагрузочный тест в Gatling, JMeter или k6, метрики через Micrometer в Prometheus и Grafana, трассировка OpenTelemetry, профилирование JFR или async-profiler.
Дальше по слоям:
- приложение: сервис должен быть stateless. Сессии в Redis или в токене, тогда экземпляры добавляются за балансировщиком (Nginx, HAProxy, Ingress в Kubernetes с HPA). Для I/O-нагрузки на Java 21 и новее помогают виртуальные потоки;
- кэш: локальный Caffeine для горячих справочников, Redis для общего, CDN для статики. Сразу назовите стратегию инвалидации и защиту от одновременного промаха по одному ключу;
- база: обычно узкое место именно она. Индексы и планы запросов, пул соединений HikariCP, реплики на чтение с учётом задержки репликации, партиционирование, и только потом шардирование;
- асинхронность: тяжёлое и некритичное уводите в очередь (Kafka, RabbitMQ), так пики сглаживаются;
- устойчивость: таймауты на каждый внешний вызов, circuit breaker и rate limiter из Resilience4j, чтобы падение одной зависимости не утянуло всю систему.
Упомяните вертикальное масштабирование как честный первый шаг: оно дёшево в разработке и часто его хватает.
Где спотыкаются
Сразу предлагают микросервисы и шардирование, не спросив про нагрузку. Интервьюер слышит, что вы построите сложное там, где хватило бы индекса.
Масштабируют приложение и забывают про базу. Двадцать экземпляров с пулом по 20 соединений это 400 соединений к PostgreSQL, где max_connections по умолчанию 100.
Оставляют состояние внутри экземпляра: сессии в памяти, локальный кэш без инвалидации, задачи с @Scheduled, которые после масштабирования запускаются на каждой копии. Для последних нужна распределённая блокировка, например ShedLock.