深夜のサーバーダウンに翌朝まで気づかない——中小企業が最初に導入すべき死活監視の設定方法を、実案件の失敗談とコード例を交えて解説します。
「サイトが昨夜から落ちてます」——朝一の電話で気づく恐怖
こんな経験、ありませんか?
月曜の朝、出社してすぐにクライアントから電話が入る。「昨夜からサイトが見られないと問い合わせが来ているんですが……」。確認してみると、サーバーは日曜の深夜2時頃からダウンしていた。つまり約8時間、誰も気づかないまま機会損失が発生していたわけです。
これは決して他人事ではありません。Fivenineでも過去に似たような状況を経験したクライアントから相談を受けています。サーバーが落ちること自体は避けられないケースもある。しかし「気づくのが遅い」は、設定次第で完全に防げます。
本記事では、中小企業のWeb担当者やエンジニアが最初に導入すべき死活監視の仕組みを、実践的なコード例とともに解説します。難しいツールは不要です。無料〜月数百円のサービスを組み合わせれば、今日中に構築できます。
なぜ「気づかない」が起きるのか
監視の仕組みがそもそも存在しない
中小企業のWebサイト運用でよく見られるのが、「サーバーを立ててデプロイしたら終わり」という状態です。開発コストを抑えるために監視ツールの導入が後回しになり、結果として障害検知の手段がゼロという環境が生まれます。
ユーザーからの報告が「監視」になっている
監視の代わりに機能しているのが「ユーザーからの問い合わせ」というケースが非常に多い。しかしこれは最悪の監視方法です。障害に気づくまでのタイムラグが読めず、報告してくれるユーザーがいない深夜帯は特に盲点になります。
サーバーエラーとアプリエラーを混同している
もう一つの落とし穴が、「サーバーが起動している=サイトが正常に動いている」という思い込みです。実際にはNginxは動いているがPHP-FPMがクラッシュしている、DBへの接続が切れていてHTTP 500を返し続けている、といった状況はよく起きます。サーバーのping監視だけでは、こうした「見えないダウン」を検知できません。
死活監視の3層構造を理解する
監視を正しく設計するには、以下の3つのレイヤーを押さえておく必要があります。
flowchart TD
A[外形監視\nHTTPステータス確認] --> B[プロセス監視\nNginx/PHP-FPMの生存確認]
B --> C[アプリケーション監視\nDB接続・ログエラー検知]
A -->|異常検知| D[Slack/メール通知]
B -->|異常検知| D
C -->|異常検知| D- 外形監視: 外部から定期的にHTTPリクエストを送り、ステータスコードと応答時間を確認する
- プロセス監視: サーバー内部でNginxやPHP-FPM、MySQLといったプロセスが生きているかを確認する
- アプリケーション監視: Laravelのログやレスポンスの内容レベルまで踏み込んで異常を検知する
最初に導入すべきは外形監視です。費用ゼロ〜月数百円で始められ、最も即効性があります。
具体的な設定手順
Step 1: UptimeRobotで外形監視を設定する(無料)
UptimeRobot は無料プランで5分間隔の外形監視が50サイトまで設定できます。Slackやメールへの通知も対応しており、中小企業の最初の監視ツールとして最適です。
- アカウントを作成してログイン
- 「Add New Monitor」をクリック
- Monitor TypeをHTTP(s)に設定
- URLに監視対象のサイトURLを入力
- 通知先のメールアドレスまたはSlack Webhookを設定
これだけで、サイトが5分以上ダウンした瞬間にアラートが届く環境が整います。
Step 2: サーバー内でのプロセス監視スクリプト
UptimeRobotはあくまで外形の確認です。Nginx・PHP-FPM・MySQLが内部でクラッシュしているケースを補うために、簡単なシェルスクリプトでプロセス監視を追加します。
#!/bin/bash
# /usr/local/bin/process_monitor.sh
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
HOSTNAME=$(hostname)
check_process() {
local SERVICE=$1
if ! systemctl is-active --quiet "$SERVICE"; then
MESSAGE=":red_circle: *[$HOSTNAME]* ${SERVICE} がダウンしています。自動再起動を試みます。"
curl -s -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"${MESSAGE}\"}" \
"$SLACK_WEBHOOK"
# 自動再起動
systemctl restart "$SERVICE"
fi
}
check_process nginx
check_process php8.2-fpm
check_process mysql
Step 3: Laravelアプリケーションのヘルスチェックエンドポイントを作成する
外形監視でHTTP 200が返っていても、DBへの接続が壊れていてアプリが正常に動作していないケースがあります。Laravelでは専用のヘルスチェックエンドポイントを作成することで、アプリレベルの死活確認が可能です。
<?php
// routes/web.php に追加
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
Route::get('/health', function () {
$checks = [];
// データベース接続確認
try {
DB::select('SELECT 1');
$checks['database'] = 'ok';
} catch (\Exception $e) {
$checks['database'] = 'error';
}
// キャッシュ確認(Redisなど)
try {
Cache::put('health_check', true, 10);
$checks['cache'] = Cache::get('health_check') ? 'ok' : 'error';
} catch (\Exception $e) {
$checks['cache'] = 'error';
}
$status = in_array('error', $checks) ? 503 : 200;
return response()->json([
'status' => $status === 200 ? 'healthy' : 'degraded',
'checks' => $checks,
'timestamp' => now()->toISOString(),
], $status);
})->name('health');
このエンドポイントを UptimeRobotの監視URLとして設定すれば、DBが切れた瞬間にHTTP 503が返り、アラートが発火します。HTTP 200が返っているのに実は壊れているという最悪のパターンを防げます。
Step 4: 通知の応答速度を可視化する
よくある失敗パターンと対処法
実案件での話:EC深夜障害を翌朝まで見逃したケース
あるECサイトのクライアントでは、MySQLのディスク容量がフルになったことでDBへの書き込みが止まり、深夜2時から朝9時まで注文が一切処理されない状態が続いていました。外形監視がなく、ユーザーからの「注文完了画面が出ない」という問い合わせで初めて発覚。推定損失は7時間分の売上約40万円でした。
その後Fivenineで3層監視を構築した結果、半年後に再びDB接続エラーが発生した際は4分以内にアラートが届き、担当者が深夜にSlackで検知・対応できました。障害時間はわずか12分に短縮されています。
監視は「何かが起きてから」ではなく、「何も起きていない今日」に設定するものです。
サーバー管理、丸ごとお任せください
サーバー保守・運用
監視・障害対応・パフォーマンス改善まで、安定稼働をサポートします
※ 通常1営業日以内にご返信します
まとめと次のステップ
死活監視は難しい技術ではありません。しかし後回しにした分だけ、気づかない損失が積み上がっていきます。まず今日、UptimeRobotに登録して本番URLを登録してください。それだけで状況は大きく変わります。
「自分でやってみたが設定に自信がない」「Laravel環境に合わせたヘルスチェックを作ってほしい」という場合は、Fivenineにお気軽にご相談ください。インフラ設計から監視構築まで、運用フェーズもサポートしています。