
Привет, меня зовут Анатолий, я ведущий разработчик в ITFB Group. У нас высоконагруженный сервис торговых операций. И раз в неделю, как по расписанию, раздавался панический звонок: «Опять пропали запросы!». Мы неслись смотреть логи — а там... ничего. Ни ошибок, ни падений. Никаких пятисотых, только стабильные двухсотые. Стенды dev и prod молчали, как рыбы. Запросы загадочным образом появлялись через некоторое время, и всё работало, пока история не повторялась снова. Это был не баг, это был призрак. Призрак в сети.
Сегодня я расскажу, как мы его поймали.

Контекст: что за система и в чем боль?
Сервис торговых операций (наш герой): Написан на Java, само собой с использованием, Spring Boot. Он отвечает за запуск и управление аукционами.
База данных: PostgreSQL — хранит все состояния и ставки.
Инфраструктура: всё крутится в Kubernetes.
Проблема: Раз в несколько дней несколько операций «пропадали» — их таймеры останавливались, а потом, спустя минуту-другую вдруг продолжали работу, будто ничего и не случилось.

Симптомы: призрак в машине
Тишина в логах. Абсолютная. Ни ошибок 5xx, ни таймаутов в трейсах. Сервисы были живы и здоровы по всем метрикам Kubernetes.
На стендах всё чисто. На dev и staging воспроизвести проблему не получалось. Она проявлялась только в prod под реальной нагрузкой.
Запросы доходили, но с диким опозданием. Это был главный ключ. Мы не теряли их насовсем, они просто «застревали» в пути и прибывали с задержкой в десятки секунд, сбивая все тайминги.
Расследование: от слепого поиска к точечной гипотезе

Шаг 1: Отчаяние и первый прорыв
Мы перерыли всё: логи приложения, логи Postgres, метрики БД (не было ли дедлоков?). Безрезультатно. Стандартный мониторинг был слеп к этой проблеме.
Решение, которое всё изменило
Я написал и запустил простой diagnostic pod в том же кластере. Это был простейший скрипт на Bash, который в бесконечном цикле curl'ил healthcheck-эндпоинт нашего Java-сервиса раз в секунду и логировал время ответа.
Результат оказался ошеломляющим: Мы поймали аномалию! Раз в 2-3 дня наш скрипт фиксировал потерю 2-3 запросов подряд. После этого пауза в 20-40 секунд – и пропавшие запросы вдруг «возвращались к жизни», получали ответ HTTP 200 OK, и всё шло дальше, как ни в чем не бывало.
Гипотеза №1 (Java / JVM): возможно сборщик мусора (Garbage Collector) уходит в длительную паузу? Мы подключили GC-логирование и смотрели в Grafana. Результат: паузы GC были в пределах нормы (200-300 мс) и не совпадали по времени с 4-5-секундными простоями.
Гипотеза №2 (Kubernetes): Проблема с самими подами? Мы посмотрели метрики: пересоздания подов, нехватка ресурсов – ничего не совпадало по времени с нашими инцидентами.
Гипотеза №3 (сеть): А что если сеть ненадолго «зависает»? Пакеты не теряются, а где-то буферизуются (например, на балансировщике нагрузки) и потом отпускаются дальше? Это объясняло бы всё: отсутствие ошибок (TCP-сессия не рвется), задержку и случайность происходящего.
Инструменты и доказательства
Мы начали целенаправленную охоту на сеть.

Углубленный мониторинг: Мы настроили Blackbox Exporter для Prometheus, который начал постоянно опрашивать наш эндпоинт не раз в секунду, а раз в 100 мс, чтобы точнее поймать момент проседания.
Анализ трафика: В момент, предшествующий очередному инциденту, мы запустили на поде с Java-сервисом команду:
bash tcpdump -i any -w /tmp/capture.pcap port 8080 #
Анализ дампа: Открыв полученный файл capture.pcap в Wireshark, мы увидели четкую картину:
- Клиент исправно отправляет SYN-пакеты для установления соединения.
- В течение 4-5 секунд на них нет ответа (SYN-ACK).
- Через 4-5 секунд соединение волшебным образом устанавливается, и все «замерзшие» запросы разом уходят и получают ответ.
Это было 100% доказательство: проблема была не в приложении, а в сетевом оборудовании между подами в Kubernetes, которое на короткое время переставало маршрутизировать пакеты.
Решение и выводы
Решение: Мы передали полученные данные (логи скрипта, .pcap дамп) команде инфраструктуры. Они, в свою очередь, обнаружили проблему на балансировщике нагрузки (L4). В его конфигурации или прошивке был баг (нам они постеснялись сказать), который при определенной нагрузке приводил к кратковременному «зависанию» сессии. Он не разрывал соединение, а буферизовал трафик, пытаясь его восстановить, и через некоторое время успешно это делал.
Что сделали: Сетевые инженеры обновили конфигурацию проблемного оборудования. Проблема исчезла.
Главные уроки
Сначала среда, потом код. Если логи молчат, а проблема есть – ищите на уровень ниже (K8s, сеть, ОС).
Создавайте активную нагрузку для диагностики. Пассивного мониторинга часто недостаточно. Простейший скрипт, который «спамит» запросы, может оказаться ценнее сложной системы APM.
tcpdump + Wireshark – мастхэв для любого разработчика. Умение сделать дамп трафика и хотя бы базово его прочитать – критически важный навык для работы в распределенных системах.
Гипотезы должны быть проверяемыми. Мы не просто говорили «сеть виновата», мы предложили механизм проверки и нашли прямое доказательство. Наш «призрак» оказался сетевым багом. И теперь мы знаем: если что-то работает с перебоями, но не падает – первым делом смотрим на сеть.