Troubleshooting
Runbook’и для типовых инцидентов: «что вижу → причина → как починить». Страницы построены так, чтобы на pager’е или на встрече инцидента открыть одну и пройти сверху вниз по секциям.
Правило: сначала сюда, потом в чат
Перед тем, как писать «у меня упало» в чат — прочитай соответствующую страницу. В 80% случаев ответ уже есть здесь, и ты разберёшься быстрее, чем дождёшься ответа. Если runbook не покрывает твой симптом — напиши в чат и заведи PR на этот handbook: добавь раздел со своим случаем.
Страницы
kafka-consumer-stuck— consumer не потребляет сообщения, лаг растёт. Причины: долгий handler, rebalance-loop, panic, DLQ, Redis недоступен.kafka-rebalancing— rebalance-loop: как отличить от stuck, медленный handler, GC pauses, static membership, cooperative sticky.migration-fails—make migrate-up/ golang-migrate CLI падает.dirty state, advisory lock, deadlock, SSL mismatch, несинхронизированная схема.db-slow-query— медленный SQL: локализация через Tempo /pg_stat_statements,EXPLAIN ANALYZE, индексы, висячие транзакции, bloat.memory-leak— heap/goroutine leak: pprof, diff между snapshot’ами, типовые причины (кэш, незакрытый body, channel без sender,time.Tick).redis-unavailable— Redis лежит или тормозит: dial/timeout/pool exhausted/OOM/READONLY, команды диагностики, порядок действий.test-hangs— тест висит или не завершается. testcontainers Docker, goroutine leak,time.Sleepвместоeventually,selectбезctx.Done().saga-failed-compensation— сага застряла вfailed_compensationпосле исчерпания retry- бюджета компенсации: как диагностировать, закрыть вручную или replay’ить компенсацию.infrastructure-issues— DNS stale, TLS expired, clock skew, disk full, FD exhaustion, partial network partition. Когда симптом выглядит как баг сервиса, но root cause в инфре.failure-modes-matrix— когда симптомов несколько одновременно: матрица корреляций, типовые multi-failure сценарии (Redis + Kafka, replica lag- cache stale, alert storm), red herrings и принципы первого часа инцидента.
Diagnostic toolkit
Команды, которые нужны в любом инциденте независимо от типа —
вынесены в один раздел, чтобы не дублировать по runbook’ам.
Подробные версии — в infrastructure-issues#diagnostic-toolkit;
здесь — самое частое.
Pod / node state
kubectl get pods -n backend -o wide
kubectl describe pod <pod> -n backend | tail -40
kubectl logs <pod> -n backend --previous --tail 200
kubectl top nodes
kubectl top pods -n backendGrafana → Tempo → Loki
Стандартный flow debugging’а production-инцидента — описан в
../conventions/observability#debugging-production-issue.
Кратко:
- Grafana dashboard сервиса → найти аномалию в
http_request_duration_seconds/http_requests_total{status=~"5.."}. - Click-through в Tempo по одному trace’у из аномального окна.
- Tempo → Loki по
trace_id/correlation_id— логи того же запроса.
Postgres
-- активные запросы, кто висит
SELECT pid, usename, state, wait_event_type, wait_event,
now() - query_start AS runtime, query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY runtime DESC NULLS LAST
LIMIT 20;
-- кто кого блокирует
SELECT blocked.pid AS blocked_pid, blocking.pid AS blocking_pid,
blocked.query AS blocked_query, blocking.query AS blocking_query
FROM pg_stat_activity blocked
JOIN pg_stat_activity blocking
ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));
-- текущий размер outbox
SELECT count(*) FILTER (WHERE offset_acked IS NULL) AS unacked,
count(*) FILTER (WHERE offset_acked IS NOT NULL) AS acked
FROM outbox;Kafka
# consumer group lag
kafka-consumer-groups.sh --bootstrap-server "$KAFKA_BROKERS" \
--describe --group <consumer-group>
# список топиков
kafka-topics.sh --bootstrap-server "$KAFKA_BROKERS" --list
# конфигурация топика
kafka-topics.sh --bootstrap-server "$KAFKA_BROKERS" --describe --topic <topic>
# прочитать хвост топика
kafka-console-consumer.sh --bootstrap-server "$KAFKA_BROKERS" \
--topic <topic> --max-messages 5 --from-beginningRedis
redis-cli -h <host> -p <port> INFO clients
redis-cli -h <host> -p <port> INFO memory
redis-cli -h <host> -p <port> SLOWLOG GET 10
redis-cli -h <host> -p <port> CLIENT LIST TYPE normal | headpprof (жив процесс)
# port-forward если нужно
kubectl port-forward -n backend <pod> 6060:6060
# snapshot heap
curl -o heap.pprof http://localhost:6060/debug/pprof/heap
go tool pprof -http=:8080 heap.pprof
# goroutine count + stacks
curl http://localhost:6060/debug/pprof/goroutine?debug=2 | head -200Детали профилирования — ../how-to/profile-service.
Связанные страницы
- Не consumer, а outbox на publisher-стороне лагает →
../how-to/debug-outbox-lag. - Общий debugging flow production-инцидента (три сигнала, Grafana
→ Tempo → Loki) →
../conventions/observability.