Как помочь микросервису при высокой нагрузке?
архитектурамасштабируемостьмикросервисыоптимизацияпроизводительность
Что проверяют
Начнёте ли вы с диагностики или сразу с «добавим инстансов». Интервьюеру важно, различаете ли вы узкие места: CPU в самом Python, ожидание базы, медленный соседний сервис. Следом часто спрашивают, что станет с базой, если сервис масштабировать в пять раз.
Как отвечать
Каркас: измерить, снять острую нагрузку, устранить причину.
- измерить: метрики RED (частота запросов, доля ошибок, перцентили задержки p95 и p99) в Prometheus и Grafana, трассировка через OpenTelemetry, профиль живого процесса без перезапуска через
py-spy; - защитить сервис: таймауты на все исходящие вызовы, ограничение частоты запросов, circuit breaker к медленным зависимостям, сброс лишней нагрузки ответом
429или503вместо очереди, которая растёт до падения; - масштабировать: горизонтально, подами и HPA в Kubernetes. Сервис должен быть без состояния, а соединения с базой идут через пул и PgBouncer, иначе новые поды упрутся в
max_connections; - кэшировать: Redis для горячих данных по схеме cache-aside, с TTL и защитой от одновременного промаха, когда сотня запросов разом идёт в базу за одним ключом;
- вынести тяжёлое в фон: долгие задачи в очередь (Celery, RabbitMQ, Kafka), клиенту сразу
202и идентификатор задачи; - учесть особенности Python: блокирующий вызов вроде
requests.getили синхронного драйвера базы внутриasync defв FastAPI останавливает весь event loop. CPU-bound работу из-за GIL параллелят процессами: несколько воркеров Gunicorn или Uvicorn,ProcessPoolExecutor, отдельный сервис.httpx.AsyncClientсоздают один на процесс, а не на запрос; - база: индексы, устранение N+1 в ORM через
selectinload, реплики для чтения.
Где спотыкаются
Добавляют поды и кладут базу: каждый держит свой пул соединений, и лимит кончается раньше, чем CPU.
Настраивают повторы без экспоненциальной задержки и джиттера. В момент деградации это умножает нагрузку и добивает сервис.
Пишут async def и считают сервис асинхронным, хотя внутри синхронный драйвер. Один медленный запрос тормозит все остальные в этом процессе.