首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 監控 Nginx 502 錯誤並自動重啟 PHP-FPM:健康檢查腳本與 Crontab 部署

     編輯:PHP 綜合知識

問題背景

PHP-FPM 進程異常退出、達到 pm.max_children 限制、慢日志阻塞等導致 Nginx 返回 502 Bad Gateway。需自動化檢測並恢復。

健康檢查腳本 (check_php_fpm.php)

> /var/log/php_fpm_monitor.log 2>&1
 */

$config = [
    'check_url' => 'https://your-domain.com/healthz', // 健康檢查端點 (返回 200 OK)
    'restart_cmd' => 'systemctl reload php-fpm',      // 或 service php-fpm reload
    'timeout' => 3,                                   // HTTP 超時秒數
    'max_retries' => 3,                               // 連續失敗幾次才重啟
    'user_agent' => 'PHP-FPM-Monitor/1.0',
];

$consecutiveFailures = 0;
$stateFile = '/tmp/php_fpm_monitor_state';

// 讀取歷史失敗計數
if (file_exists($stateFile)) {
    $consecutiveFailures = max(0, (int)file_get_contents($stateFile));
}

for ($i = 0; $i < $config['max_retries']; $i++) {
    $ctx = stream_context_create([
        'http' => [
            'method' => 'HEAD',
            'timeout' => $config['timeout'],
            'user_agent' => $config['user_agent'],
            'ignore_errors' => true, // 獲取錯誤碼不拋異常
        ],
        'ssl' => [
            'verify_peer' => false, // 自簽證書環境
            'verify_peer_name' => false,
        ],
    ]);
    
    $headers = @get_headers($config['check_url'], 1, $ctx);
    
    if ($headers && isset($headers[0]) && stripos($headers[0], '200') !== false) {
        // 成功:重置計數
        $consecutiveFailures = 0;
        @file_put_contents($stateFile, '0');
        exit(0);
    }
    
    $consecutiveFailures++;
    @file_put_contents($stateFile, (string)$consecutiveFailures);
    sleep(2); // 重試間隔
}

// 達到閾值,執行重啟
if ($consecutiveFailures >= $config['max_retries']) {
    error_log("[PHP-FPM Monitor] " . date('c') . " Detected 502, executing restart: {$config['restart_cmd']}");
    @shell_exec($config['restart_cmd']);
    
    // 重啟後等待並再次驗證
    sleep(5);
    $headers = @get_headers($config['check_url'], 1, $ctx);
    if ($headers && stripos($headers[0], '200') !== false) {
        error_log("[PHP-FPM Monitor] Restart successful, service recovered.");
    } else {
        error_log("[PHP-FPM Monitor] CRITICAL: Restart failed, manual intervention required!");
    }
    
    // 重置計數避免重複重啟
    @file_put_contents($stateFile, '0');
}

關鍵設計點

機制作用
HEAD 請求不下載 Body,極輕量,僅檢查狀態碼
連續失敗計數避免網絡抖動誤觸發重啟 (文件持久化跨進程)
多次重試單次超時不重啟,連續 3 次失敗才動作
重啟後驗證確認恢復,失敗記錄 CRITICAL 日志
忽略 SSL 驗證適配自簽證測試環境,生產建議開啟驗證

Nginx 健康檢查端點配置

# nginx.conf / site.conf
location = /healthz {
    access_log off;
    return 200 "OK\n";
    add_header Content-Type text/plain;
}

或 PHP 實現 (healthz.php):



系統級替代方案:systemd Watchdog

# /etc/systemd/system/php-fpm.service.d/watchdog.conf
[Service]
WatchdogSec=30
Restart=on-failure
RestartSec=5
# PHP-FPM 需支援 sd_notify (PHP 7.3+ 支援)
# 需在 php-fpm.conf: systemd_interval = 10

優點:內核級監控、無需外部腳本、精確到進程級。缺點:需 systemd 229+、PHP-FPM 編譯支援。

進階:Zabbix / Prometheus 監控告警

  • Zabbix:net.tcp.service[http,,80] + 觸發器「連續 3 次 502」→ 執行腳本重啟 + 鈉釘/郵件告警。
  • Prometheus + Alertmanager:nginx_upstream_server_status{status="down"} → 告警 → Webhook 觸發 Ansible/腳本重啟。

總結

「輕量腳本 + Crontab」適合中小項目快速落地;中大型項目建議接入系統級 Watchdog + 監控系統告警,實現自愈與可觀測並重。核心原則:**檢測業務端點而非進程存活,重啟後必須驗證恢復,避免重啟風暴**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved