Heartbeat

9 июля 2026 · ~14 мин чтения

концепция мониторинг надёжность распределённые-системы отказоустойчивость

Heartbeat

Heartbeat (сердцебиение) — это регулярный сигнал «я жив», который один
компонент системы отправляет другому через фиксированные промежутки времени.
Пока сигнал приходит вовремя — считается, что источник работает; пропало
несколько сигналов подряд — источник считается сломавшимся, и включаются
заранее оговорённые действия: алерт, перезапуск, переключение на резерв.

История

Сама идея старше компьютеров. В телеметрии первых баллистических ракет и
спутников 1950-х уже был «маяк» (beacon): аппарат непрерывно передавал
короткий радиосигнал, и пока сигнал слышен — считалось, что аппарат жив и
летит. У «Спутника-1» в октябре 1957 года это буквально был знаменитый
писк на частоте 20 МГц — простейший heartbeat планетарного масштаба.

В вычислительной технике параллельно развивалась идея watchdog-таймера
(«сторожевой таймер»): аппаратный счётчик, который сам себя сбрасывает,
если процессор регулярно к нему обращается, и жёстко перезагружает
машину, если обращений долго нет. Первые упоминания — конец 1960-х,
массово — в промышленной электронике и авионике 1970-х.

Дальше — вехи именно термина «heartbeat» в софте:

Сегодня это один из самых базовых кирпичиков любой распределённой
системы: без него нельзя честно ответить на вопрос «а этот сервер вообще
ещё работает?».

Что это такое

Представь двух людей, которые договорились: «Пока я пишу тебе в чат
короткое „ок“ каждую минуту — со мной всё нормально. Молчу пять минут
подряд — вызывай скорую». Это и есть heartbeat в чистом виде. Один
конец периодически отсылает сигнал, второй следит за расписанием
поступления и реагирует на пропуск.

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

Heartbeat vs health check. Heartbeat — сигнал в одну сторону, отправляет
сам «пациент»: «я жив, я жив, я жив» (это называют push-модель). Health check
(«проверка здоровья») — обычно наоборот: наблюдатель сам ходит и спрашивает
«ты жив? покажи внутренности», получает ответ с деталями (это pull-модель).
Часто внутри health check как раз реализована функция, которая проверяет
«не устарел ли последний heartbeat».

Heartbeat vs polling (опрос). Polling — это «наблюдатель сам стучится в
дверь по расписанию». Heartbeat — «жилец сам кричит из окна по расписанию».
При heartbeat инициатива у источника, при polling — у наблюдателя. Разница
принципиальна для случаев, когда наблюдатель не может достучаться до
источника: он за NAT, за файрволом, в мобильной сети без внешнего IP.
Тогда heartbeat — единственный способ.

Heartbeat vs watchdog (сторожевой таймер). Watchdog — почти всегда
локальный: процессор пишет в регистр «я живой», и если долго не пишет —
аппаратура жёстко его перезагружает. Heartbeat — почти всегда сетевой:
между процессами, машинами, датацентрами. Идея одна («молчание = смерть»),
масштаб разный.

Liveness vs readiness. В Kubernetes прижилась чёткая пара:
liveness probe («жив ли контейнер вообще, не завис ли») и readiness probe
(«готов ли принимать трафик прямо сейчас — прогрел ли кэш, подключился ли
к базе»). Первый пропуск заканчивается перезапуском контейнера, второй —
временным выведением из балансировки. Heartbeat как термин обычно
относится к первому.

Важный принцип: сам факт прихода heartbeat не гарантирует, что система
работает правильно. Он гарантирует только, что процесс, отвечающий за
отправку heartbeat, крутится и до сети дотягивается. Если приложение
внутри зависло на бесконечной обработке одного запроса, а фоновый
поток продолжает отправлять «я жив» — снаружи всё выглядит здоровым.
Поэтому в зрелых системах heartbeat совмещают с более честными
проверками: «сходить в базу», «обработать тестовый запрос».

Аналогии из жизни

Ребёнок в игре в прятки, который громко считает. Пока водящий слышит
«раз, два, три...» — он знает: игрок жив, играет по правилам, стоит у
стены и не подглядывает. Замолчал — либо ушёл жульничать, либо ушёл на
кухню за печеньем.
Где ломается: ребёнок может считать вслух, но подглядывать одним глазом
— формально жив, по существу читерит. Ровно так же процесс может слать
heartbeat, но внутри быть намертво зависшим на реальной работе. Сигнал
подтверждает только то, что механизм счёта работает, а не то, что игра
идёт честно.

Кардиомонитор в больничной палате. Пикает при каждом ударе сердца
пациента, а при остановке ритма кричит громким тревожным сигналом.
Медсестра на посту не смотрит непрерывно — она реагирует только на
молчание монитора или на тревогу.
Где ломается: датчик может отвалиться от кожи, и монитор закричит,
когда пациент здоров и хочет спать (ложная тревога). Или наоборот,
провод может касаться и давать красивую линию, когда пациенту плохо.
Ровно те же две беды в IT: ложные срабатывания от сетевого сбоя между
источником и наблюдателем и ложное спокойствие, если heartbeat идёт «в
обход» настоящего состояния системы.

Регулярный звонок бабушке. Договор: «Звоню каждое воскресенье в семь
вечера. Если два воскресенья подряд не позвонил — езжай проверять».
Простая, дешёвая, честная модель heartbeat: интервал, порог пропусков
(два), действие при срабатывании (езжай проверять).
Где ломается: бабушка живёт в деревне, где связь пропадает по погоде.
Пропущенный звонок означает не «беда», а «дождь». В IT то же самое:
надо отличать «источник умер» от «сеть между нами моргнула». Обычно
это лечится порогом («не один пропуск, а три подряд») и учётом
косвенных признаков («а другие соседи бабушки на связи?»).

Как это работает

Разберём типовую схему по шагам.

Шаг 1. Договор. Отправитель (sender) и приёмник (receiver) заранее
договариваются о трёх числах:

Шаг 2. Отправка. Отправитель раз в интервал отсылает короткое
сообщение. Формат зависит от контекста: TCP-пакет без данных с флагом
ACK (TCP keepalive), UDP-датаграмма, HTTP POST на URL мониторинга,
запись строки в таблицу базы, вызов RPC-метода.

Псевдокод простого heartbeat в фоновой задаче:

while running:
    try:
        send_heartbeat(job_id, status="ok", timestamp=now())
    except Exception as e:
        log(e)
    sleep(interval)

Шаг 3. Наблюдение. Приёмник ведёт таблицу «когда в последний раз я
слышал каждого». Отдельный процесс раз в интервал сверяет её с текущим
временем:

for job_id, last_seen in heartbeats.items():
    if now() - last_seen > timeout:
        raise_alert(job_id)

Шаг 4. Реакция. Что именно происходит при обнаружении молчания —
зависит от роли системы:

Шаг 5. Возврат в норму. Когда сигнал возобновляется, наблюдатель
снимает алерт (или пишет отдельное «recovery»-событие), сбрасывает
счётчик пропусков и возвращает узел в строй.

Push vs pull. Push (то, что мы описали) — источник сам шлёт. Pull —
наблюдатель сам ходит и спрашивает. Push дешевле для наблюдателя
(меньше сетевых запросов на всех сразу) и работает через NAT/файрвол,
но требует, чтобы источник знал адрес наблюдателя. Pull даёт
наблюдателю больше контроля (может спросить дополнительно, может
пропустить проверку под нагрузкой) и удобнее для внешних клиентов
мониторинга. В реальности часто гибрид: клиент отправляет heartbeat,
а раз в час наблюдатель делает контрольный pull для сверки.

Ложные срабатывания и jitter. Если тысяча процессов настроена
слать heartbeat ровно в HH:MM:00, один сбой сети создаст лавину
одновременных «пропали». Лечится jitter (дрожанием) — добавлением
небольшого случайного сдвига к интервалу: не ровно 60 секунд, а
55–65. Тот же приём распределяет нагрузку на приёмник ровным ковром
вместо пиков.

Выбор интервала — это компромисс. Слишком часто (1 сек) — нагрузка
на сеть и приёмник, лишний расход батареи для мобильных клиентов,
масса ложных срабатываний. Слишком редко (10 минут) — узнаёшь о падении
через 20–30 минут, за это время клиенты успевают разозлиться.
Правило большого пальца: интервал ≈ 1/10 от допустимого времени
обнаружения сбоя.

Heartbeat лечит слепоту, но не глухоту

Сам по себе сигнал говорит только «процесс жив и до наблюдателя дотягивается». Он не говорит, что приложение работает правильно, что база отвечает, что очередь не переполнена. В зрелой системе heartbeat — самый низкий уровень пирамиды: над ним health check с проверкой зависимостей, а над ним — метрики бизнес-смысла («сколько заявок за минуту прошло»).

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Кто пользуется

Альтернативы и конкуренты

Когда НЕ стоит использовать

Тишина — тоже сообщение

Главная сила heartbeat не в том, что мы слышим сигнал, а в том, что мы умеем интерпретировать его отсутствие. Ровно поэтому у heartbeat всегда есть тройка «интервал — таймаут — порог»: без честно заданного порога любая пропущенная посылка превращается либо в ложную тревогу, либо в проигнорированную беду.

Связанные понятия

Литература и источники

Где встретилось у меня

Вчера в сервисе мониторинга рекламных кампаний проектировалась
таблица cron_heartbeat в SQLite: каждый фоновый job в конце
работы делает upsert строки со своим статусом и временем; поверх
этого — детектор протухшего OAuth-токена внешней рекламной системы
с алертом в мессенджер и красным баннером в админке. Ровно тот
самый dead man's switch: молчание job'а — сигнал, что что-то пошло
не так, ещё до того, как это увидит менеджер.

Краткое резюме