Django-приложение тормозит под нагрузкой: как вы будете диагностировать и масштабировать его?
Короткий ответ
- Сначала измерить: APM, медленные запросы, профиль эндпоинтов
- Чаще всего виновата БД: N+1, отсутствие индексов
- Кэширование уровнями: per-view, фрагменты, низкоуровневый cache API
- Долгие операции — в Celery/очередь, не в request-response
- Пул соединений и реплики чтения для Postgres
- Горизонтально: stateless-инстансы за балансировщиком, сессии в Redis
- Gunicorn/uvicorn: подобрать тип и число воркеров
Порядок действий: измерить и найти узкое место (обычно БД), снять нагрузку кэшем и очередями, затем масштабировать stateless-инстансы горизонтально.
Как сказать вслух
пример ответаПервый шаг — не оптимизировать, а измерить: подключить APM или хотя бы логирование медленных запросов и понять, где время — в базе, в коде или во внешних вызовах. В Django чаще всего это база: N+1 и недостающие индексы, лечится select_related, prefetch_related и планом запроса. Дальше снимаю нагрузку кэшем в Redis и выношу всё долгое — письма, отчёты, интеграции — в Celery. Когда приложение stateless, остаётся добавить инстансов за балансировщиком и, при необходимости, реплику базы на чтение.
Подробный ответ
Основной ответ
Диагностика: APM (Sentry, New Relic, OpenTelemetry), pg_stat_statements и django-debug-toolbar локализуют проблему — БД, CPU в Python, внешние API или воркеры. Типовые находки и лечение: N+1 → select_related/prefetch_related; тяжёлые запросы → индексы по плану EXPLAIN, денормализация, annotate вместо Python-циклов. Кэширование: Redis как backend, уровни от кэша вью до низкоуровневого cache.get/set с продуманной инвалидацией. Долгие операции (почта, PDF, вызовы внешних API) уходят в Celery с идемпотентными задачами, ретраями и мониторингом очереди. База: PgBouncer для пула соединений, реплики чтения с маршрутизацией через database router, осторожность с лагом репликации. Приложение делается stateless (сессии и медиа — в Redis/S3) и масштабируется горизонтально; число воркеров gunicorn подбирается по профилю нагрузки, статику отдаёт CDN/nginx.
Ключевые моменты
- Измерение до оптимизации. Без профиля легко неделями ускорять код, который даёт 2% времени ответа; метрики показывают настоящее узкое место.
- База — главный подозреваемый. ORM скрывает стоимость запросов; N+1, missing index и выборка лишних колонок — три самые частые причины.
- Очереди для долгих задач. Всё дольше сотен миллисекунд — кандидат в Celery: веб-воркер должен быстро освобождаться.
- Stateless и горизонталь. Состояние в Redis и S3 позволяет добавлять инстансы без привязки клиента к серверу; дальше узким местом становится БД.
Практический контекст
Такой вопрос на senior-интервью проверяет реальный опыт эксплуатации, а не знание слова «микросервисы». Сильный ответ строится как методика: измерил, нашёл, починил самое дешёвое, повторил — и содержит конкретику уровня pg_stat_statements, PgBouncer и инвалидации кэша. Отдельно ценят упоминание рисков: лаг реплики, штормы инвалидации, переполнение очереди Celery.
Частые ошибки
- Сразу предлагают «переписать на микросервисы» вместо диагностики узкого места
- Добавляют кэш без стратегии инвалидации и получают отдачу устаревших данных
- Масштабируют веб-слой, когда узкое место — база данных, и делают только хуже