Heartbeat(ハートビート)とは?システム監視の仕組みを徹底解説

プログラミング・IT

「サーバーがダウンしていることに気づかなかった…」

「障害を早期に検知する方法が知りたい」

こんな課題を解決してくれるのが、Heartbeat(ハートビート)です。

この記事では、システムやネットワークの生存確認に欠かせないハートビートの仕組みについて、基礎から実践まで分かりやすく解説していきますね。


スポンサーリンク

Heartbeatの基本概念

Heartbeatって何?

Heartbeat(ハートビート)は、システムやサービスが正常に動作していることを確認するための「生存信号」です。

心臓の鼓動のように、定期的に信号を送ることで「生きている」ことを示します。

この信号が途絶えると、システムに問題が発生したと判断できるんですね。

なぜHeartbeatが必要なの?

システムの障害は、いつ発生するか分かりません。

早期発見

問題が発生したら、すぐに検知できます。

ユーザーからの報告を待つ前に対応できるんですね。

自動フェイルオーバー

メインシステムがダウンしたら、自動的に予備システムに切り替えられます。

サービスの停止時間を最小限に抑えられますよ。

サービスレベルの保証

システムの可用性を高く保てます。

ビジネスの信頼性向上につながるんです。

実世界の例

スマートウォッチが心拍数を測るように、ITシステムも「生きているか」を常に確認します。

人間の心拍が止まったら緊急事態なのと同じように、ハートビートが止まったらシステムに問題があると判断できますね。


Heartbeatの基本的な仕組み

送信側と受信側

ハートビートは、2つの役割で成り立ちます。

送信側(Sender)

定期的に「生きています」という信号を送る側です。

通常は、監視されるサーバーやアプリケーションが担当します。

受信側(Receiver / Monitor)

信号を受け取って、システムの状態を判断する側です。

監視システムや管理サーバーが担当しますね。

動作の流れ

基本的なハートビートの処理は、とてもシンプルです。

ステップ1:定期送信

送信側が、一定間隔(例:5秒ごと)で信号を送ります。

「ping」のような簡単なメッセージで十分です。

ステップ2:受信確認

受信側が、信号を受け取ったことを記録します。

最後に受信した時刻を保存しておくんですね。

ステップ3:タイムアウト判定

一定時間(例:15秒)信号が来なければ、異常と判断します。

この時間を「タイムアウト値」と呼びます。

ステップ4:アクション実行

異常を検知したら、アラートを出したり、フェイルオーバーを実行したりします。


Heartbeatの種類

プッシュ型(Push型)

監視される側から、能動的に信号を送る方式です。

サーバーA → 「生きてます!」 → 監視システム
(5秒ごと)

メリット:

  • サーバーの状態を正確に反映
  • ネットワーク負荷が低い
  • シンプルで実装しやすい

デメリット:

  • サーバーがダウンすると信号が送れない
  • 送信側にロジックが必要

最も一般的な方式ですね。

プル型(Pull型)

監視する側から、定期的に状態を確認する方式です。

監視システム → 「生きてる?」 → サーバーA
               ← 「はい!」 ←
(5秒ごと)

メリット:

  • 監視側で制御できる
  • 複数サーバーを統一的に監視可能
  • 送信側の実装が不要な場合も

デメリット:

  • ネットワーク負荷がやや高い
  • 大規模環境では負荷が問題に

ヘルスチェックとも呼ばれる方式です。

ハイブリッド型

両方の良いところを組み合わせた方式もあります。

通常はプッシュ型で、応答がない場合のみプル型で確認するなど、柔軟な運用ができますよ。


Heartbeat間隔とタイムアウトの設定

適切な間隔の決定

環境や要件に応じて、最適な値を設定します。

高頻度(1〜5秒)

  • リアルタイム性が重要なシステム
  • 金融取引システム
  • 医療機器の監視

迅速な障害検知が可能ですが、ネットワーク負荷は高くなりますね。

中頻度(10〜30秒)

  • 一般的なWebサービス
  • 社内業務システム
  • データベースクラスタ

バランスの取れた設定で、最も多く使われます。

低頻度(1〜5分)

  • バッチ処理システム
  • 定期レポート生成
  • バックアップサービス

リアルタイム性は不要だが、稼働確認は必要な場合ですよ。

タイムアウト値の計算

一般的な目安は、「ハートビート間隔の3倍」です。

例:

  • ハートビート間隔:10秒
  • タイムアウト値:30秒

2回連続で失敗してもまだ余裕があり、誤検知を防げますね。

誤検知を防ぐ工夫

ネットワークの一時的な遅延で、誤って障害と判断しないようにします。

リトライ機構

タイムアウト後、即座に再確認します。

3回連続で失敗した場合のみ、障害と判断するなど。

閾値の設定

一定回数以上の失敗で、初めてアラートを出します。

過敏な反応を避けられますよ。


実装例とコード

Python での簡単な実装

シンプルなハートビート送信側の例です。

import time
import requests

def send_heartbeat(url, interval=5):
    """
    定期的にハートビートを送信する
    """
    while True:
        try:
            response = requests.post(url, json={'status': 'alive'})
            print(f'Heartbeat sent: {response.status_code}')
        except Exception as e:
            print(f'Failed to send heartbeat: {e}')

        time.sleep(interval)

# 5秒ごとにハートビートを送信
send_heartbeat('http://monitor.example.com/heartbeat', interval=5)

受信側(監視側)の実装

受信したハートビートをチェックします。

import time
from datetime import datetime, timedelta

class HeartbeatMonitor:
    def __init__(self, timeout=30):
        self.last_heartbeat = {}
        self.timeout = timeout

    def receive_heartbeat(self, server_id):
        """ハートビートを受信"""
        self.last_heartbeat[server_id] = datetime.now()
        print(f'Heartbeat received from {server_id}')

    def check_status(self, server_id):
        """サーバーの状態をチェック"""
        if server_id not in self.last_heartbeat:
            return 'unknown'

        last_time = self.last_heartbeat[server_id]
        elapsed = (datetime.now() - last_time).total_seconds()

        if elapsed > self.timeout:
            return 'down'
        return 'alive'

    def monitor_loop(self):
        """定期的に全サーバーをチェック"""
        while True:
            for server_id in list(self.last_heartbeat.keys()):
                status = self.check_status(server_id)
                if status == 'down':
                    print(f'ALERT: {server_id} is down!')

            time.sleep(10)

# 使用例
monitor = HeartbeatMonitor(timeout=30)

Node.js での実装

JavaScriptでも簡単に実装できます。

const express = require('express');
const app = express();

const heartbeats = new Map();
const TIMEOUT = 30000; // 30秒

// ハートビート受信エンドポイント
app.post('/heartbeat', express.json(), (req, res) => {
  const serverId = req.body.server_id;
  heartbeats.set(serverId, Date.now());
  console.log(`Heartbeat received from ${serverId}`);
  res.json({ status: 'ok' });
});

// 定期的な監視
setInterval(() => {
  const now = Date.now();
  heartbeats.forEach((lastTime, serverId) => {
    if (now - lastTime > TIMEOUT) {
      console.log(`ALERT: ${serverId} is down!`);
    }
  });
}, 10000); // 10秒ごとにチェック

app.listen(3000, () => {
  console.log('Monitor server running on port 3000');
});

実際の使用場面

ロードバランサーとの連携

ロードバランサーは、ハートビートで各サーバーの状態を確認します。

動作の流れ:

  1. ロードバランサーが各Webサーバーにヘルスチェック
  2. 応答があるサーバーにのみトラフィックを振り分け
  3. ダウンしたサーバーを自動的に切り離す
  4. 復旧したら自動的に組み込む

ユーザーは障害に気づかず、継続してサービスを利用できますね。

データベースクラスタ

高可用性データベースシステムでの活用例です。

マスター・スレーブ構成:

  • スレーブがマスターのハートビートを監視
  • マスターがダウンしたら、スレーブが昇格
  • 自動フェイルオーバーでサービス継続

PostgreSQLのStreaming ReplicationやMySQL Group Replicationなどで使われています。

マイクロサービスアーキテクチャ

多数のサービスが連携する環境で重要です。

サービスディスカバリ:

  • 各マイクロサービスが自分の存在を通知
  • サービスレジストリが稼働サービスを管理
  • ダウンしたサービスを自動的にリストから削除

Kubernetes、Consul、Eurekaなどで実装されていますよ。

コンテナオーケストレーション

Kubernetesでの活用例です。

Liveness Probe:

コンテナが生きているか確認します。

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10

応答がなければ、コンテナを自動再起動しますね。

Readiness Probe:

コンテナがトラフィックを受け付けられるか確認します。

準備ができていないコンテナには、リクエストを送りません。


ハートビートプロトコルの設計

メッセージフォーマット

シンプルで効率的な設計が重要です。

最小限の情報:

{
  "server_id": "web-01",
  "timestamp": "2025-10-21T12:00:00Z",
  "status": "ok"
}

詳細な情報を含む場合:

{
  "server_id": "web-01",
  "timestamp": "2025-10-21T12:00:00Z",
  "status": "ok",
  "cpu_usage": 45.2,
  "memory_usage": 68.5,
  "active_connections": 127
}

メトリクスも同時に送れば、監視を強化できます。

通信方式

環境に応じた最適な方式を選びます。

HTTP/HTTPS:

最も一般的で、実装が簡単です。

既存のWebサーバーに簡単に組み込めますね。

UDP:

軽量で高速ですが、信頼性は低くなります。

パケット損失を許容できる場面で有効です。

TCP:

信頼性の高い通信が可能です。

重要なシステムでの使用に適しています。

メッセージキュー:

RabbitMQ、Kafkaなどを使った非同期通信です。

大規模システムでのスケーラビリティに優れていますよ。


フェイルオーバーとの連携

自動フェイルオーバーの流れ

ハートビートが障害を検知したら、自動的に切り替えます。

ステップ1:障害検知

プライマリサーバーのハートビートが停止します。

ステップ2:待機系の昇格

セカンダリサーバーがプライマリに昇格するんですね。

ステップ3:IPアドレスの引き継ぎ

仮想IPアドレスを新しいプライマリに移動します。

ステップ4:サービス再開

クライアントは同じIPアドレスでアクセスを継続できます。

切り替えは数秒〜数十秒で完了しますよ。

スプリットブレイン問題

両方のサーバーがプライマリになってしまう問題です。

原因:

ネットワーク分断により、互いが相手をダウンと誤認します。

対策:

  • Quorum(定足数): 過半数の票を得た方がプライマリになる
  • STONITH(Shoot The Other Node In The Head): 強制的に相手をシャットダウン
  • 仲裁サーバー: 第三者が正当性を判断

複雑ですが、データの整合性のために重要な仕組みですね。


セキュリティの考慮事項

なりすまし対策

悪意のある第三者が偽のハートビートを送る可能性があります。

認証トークン:

{
  "server_id": "web-01",
  "timestamp": "2025-10-21T12:00:00Z",
  "token": "abc123def456"
}

事前共有鍵や証明書で、正当性を確認します。

IPアドレス制限:

特定のIPアドレスからのハートビートのみ受け付けます。

内部ネットワーク限定にすることが多いですね。

暗号化通信

ハートビートの内容を保護します。

TLS/SSL:

HTTPS経由でハートビートを送信すれば、盗聴や改ざんを防げます。

VPN:

専用の暗号化トンネルを使用する方法もありますよ。


パフォーマンスへの影響

ネットワーク負荷

ハートビートは、継続的な通信を発生させます。

負荷の計算例:

  • サーバー数:100台
  • ハートビート間隔:10秒
  • パケットサイズ:100バイト

毎秒10回 × 100バイト = 1KB/秒

大規模環境でも、負荷は比較的小さいですね。

CPUとメモリ

ハートビートの処理自体は軽量です。

適切に実装すれば、システムリソースへの影響は最小限に抑えられます。

最適化のポイント

効率的な実装のコツです。

バッチ処理:

複数のハートビートをまとめて処理します。

非同期処理:

メインの処理をブロックしないようにします。

適切なタイムアウト値:

過度に短くしないことで、不要な処理を減らせますよ。


トラブルシューティング

ハートビートが届かない

いくつかの原因が考えられます。

ネットワークの問題:

ファイアウォールでブロックされていないか確認しましょう。

pingやtelnetで疎通確認をしてください。

送信側の問題:

プロセスが停止していないか確認します。

ログを見て、エラーが出ていないかチェックしますね。

タイムゾーンのずれ:

タイムスタンプを使う場合、時刻同期が重要です。

NTPで時刻を合わせましょう。

頻繁な誤検知

正常なのに障害と判断されてしまう場合です。

タイムアウト値の見直し:

短すぎる可能性があります。

ネットワーク遅延を考慮して、余裕を持たせてください。

リトライ回数の増加:

1回の失敗で判断せず、複数回確認します。

ログの分析:

実際の応答時間を記録して、適切な値を決定しますよ。


モニタリングツールの活用

オープンソースツール

既存のツールを活用すると、実装が楽になります。

Nagios:

古典的な監視ツールで、豊富なプラグインがあります。

ハートビートチェックも標準機能として提供されていますね。

Prometheus:

現代的なメトリクス収集システムです。

時系列データとして、ハートビートを記録できます。

Zabbix:

企業向けの統合監視ツールです。

エージェントを使った詳細な監視が可能ですよ。

クラウドサービス

マネージドサービスも充実しています。

AWS CloudWatch:

AWSリソースの監視に特化しています。

カスタムメトリクスでハートビートも送信できますね。

Google Cloud Monitoring:

GCPの統合監視サービスです。

アップタイムチェック機能が組み込まれています。

Datadog:

クラウドネイティブな監視プラットフォームです。

豊富な統合機能で、あらゆる環境を監視できますよ。


ベストプラクティス

設計時の推奨事項

成功するハートビートシステムの条件です。

シンプルに保つ:

複雑な処理は避け、軽量な実装を心がけましょう。

冗長性を確保:

監視システム自体も冗長化します。

監視の監視(メタモニタリング)も検討してください。

適切なアラート:

重要度に応じて、通知方法を変えます。

深夜に緊急でないアラートで起こされるのは避けたいですね。

運用時の注意点

日々の運用で気をつけるポイントです。

定期的な見直し:

システムの成長に合わせて、設定値を調整します。

テストの実施:

フェイルオーバーが正しく動作するか、定期的に確認しましょう。

ドキュメント化:

設定内容や対応手順を明文化します。

緊急時に慌てないための準備が大切ですよ。


まとめ:Heartbeatでシステムの信頼性を高めよう

Heartbeat(ハートビート)は、システムの健全性を保つための基本的な仕組みです。

適切に実装・運用することで、サービスの可用性を大幅に向上させられます。

この記事の重要ポイント:

  • ハートビートは定期的な生存信号で障害を早期検知
  • プッシュ型とプル型の2つの方式がある
  • 適切な間隔とタイムアウト値の設定が重要
  • 誤検知を防ぐ工夫が必要
  • ロードバランサーやクラスタで広く使われる
  • 自動フェイルオーバーと組み合わせて高可用性を実現
  • セキュリティ対策も忘れずに
  • 既存の監視ツールを活用すると効率的

まずは小規模な環境で、シンプルなハートビートを実装してみましょう。

実際に動かしながら学ぶことで、システム監視の理解が深まっていきますよ。

コメント

タイトルとURLをコピーしました