Мониторинг интеграций и очередей: метрики и алерты без шума
Практический разбор: мониторинг интеграций и очередей в MQ и Kafka - метрики задержек, дублей, DLQ, и как выстроить сквозной контроль без шума.

Какая проблема на самом деле: где теряются сообщения и время
Бизнес почти всегда видит не «ошибки брокера», а симптомы: заказ не дошел, статус обновился через 30 минут, платеж прошел дважды, уведомление ушло не тому. Для команд это часто звучит как «Kafka/MQ сломалась», но время обычно теряется на стыках: продюсер не отправил, консьюмер не обработал, ретраи зациклили поток, а «мертвые» сообщения ушли в DLQ и лежат там незаметно.
Так происходит потому, что большинство графиков показывают то, что легко снять (CPU, память, общий throughput), но не то, что помогает во время инцидента. Когда пользователи жалуются на задержку, график «сообщений в секунду» может быть идеальным. А когда случился дубль, метрики брокера могут не заметить проблему: она родилась в логике ретраев, дедупликации или внутри обработчика.
Наблюдаемость отличается от набора графиков тем, что отвечает на четыре вопроса: что сломалось, где, с какого момента и сколько реальных операций затронуто. Для этого нужен сквозной контроль по всей цепочке «продюсер - брокер - консьюмер - внешняя система», а не только «очередь жива».
Рабочий мониторинг - это не «у нас 50 дашбордов». Это несколько понятных сигналов, которые быстро приводят к причине: задержка по ключевым потокам, доля ошибок и ретраев, дубли и нарушения идемпотентности, а также DLQ как управляемая очередь, а не кладбище.
Если эти сигналы привязаны к бизнес-операциям (например, «создание заявки», «проведение платежа», «обновление статуса»), поиск причины обычно занимает минуты, а не часы.
Короткая модель интеграции: чтобы метрики говорили об одном
Чтобы мониторинг не превращался в набор разрозненных графиков, полезно договориться об одной простой модели. В любой очереди или топике есть три роли: продюсер (кто отправляет), брокер (где хранится и раздается), консьюмер (кто читает и делает действие). Задержка может появиться на каждом шаге, и метрики должны указывать, где именно.
Практичный способ думать о пути сообщения:
- Система A создала событие и попыталась отправить.
- Брокер принял и сохранил.
- Консьюмер прочитал и обработал.
- Система B получила эффект (запись в БД, изменение статуса, отправка письма).
Подтверждение (ack) простыми словами: консьюмер говорит брокеру «я обработал, можно считать доставленным». Если подтверждения нет, включаются ретраи: повторные попытки доставить или обработать.
Идемпотентность означает: «если это же сообщение придет второй раз, результат не испортится». Например, обновление статуса по ключу вместо создания второй записи.
Дубли обычно возникают в двух местах: при повторной отправке (продюсер не уверен, что брокер принял) и при повторной обработке (консьюмер упал после действия, но до ack). Поэтому одни метрики должны отвечать за доставку, а другие - за эффект.
DLQ (dead letter queue) нужна не как свалка, а как карантин: туда попадают сообщения, которые не проходят обработку после разумного числа попыток. В DLQ должны быть понятные причины, счетчик попыток и владелец, который разберет ситуацию и вернет сообщение в работу или исправит данные.
Сквозной контроль начинается с одного поля корреляции (например, orderId или requestId). Оно связывает событие в системе A с результатом в системе B и позволяет измерять полный путь, а не только «сообщение лежит в брокере».
Метрики задержек: что показывает реальную боль пользователей
Задержка в очереди сама по себе редко волнует бизнес. Болит другое: «заявка не дошла», «платеж завис», «врач не видит результат», «отчет обновился через час». Поэтому важно измерять не только «что в очереди», а путь сообщения до итогового действия.
End-to-end latency: измеряем от события до результата
Самая полезная метрика - сквозная задержка: время от момента, когда источник создал событие, до момента, когда целевая система подтвердила результат (запись в БД, созданный документ, отправленное уведомление). На практике это делается через timestamp в сообщении и фиксацию «финиша» в логике потребителя (или отдельным событием-ответом).
Простой пример: сервис выставил счет в 10:00:00, а бухгалтерия увидела его в системе в 10:07:30. Сквозная задержка - 7 минут 30 секунд, даже если брокер «здоров».
Consumer lag: полезно, но не равно задержке для пользователя
Consumer lag показывает, насколько потребитель отстал от конца партиции. Это индикатор давления, но он не отвечает на вопрос «сколько ждет конкретное сообщение». Lag может быть большим во время плановой догрузки, и пользователи этого не заметят. И наоборот: lag может быть небольшим, но одно «старое» сообщение застряло из-за ошибки обработки.
Чтобы ловить именно ожидание, часто помогает age of oldest message (возраст самого старого необработанного сообщения). Он проще для порогов: если «самому старому» уже 10 минут, значит кто-то точно ждет.
Среднюю задержку лучше не использовать как главный сигнал. Смотрите перцентили (p95, p99): проблемы обычно прячутся в хвосте, когда 1-5% сообщений «тянут» процесс и создают очередь жалоб.
И считайте задержки отдельно по типам событий и ключевым очередям. У «авторизации» и «ночной выгрузки» разные ожидания, и общий график легко маскирует реальную боль.
Метрики надежности: ошибки, ретраи, дубли и DLQ без иллюзий
Надежность в очередях и интеграциях чаще ломается не «в брокере», а в обработчиках: в коде, зависимостях, данных. Поэтому стоит держать под контролем метрики, которые отвечают на простой вопрос: сообщения доходят до результата или застревают в попытках.
Ошибки обработки и ретраи
Начните с доли ошибок и их скорости. Важно не только «сколько ошибок за час», но и как быстро растет кривая: резкий всплеск часто означает падение внешнего сервиса или ошибку в новой версии.
Ретраи полезны, пока они короткие и редкие. Когда повторов становится много, возникает «шторм ретраев»: очереди забиваются одними и теми же событиями, задержка растет, а новые сообщения ждут дольше.
Практичные метрики здесь такие:
- процент сообщений, завершившихся ошибкой (с разбивкой по типам ошибок);
- среднее и p95 число попыток на сообщение;
- время между первой попыткой и успешной обработкой;
- число сообщений, которые крутятся в ретраях дольше N минут.
DLQ, poison message и дубли
DLQ показывает, где система признала поражение. Следите не только за размером DLQ, но и за возрастом самого старого сообщения: полный DLQ не так страшен, как DLQ, который никто не разбирает неделями.
Poison message обычно видно по одному и тому же ключу/идентификатору, который регулярно попадает в DLQ или вызывает одинаковую ошибку. Если одно сообщение дает 30% ошибок, это чаще проблема данных, а не «нестабильность системы».
Дубли опасны там, где есть деньги, лимиты, статусы и остатки. Их считают по idempotency key или бизнес-ключу (например, номер платежа/заявки) и окну времени.
Алерты, которые обычно дают пользу без лишнего шума:
- рост скорости попаданий в DLQ выше базовой линии;
- возраст сообщений в DLQ превысил порог;
- доля сообщений с попытками > X растет подряд несколько интервалов;
- доля дублей по бизнес-ключу превысила норму;
- одна и та же ошибка повторяется по одному ключу чаще N раз.
Пропускная способность и ресурсы: чтобы не перепутать причину и следствие
Когда начинаются задержки, легко ошибиться с диагнозом: кажется, что брокер «не тянет», а на деле не успевают консьюмеры или узкое место в сети. Поэтому важно смотреть не только на «сколько лежит в очереди», но и на баланс потоков: сколько приходит и сколько реально обрабатывается.
Смотрите входной и выходной поток в одном масштабе времени: messages/sec и bytes/sec. Если вход стабильно выше выхода, накопление неизбежно. Если вход просел, а backlog растет, проблема часто в обработке или в подтверждениях (ack/commit).
Backlog (или consumer lag в Kafka) полезен только вместе со скоростью его изменения. Само по себе «10 000 сообщений» почти ничего не говорит. Важно, растет ли число, и с какой скоростью вы «съедаете хвост» после пика.
Что чаще всего ограничивает скорость
В Kafka верхняя граница часто упирается в partitions и consumer group. Один partition читается последовательно, поэтому увеличение числа консьюмеров не поможет, если партиций мало или ключи распределены плохо.
Чтобы быстрее найти узкое место, проверьте:
- входной поток vs выходной поток за тот же интервал;
- скорость роста backlog и время до «нуля» при текущей скорости;
- равномерность lag по partitions (одна «горячая» партиция может ломать весь поток);
- время обработки на стороне консьюмера (среднее и хвост p95/p99);
- ошибки коммитов/ack и повторы из-за таймаутов.
Ресурсы смотрите в общих терминах: CPU, память, диск и сеть. Частая картина: CPU нормальный, а паузы GC или медленный диск дают длинные остановки. Из-за этого консьюмер «дергается» и не успевает подтверждать.
Пики не равны обычному дню
Отдельно отмечайте окна пиков: конец месяца, отчетные периоды, массовые выгрузки. Например, днем система стабильна, а в 18:00 вход удваивается на 30 минут - и backlog растет на часы. Для таких окон полезны отдельные пороги и алерты на «время восстановления» (сколько нужно, чтобы вернуться к норме). Иначе вы будете либо молчать в реальный пик, либо получать шум весь месяц.
Алерты, которые не раздражают: правила, пороги и приоритеты
Хороший алерт отвечает на один вопрос: что сломается для пользователя, если ничего не сделать. Поэтому начинать стоит не с метрик, а с SLO: сколько минут допустима задержка обработки, какой процент сообщений может уйти в ретрай, и когда поток считается «встал».
Обычно собираются десятки графиков, но алертить нужно на риск, а не на сам факт «что-то изменилось». Самые полезные сигналы почти всегда про время и необработанные хвосты: возраст самого старого сообщения, рост отставания потребителя, ускоряющийся рост DLQ, а также доля дублей, если она влияет на деньги, склад или отчеты.
Пороговые алерты подходят там, где есть понятная граница боли. Например: «возраст сообщений > 5 минут дольше 10 минут» для критичного процесса. Алерты по тренду полезнее, когда поток плавает по нагрузке: не «lag 20k», а «lag растет 15 минут подряд и не снижается».
Чтобы снизить шум, держите несколько простых правил:
- Срабатывание с задержкой (например, 5-10 минут), чтобы не ловить короткие всплески.
- Группировка по потоку или топику, а не по каждому партишену.
- Дедупликация: один инцидент - одно уведомление, дальше только апдейты.
- Привязка к окнам бизнеса (например, ночью другой порог для неважных потоков).
Приоритеты лучше задавать не «по красоте графика», а по цене простоя. Удобная схема из трех уровней:
- P1: бизнес-критичные потоки (платежи, учет, доступ) и рост DLQ, который блокирует восстановление.
- P2: деградация без немедленных потерь (рост ретраев, рост задержек в 2-3 раза от нормы).
- P3: ранние признаки (тренд на рост lag, рост времени обработки) для дневного разбора.
Сквозной контроль: корреляция по всем шагам, а не только внутри брокера
Если смотреть только на брокер, легко получить «все зеленое», пока пользователь ждет минутами. Сквозной контроль нужен, чтобы связать запрос, публикацию события, очередь, обработку и итоговый результат в одной цепочке.
Корреляционный идентификатор (correlation_id) - общий номер, который проходит через все шаги. Его обычно берут из входного запроса (если он есть) или создают в первом сервисе, а дальше передают в заголовках сообщения и кладут в логи. Важно хранить его и у продюсера, и у консьюмера, и в DLQ, иначе расследование обрывается ровно там, где больнее всего.
Хорошо работает единый формат логов: один и тот же набор полей и одинаковые названия. Тогда поиск по correlation_id дает последовательность событий, а не набор несвязанных строк.
Минимальный набор полей в событии и логах для диагностики обычно такой:
- correlation_id;
- message_id (уникален для сообщения);
- event_type и version;
- produced_at и received_at/processed_at;
- source_system и consumer_service.
Трассировка должна связывать «запрос -> событие -> обработка». Даже без сложных инструментов можно начать с простого правила: на каждом шаге писать в лог тот же correlation_id и отметку времени, а в сообщении передавать produced_at.
Чтобы быстро понять, какая система тормозит, полезна «карта потока»: по каждому шагу показывать медиану и 95-й процентиль времени (в очереди и в обработке). Если задержка растет в очереди, а обработка стабильна - ищите проблему в пропускной способности брокера или лимитах консьюмера. Если растет время обработки - узкое место в сервисе или внешней зависимости.
Пошагово: как внедрить мониторинг MQ и Kafka за разумный срок
Сильный мониторинг начинается с договоренностей. Если попытаться сразу покрыть все топики и очереди, получится шум и усталость. Выберите несколько потоков, которые действительно влияют на клиентов и процессы, и опишите «норму» так же четко, как описываете SLA.
План на 2-3 недели, который обычно срабатывает
Начните с 3-5 критичных потоков: например, «заказ создан», «статус доставки обновлен», «счет выставлен». Для каждого зафиксируйте ожидаемое поведение: максимальная задержка, допустимые ретраи, что считать ошибкой, где допускается асинхронность.
Дальше двигайтесь по простой цепочке:
- Добавьте в события метку времени (когда событие произошло) и correlation id (один идентификатор на весь путь). Без этого сквозной контроль разваливается.
- Соберите базовые метрики брокера и клиентов: consumer lag, скорость обработки, процент ошибок, глубина очереди, размер DLQ, доля ретраев.
- Сделайте один дашборд для дежурной смены: 5-8 ключевых графиков и один список «топ проблемных потоков» по задержке и DLQ.
- Настройте 5-10 алертов по симптомам: задержка выше порога N минут, lag растет X минут подряд, DLQ не пустая Y минут, ошибка обработки превышает Z%.
- Прогоните учебные инциденты: искусственно замедлите консьюмера, отключите внешнюю зависимость, вызовите массовый ретрай. Проверьте, что алерт понятен, а дежурный видит, что делать дальше.
Отдельно согласуйте правила DLQ и ретраев: сколько попыток, какие ошибки ретраятся, когда сообщение уходит в DLQ, кто и как его разбирает вручную, и как фиксируется итог (повторная отправка, компенсация, списание как «невозможное»). Это превращает наблюдение в управляемый процесс.
Частые ловушки: почему метрики есть, а контроля нет
Часто все выглядит так: «включили метрики, настроили пару алертов», но инциденты все равно приходят от пользователей. Причина простая: метрики есть, а ответов на вопросы «где тормозит» и «что делать» нет.
Типичная ошибка - алерты на среднее. Средняя задержка может быть красивой, пока небольшая доля сообщений зависает на минуты. Поэтому смотрите хвост распределения (p95 и особенно p99) и алертьте его.
Вторая ловушка - путать consumer lag с бизнес-задержкой. Lag показывает, сколько сообщений не обработано, но не говорит, сколько времени клиент ждет результат. Можно иметь небольшой lag и при этом долго держать сообщение в обработке (внешний сервис, база, блокировки). И наоборот: lag большой, но пользователи не страдают, если очередь некритичная.
Еще три вещи, которые тихо ломают контроль:
- Безлимитные ретраи маскируют сбой: система «как будто работает», но долг растет, а после восстановления вы получаете лавину.
- DLQ без процесса разбора превращается в свалку: она растет неделями и всплывает в самый неудобный момент.
- Отсутствие идемпотентности делает дубли опасными: повторное сообщение может дважды списать деньги или создать две заявки.
И еще одна частая ошибка - одинаковые пороги для всех очередей. Для платежей 2 минуты задержки - это инцидент, для ночной синхронизации справочника - норма. Пороги и приоритеты должны зависеть от критичности и ожидаемого времени обработки.
Быстрый чеклист: что проверить перед релизом и при инциденте
Перед релизом полезно убедиться, что вы контролируете не «здоровье брокера», а реальное прохождение сообщений.
Перед релизом проверьте:
- Есть ли метрика возраста самого старого сообщения (oldest message age) по каждому критичному потоку, а не только общий backlog.
- Настроены ли алерты на DLQ: рост количества и «застой» (возраст сообщений в DLQ растет).
- Проверен ли сценарий дублей: одинаковое событие приходит дважды, а система не портит данные (идемпотентность, ключи дедупликации, уникальные ограничения).
- Зафиксированы ли лимиты и политика ретраев: сколько попыток, с какой паузой, и где заканчивается «лечим» и начинается «ломаем».
- Понятно ли, кто владелец DLQ и как выглядит процедура: разбор причины, исправление, возврат в поток, отчет.
Если случился инцидент, сначала соберите картину в одном месте. Дежурному нужен один дашборд: задержка (age), backlog, ошибки/ретраи, DLQ. Это быстрее, чем прыгать между экранами и спорить, «где именно тормозит».
Во время инцидента действуйте так:
- Сравните возраст сообщений и backlog: если backlog небольшой, но возраст большой, проблема часто в конкретном партиционном ключе или одном медленном консьюмере.
- Проверьте ретраи: не крутится ли одна и та же ошибка, создавая лавину и задержки в соседних потоках.
- Посмотрите DLQ: растет ли количество и увеличивается ли возраст (значит, разбор не идет).
- Оцените дубли: не появились ли повторные списания/заявки из-за повторной доставки и отсутствия защиты.
- Зафиксируйте временное решение и владельца дальнейших действий: что делаем сейчас (пауза, ограничение, ручной разбор), что исправляем после.
Пример из практики: задержка и дубли в критичном процессе
В одном критичном процессе система A публикует событие «заявка подтверждена», а система B по нему обновляет статус в карточке клиента. Для бизнеса все просто: пользователь нажал кнопку и через пару секунд должен увидеть новый статус.
Проблема проявилась не как явная ошибка, а как «подвисание»: статусы обновлялись с задержкой 10-40 минут, а у части клиентов статус дергался туда-сюда. В тикетах это выглядело как нестабильность, хотя брокер был «зеленым».
Первое, что помогло, - смотреть не на CPU, а на время. Проверили возраст сообщений в очереди (message age) и lag потребителей: новые события копились быстрее, чем система B успевала их разбирать. Параллельно выросли ошибки обработки и начала заполняться DLQ.
Дальше важно отличить перегруз от «плохих» данных. При перегрузе lag растет почти равномерно, а процент ошибок остается примерно стабильным. При poison message картина другая: lag растет рывками, ошибки одного и того же типа повторяются, а в DLQ попадают события с одинаковой причиной (например, неожиданное значение поля или нарушенная схема).
Что сделали по шагам:
- Ограничили ретраи по времени и числу попыток, чтобы не гонять одно и то же событие часами.
- Временно изолировали проблемный тип событий в отдельный поток обработки, чтобы не стопорить остальные.
- Разобрали DLQ: выделили одну причину, подготовили исправление данных и ретро-обработку.
- Добавили идемпотентность на стороне B (ключ операции), чтобы повторная доставка не меняла статус дважды.
Чтобы это не повторилось, закрепили два правила: алерт на «возраст сообщений > X минут» с приоритетом выше, чем алерт по количеству ошибок, и отдельный алерт на рост DLQ по конкретной причине. Плюс обновили схему события: сделали обязательные поля явными и добавили версию, чтобы потребитель корректно обрабатывал изменения.
Следующие шаги: закрепить процесс и подготовить инфраструктуру
Чтобы мониторинг реально помогал, его нужно закрепить как часть операционного процесса, а не как набор графиков. Начните с инвентаризации: какие интеграции критичны для денег, пациентов, студентов, госуслуг или регламентных сроков, и кто отвечает за результат на стороне бизнеса.
С владельцами процессов согласуйте SLO в простых терминах: сколько минут допустима задержка, сколько сообщений можно потерять (обычно ноль), как быстро нужно восстановиться. Это задает смысл порогам и приоритетам.
Дальше разделите метрики по уровням. На уровне приложений важны факты, которые видит пользователь: время от создания события до обработки, доля ретраев, число дублей, процент сообщений, ушедших в DLQ. На уровне брокера нужны показатели здоровья транспорта: лаги, скорость потребления, ошибки продьюсеров/консьюмеров, заполнение дисков, состояние партиций и репликации.
Практичный план на 2-4 недели:
- Составить список критичных потоков и назначить владельцев.
- Зафиксировать 3-5 обязательных метрик на приложение и 3-5 на брокер.
- Провести нагрузочную проверку и один учебный инцидент (например, остановить консьюмера на 10 минут) и убедиться, что алерты ведут к понятным действиям.
- Описать runbook: кто реагирует, что проверяет первым, где смотреть DLQ и как безопасно делать повторную обработку.
Инфраструктуру лучше готовить заранее: надежные серверы под брокеры, резервирование, прогноз диска под ретеншн, отдельное хранение метрик и логов, а также доступы и аудит. Для организаций с повышенными требованиями важно, чтобы поставка и поддержка были прозрачными.
Если вы планируете обновление или расширение кластера, GSE.kz (gse.kz) может помочь с подбором и поставкой серверов, а также с системной интеграцией и круглосуточной поддержкой, чтобы очереди и мониторинг работали предсказуемо.
FAQ
С каких метрик начать, если пользователи жалуются на задержки, а брокер «зеленый»?
Сначала измерьте **сквозную задержку**: время от создания события в системе-источнике до фактического результата в целевой системе (запись в БД, обновленный статус, отправленное уведомление). Метрики брокера важны, но они не показывают, сколько реально ждет пользователь.
Почему consumer lag в Kafka не равен задержке для бизнеса?
Consumer lag показывает отставание чтения партиции, но не гарантирует, что конкретное сообщение быстро превратилось в результат. Сообщение может «застрять» в обработке, ретраях или внешней зависимости при небольшом lag, поэтому обязательно дополняйте lag метриками времени обработки и end-to-end latency.
Какая метрика лучше всего показывает, что поток реально «встал»?
Используйте **возраст самого старого необработанного сообщения** (oldest message age). Эта метрика напрямую отвечает на вопрос «сколько времени кто-то ждет» и обычно проще для порогов, чем средняя задержка или общий backlog.
Почему нельзя алертить по средней задержке?
Смотрите перцентили, минимум p95 и p99, потому что проблемы чаще живут в «хвосте». Среднее может быть нормальным, пока небольшая доля сообщений висит на минуты и именно она генерирует жалобы и инциденты.
Откуда берутся дубли сообщений и как от них защититься?
Дубли чаще появляются при повторной отправке продюсером (не уверен, что брокер принял) или при повторной обработке консьюмера (успел сделать действие, но не успел подтвердить). Базовая защита — идемпотентность на стороне эффекта: обновление по бизнес-ключу, уникальные ограничения и явный idempotency key, который не дает выполнить операцию второй раз.
Как настроить ретраи, чтобы они помогали, а не ломали поток?
Ретраи полезны, пока они редкие и короткие, но опасны, когда превращаются в «шторм» и забивают очередь одними и теми же событиями. Ограничьте число попыток и общее время ретраев, разделяйте ошибки на временные и постоянные, а невалидные данные быстрее отправляйте в DLQ, чтобы не тормозить весь поток.
Какие сигналы по DLQ действительно важны?
Следите не только за количеством сообщений в DLQ, но и за **возрастом самого старого** и скоростью поступления. DLQ должна быть карантином с понятной причиной, владельцем и процессом разбора; иначе она незаметно накапливает долг и внезапно превращается в крупную бизнес-проблему.
Что нужно для сквозного контроля, если сейчас есть только метрики брокера?
Добавьте единый correlation_id (например, orderId или requestId), который проходит через продюсер, брокер, консьюмер и сохраняется в DLQ. Плюс фиксируйте produced_at и processed_at, чтобы видеть, где именно «съедается» время: в очереди, в обработке или во внешней системе.
Какие алерты обычно дают пользу и не раздражают дежурных?
Сделайте их на риск для пользователя: возраст сообщений выше порога в течение нескольких минут, lag растет подряд и не снижается, ускоряющийся рост DLQ, рост доли ошибок и попыток на сообщение. Чтобы уменьшить шум, используйте задержку срабатывания, дедупликацию инцидентов и разные пороги для критичных и фоновых потоков.
Что стоит проверить перед релизом и к кому обратиться, если нужна инфраструктура и интеграция под Kafka/MQ?
Проверьте, что у вас есть понятные SLO по критичным потокам, сквозной идентификатор и метки времени в событиях, ограниченные ретраи и рабочий процесс разбора DLQ. Если параллельно планируется обновление или расширение инфраструктуры под брокеры и мониторинг, GSE.kz может закрыть подбор и поставку серверов, системную интеграцию и круглосуточную поддержку, чтобы эксплуатация была предсказуемой.