# (6)障害検知機能の追加
Laravel + cron + AWS CloudWatch で実装する障害検知・ジョブ監視設計
以下、githubのソースコードリンクです。これを基に解説していきます。
はじめに
この大喜利アプリケーションにおいて、最も重要な機能の一つが
お題のスケジュール管理(Cronjob) です。
Linux の cronjob を使って定期処理を実行していますが、
本番運用を考えると以下のリスクが存在します。
- cron がエラーで落ちる
- cron 自体が止まる
- サーバが落ちる
- サーバが高負荷で正常に処理できない
本記事では、これらを想定した 多層的な障害検知・監視設計 を紹介します。
監視設計の全体像
本システムでは、以下の 3 レイヤで監視を行います。
① アプリ内監視(Laravel Scheduler)
② cron 自己監視(heartbeat)
③ 外部監視(AWS CloudWatch)
| レイヤ | 目的 |
|---|---|
| Scheduler | ジョブ失敗の即時検知 |
| heartbeat | cron 停止の検知 |
| CloudWatch | サーバ障害・高負荷検知 |
新しく追加する機能
● スケジュール監視機能
cron で実行されるジョブが失敗した場合に、管理者へメール通知する。
● サーバ死活監視機能
サーバが停止した場合に、AWS 側からメール通知する。
● CPU 使用率監視機能
直近 5 分間の CPU 使用率が 80% を超えた場合に通知する。
1. スケジュール監視機能(Laravel Scheduler)
Scheduler 設定(routes/console.php)
use Illuminate\Support\Facades\Schedule;
Schedule::command('daily:process')
->everyMinute()
->emailOutputOnFailure('admin@admin.com');
Schedule::command('odai:process')
->dailyAt('12:00')
->emailOutputOnFailure('admin@admin.com');
emailOutputOnFailure() は Laravel Scheduler 専用のメソッド で、
コマンドが異常終了(exit code ≠ 0)した場合のみ、
標準出力・標準エラーをメール送信します。
ジョブ側の実装(重要)
class DailyProcess extends Command
{
protected $signature = 'daily:process';
public function handle(): int
{
try {
// 処理省略
return Command::SUCCESS;
} catch (Throwable $e) {
report($e);
throw $e; // ← exit code を失敗扱いにするため必須
}
}
}
なぜ throw し直すのか?
- 例外を握りつぶすと exit code = 0 になる
-
emailOutputOnFailureは 失敗時のみ発火 - よって 必ず例外を再スローする必要がある
2. cron 自己監視(heartbeat)
heartbeat を更新するジョブ
Schedule::call(function () {
Cache::put('cron_heartbeat', now());
})->everyMinute();
heartbeat をチェックする監視ジョブ
Schedule::command('cron:check-heartbeat')
->everyFiveMinutes()
->emailOutputOnFailure('admin@admin.com');
class CheckCronHeartbeat extends Command
{
protected $signature = 'cron:check-heartbeat';
public function handle(): int
{
try {
$lastRun = Cache::get('cron_heartbeat');
if (!$lastRun || now()->diffInMinutes($lastRun) > 5) {
throw new \RuntimeException('Cron stopped');
}
return Command::SUCCESS;
} catch (Throwable $e) {
report($e);
throw $e; // Scheduler failure 扱い
}
}
}
これにより、cron が 5 分以上止まった場合にアラートが飛ぶ ようになります。
3. サーバ死活監視・CPU 監視(AWS)
アプリ内の監視だけでは、サーバ自体が落ちた場合に検知できません。
そのため、AWS のマネージドサービスを利用します。
使用サービス
- Amazon CloudWatch:監視・アラーム
- Amazon SNS:通知(メール)
監視内容
- EC2 インスタンスの Status Check
- CPU 使用率(5 分平均 > 80%)
公式ドキュメント
-
CloudWatch 概要
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html -
SNS 通知設定
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Notify_Users_Alarm_Changes.html
まとめ
- 監視は一層では足りない
- アプリ・cron・インフラの 三段構え が重要
- 「監視が壊れた場合の監視」まで考えると安心
今後は、
- DB 冗長化
- ネットワーク構成
- 障害時の復旧戦略
なども学びつつ、
個人開発での実装で理解を深めていきたいと思います!(^^)
Discussion