Какие инфраструктурные компоненты можно проверить или добавить для оптимизации приложения?
Что проверяют
Понимаете ли вы, что оптимизация начинается с измерения, а не с «добавим Redis». Хотят услышать, какие звенья стоят между пользователем и кодом на Python и где в них обычно теряется время. Следом спрашивают: «У вас вырос p95, с чего начнёте?»
Как отвечать
Сначала скажите, как найдёте узкое место: метрики в Prometheus и Grafana, трассировка через OpenTelemetry, медленные транзакции в Sentry, профилирование живого процесса через py-spy без перезапуска. Потом пройдите по цепочке:
- сервер приложения: Gunicorn с подходящим типом воркеров. Синхронные воркеры простаивают на медленном вводе-выводе, для асинхронного кода нужен Uvicorn. Число процессов подбирают под ядра и нагрузку, документация Gunicorn предлагает начинать с
2 × ядра + 1; - reverse proxy: Nginx отдаёт статику, сжимает ответы и буферизует медленных клиентов, чтобы они не держали воркер;
- база:
EXPLAIN ANALYZE, индексы, борьба с N+1 черезselect_relatedиprefetch_relatedв Django, реплики для чтения; - пул соединений: PgBouncer перед PostgreSQL, особенно когда процессов много и каждый держит свой пул;
- кэш: Redis для тяжёлых вычислений и частых чтений, со сроком жизни и понятным правилом инвалидации;
- фоновые задачи: Celery, RQ или arq выносят письма, отчёты и вызовы внешних API из запроса;
- CDN и HTTP-кэширование: статика и публичные страницы не должны доходить до Python вовсе.
Отдельно упомяните GIL: для задач, упирающихся в процессор, помогают процессы или вынос в отдельный сервис, а не потоки.
Где спотыкаются
Добавляют воркеров и реплики приложения, когда упираются в базу. Каждый новый процесс открывает свои соединения, и сервис падает уже на max_connections.
Предлагают кэш без стратегии инвалидации. Пользователи начинают видеть устаревшие данные, и оптимизация превращается в баг.
Не называют метрику успеха. Ответ «станет быстрее» слабее, чем «снизим p95 ответа с 900 до 300 мс и подтвердим это нагрузочным тестом в Locust».