
Устойчивость к сбоям в Python: что ломается первым
Retry без джиттера превращает один таймаут БД в лавину запросов. Разбираем, как повторы, таймауты и circuit breaker ведут себя под нагрузкой и где именно рвётся.

Retry без джиттера превращает один таймаут БД в лавину запросов. Разбираем, как повторы, таймауты и circuit breaker ведут себя под нагрузкой и где именно рвётся.

Кеш ускоряет чтение, но инвалидация растекается по всему коду и превращает простой lru_cache в источник рассинхрона. Разбираем, где ломается инвалидация под нагрузкой и что она делает с архитектурой сервиса.

Redis SETNX без TTL повесил очередь задач на сутки, а lock через истёкший ключ дал двум воркерам обработать один платёж. Разбираем, где ломаются распределённые блокировки в Python и как их чинить.

Дубли платежей и повторные списания рождаются не в коде обработчика, а в том, как вы храните ключи идемпотентности. Разбираем механику блокировок, замеры и места, где схема ломается.

Профайлер показал, что 80% времени уходит в один цикл. Разбираем, когда его спасёт Cython, а когда сначала нужно переписать сам алгоритм и структуры данных.

Воркер на SIGTERM обрывал задачи посреди выполнения, а данные оставались в неконсистентном состоянии. Разбираем, почему стандартный signal.signal не спас и как устроена остановка процесса под управлением orchestrator.

Обработчик сигнала, который лезет в лог или дёргает asyncio-loop, — частая причина зависшего процесса при деплое. Разбираем, на что смотреть в ревью кода с signal.

Очередь задач копится быстрее, чем воркеры её разбирают, задержка растёт до минут, а память течёт. Разбираем, где Celery и RQ ломаются под нагрузкой и что мерить, пока не поздно.

Тесты корутин зелёные, но продакшн падает: забытый await молча возвращает объект корутины, event loop течёт между тестами, а mock не дожидается задач. Разбираем, где именно ломается pytest-asyncio и как это ловить.

Почему asyncio.sleep не блокирует поток, откуда берётся очередь готовых колбэков и что делает event loop между итерациями — разбор внутренностей планировщика в CPython 3.12.

Пул на 20 соединений выглядит безобидно, пока сервис не начнёт отдавать 500 на пике. Разбираем, как размер и время жизни пула влияют на латентность, память базы и поведение при отказе.

Асинхронный генератор оставляет открытыми соединения, теряет aclose() при досрочном выходе и падает при финализации из чужого event loop. Разбираем, где именно ломается async for.