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

使用 Shell 腳本守護 PHP 進程:百萬級用戶資料檢測的實戰方案

     編輯:PHP 相關知識

專案背景與挑戰

近期接手一項任務:需對 2000 萬用戶名單進行手機號、郵箱綁定狀態檢測。用戶名單易於獲取,但檢測必須逐個調用外部安全接口,接口響應極慢,單線程處理 2000 萬條記錄至少需數天。若 PHP 腳本中途掛掉,進度將難以恢復,因此必須建立可靠的守護機制。

整體架構設計

  1. 資料暫存層:建立臨時表 users,字段包含帳號、手機標記、郵箱標記、處理標記(flag)。
  2. 批次處理層:PHP 腳本每次取 flag=0 的 500 條記錄,調用接口檢測,生成批量 UPDATE SQL 寫回,並將 flag 置 1。
  3. 守護進程層:Shell 腳本每分鐘通過 crontab 執行,檢測 PHP 進程是否存活;若掛掉或執行超時則 kill 後重啟,確保任務持續推進。

核心代碼實現

1. 資料表結構

CREATE TABLE `users` (
  `account` varchar(50) COMMENT '用戶名',
  `has_phone` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有手機號',
  `has_email` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有郵箱',
  `flag` tinyint(3) unsigned NOT NULL default '0' COMMENT '標志位',
  PRIMARY KEY (`account`),
  KEY `flag` (`flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='名單表';

2. PHP 批次處理腳本 (check_users.php)

nums != 500) { $flag = false; }
            if ($this->total_nums >= 10000) { exit(0); } // 每 1 萬條退出,由守護進程重啟
            
            $this->getUsers();
            $this->checkUserInfo();
            $this->updateUserInfo();
            sleep(1); // 保護下游接口
        }
    }
}
$user = new Users();
$user->run();

關鍵點:引入 $total_nums 計數器,每處理 1 萬條主動 exit(0),避免長連接導致的資源洩漏或 DB 連接斷開而腳本卡死無法退出。

3. Shell 守護腳本 (check_daemon.sh)

#!/bin/bash
PHP_SCRIPT="/path/to/check_users.php"
MAX_RUNTIME=300  # 5 分鐘超時

# 檢查進程是否存在
pid=$(pgrep -f "check_users.php")
if [ -n "$pid" ]; then
    # 計算已運行時間
    start_time=$(ps -o lstart= -p "$pid" | xargs -I {} date -d "{}" +%s)
    now=$(date +%s)
    if [ $((now - start_time)) -gt $MAX_RUNTIME ]; then
        kill -9 "$pid"
        php "$PHP_SCRIPT" &
    fi
else
    php "$PHP_SCRIPT" &
fi

將此腳本加入 crontab -e,設置 * * * * * /path/to/check_daemon.sh 每分鐘執行。

執行結果示例

處理前:testalexlee,0,0,0
處理後:testalexlee,1,0,1(flag=1 表示已完成,has_phone=1 表示綁定手機)

經驗總結與優化建議

  • 接口瓶頸:外部接口需自查表、回寫,RT 高。若有權限,直接讀取源表配合 LOAD DATA + Shell 處理可將耗時從天級降至小時級。
  • 超時保護:Shell 層雙重保險(進程存活 + 運行時長)有效解決 PHP 卡死不退出問題。
  • 批次大小:500 條/批平衡了內存佔用與接口調用頻率;配合 sleep(1) 避免觸發限流。
  • 冪等性:flag 機制保證重複執行不會重複扣款/寫入。

此方案在受限環境下(無法直連 DB、只能走慢速接口)以最小改動實現了百萬級任務的可靠跑批,核心思想是「分批處理 + 主動退出 + 外部守護」三位一體,適用於各類長耗時、不可中斷的 PHP 異步任務。

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