docs(DR-HA): зафиксировать риск RabbitMQ consumer_timeout + Infisical failover
All checks were successful
Deploy / test (push) Successful in 4m5s
Deploy / deploy (push) Successful in 18m13s

Обнаруженный на практике 26.08 краш-луп (долгий retry в Celery-таске дольше
1800с consumer_timeout → брокер рвёт канал → падение → бесконечный повтор)
стоит знать при добавлении новых долгих retry-циклов. Заодно поправлена
инструкция failover PostgreSQL — POSTGRES_HOST теперь меняется в Infisical,
не в .env на сервере (перезапишется следующим деплоем).
This commit is contained in:
jze9
2026-08-27 16:54:26 +05:00
parent fc40793f4d
commit 95d2903766

View File

@@ -30,7 +30,9 @@ bash scripts/ops/pg_restore_verify.sh # креды из .env
2. **Replica**: `pg_basebackup -h 1.38 -U replicator -D $PGDATA -R` (создаёт
`standby.signal` + `primary_conninfo`), затем старт — догоняет primary по WAL.
3. **Failover**: ручной `pg_ctl promote` на реплике + переключение `POSTGRES_HOST`
в `.env` (или автоматизация через Patroni + etcd — если нужен авто-failover).
в Infisical (окружение `prod` — не в `.env` на сервере напрямую, его перезапишет
следующий деплой, см. ARCHITECTURE.md §10) и передеплой/рестарт сервисов
(или автоматизация через Patroni + etcd — если нужен авто-failover).
4. Проверка лага: `SELECT * FROM pg_stat_replication` на primary.
## 4. HA Redis — реплика + Sentinel (требует новый LXC)
@@ -53,3 +55,19 @@ Redis у нас — кэш/rate-limits/LSH-индекс (префикс `antipla
| Векторный индекс | было | `VECTOR_BACKEND=qdrant` снимает (см. README) ✅ |
| RabbitMQ .82 | да | мониторинг ловит падение ✅; кластер — по потребности |
| app/ES 1.32 | да | воркеры горизонтальны; ES single-node (для BM25 не критично) |
## 6. Известный операционный риск — RabbitMQ `consumer_timeout` vs долгие таски
Обнаружено на практике (2026-08-26): RabbitMQ по умолчанию рвёт канал, если consumer
не сделал ack за 1800с. Любой Celery-таск с retry-логикой (rate-limit backoff у
парсеров, ожидание зависшего внешнего сервиса вроде Ollama), суммарно занимающий
дольше — брокер обрывает соединение раньше, чем таск успевает сдаться и
подтвердиться, весь Celery-процесс падает (`exitCode=1`), Docker
(`restart: unless-stopped`) поднимает его заново, недоставленное сообщение
передоставляется — и цикл повторяется бесконечно, монополизируя весь пул воркера
(было и на `worker-indexer` из-за backoff `scripts/parsers/openalex.py`, и на
`worker-gpu` из-за зависшей Ollama на embedding-gpu). Текущая митигация — держать
retry-бэкоффы заведомо короче 1800с (пример: `MAX_RATE_LIMIT_RETRIES` в
`openalex.py`). Более глубокий фикс — поднять `consumer_timeout` на самом RabbitMQ
(доступа для этого пока не заводили) — актуально при добавлении любых новых
долгих retry-циклов в Celery-тасках.