shell腳本作為保證PHP腳本不掛掉的守護(hù)進(jìn)程實(shí)例分享
前幾天開(kāi)始跑一份數(shù)據(jù)名單,名單需要提供用戶(hù)名、是否有手機(jī)號(hào)、是否有郵箱,用戶(hù)名單我輕易的獲取到了,但是,用戶(hù)名單有2000w之多,并且去檢測(cè)用戶(hù)是否有手機(jī)號(hào)、是否有郵箱必須得通過(guò)一個(gè)對(duì)外開(kāi)放的安全接口一個(gè)一個(gè)用戶(hù)去請(qǐng)求,然后分析返回值才能知道。
下面是我處理的方案:
1、將2000w名單保存到臨時(shí)數(shù)據(jù)表
2、用PHP程序每次從該表獲取500個(gè)用戶(hù),檢測(cè)完后生成SQL update原紀(jì)錄
3、為了防止PHP程序突然斷掉,用shell腳本每隔1分鐘檢測(cè),PHP掛掉了則重啟
我使用shell腳本作為守護(hù)進(jìn)程的原因是,手機(jī)與郵箱的檢測(cè)接口速度慢,不可能在1~2天將2000w用戶(hù)檢測(cè)完。
方案詳細(xì):
1、臨時(shí)保存用戶(hù)名單表users,表結(jié)構(gòu)如下:
CREATE TABLE `users` (
`account` varchar(50) COMMENT '用戶(hù)名',
`has_phone` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有手機(jī)號(hào)',
`has_email` tinyint(3) unsigned NOT NULL default '0' COMMENT '是否有郵箱',
`flag` tinyint(3) unsigned NOT NULL default '0' COMMENT '標(biāo)志位',
PRIMARY KEY (`account`),
KEY `flag` (`flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='名單表';
我先將2000多w用戶(hù)名導(dǎo)入到這個(gè)臨時(shí)表,has_phone與has_email這二個(gè)字段默認(rèn)都是0(沒(méi)有),標(biāo)志位flag說(shuō)明該用戶(hù)是否已經(jīng)檢測(cè)完。
下面是一部分表數(shù)據(jù):
9873aaa,0,0,0
adddwwwd876222,0,0,0
testalexlee,0,0,0
codejia.net,0,0,0
haohdouywaa21,0,0,0
2、PHP腳本check_users.php
將 用戶(hù)名單導(dǎo)入到表之后,再寫(xiě)一個(gè)簡(jiǎn)單的PHP腳本,思路是這樣的:每次循環(huán)從表取flag=0的500個(gè)用戶(hù),然后請(qǐng)求接口判斷用戶(hù)是否有手機(jī)號(hào)、郵箱, 生成一條SQL,保存到一個(gè)SQLS數(shù)組里,等500個(gè)用戶(hù)全部檢測(cè)完了之后,循環(huán)SQLS數(shù)組,更新表里這500個(gè)名單,并將flag標(biāo)志位設(shè)置為1, 表示已經(jīng)檢測(cè)完,下次就不獲取了。
由于PHP腳本代碼較長(zhǎng),這里分享下簡(jiǎn)單的代碼說(shuō)明:
<?php
class Users{
private $data;
private $sqls;
private $nums; //判斷是否有500用戶(hù)
private $total_nums; //當(dāng)前已經(jīng)檢測(cè)完的用戶(hù)數(shù)量
//每次取500個(gè)用戶(hù)
private function getUsers(){...}
//檢測(cè)這500個(gè)用戶(hù)并生成SQL
private function checkUserInfo(){...}
//更新這500個(gè)用戶(hù)
private function updateUserInfo(){...}
//運(yùn)行
public function run(){
$flag = true;
while($flag){
if($this->nums != 500){ $flag = false; }
if($this->total_nums == 10000){
exit(0); //跑完1w個(gè)用戶(hù)就退出,由守護(hù)進(jìn)程啟動(dòng)
}
$this->getUsers();
$this->checkUserInfo();
$this->updateUserInfo();
sleep(1); //跑完500用戶(hù)休息1秒,保護(hù)用戶(hù)檢測(cè)接口
}
}
}
$user = new Users();
$user->run();
?>
上面是簡(jiǎn)潔版的PHP腳本,大概意思到了,剛開(kāi)始的版本是沒(méi)有$total_nums這個(gè)變量,是因?yàn)閯傞_(kāi)始跑這個(gè)腳本的時(shí)候,發(fā)現(xiàn)只跑完了4w多條腳本就掛球了,后來(lái)一看,是因?yàn)檫B接數(shù)據(jù)庫(kù)沒(méi)連上,腳本一直掛在那里。加上這個(gè)變量也無(wú)法解決這個(gè)問(wèn)題,只是在每次跑完1w個(gè)用戶(hù)之后,PHP腳本退出,再由下面的shell腳本重新啟動(dòng)。
3、shell腳本作為守護(hù)進(jìn)程
我把這個(gè)shell腳本加到了crontab里邊,每隔1分鐘執(zhí)行一次,這個(gè)shell腳本很簡(jiǎn)單,檢測(cè)check_users.php是否存在進(jìn)程id,如果存在,則說(shuō)明PHP腳本還在運(yùn)行,shell腳本不做任何操作;如果不存在,則說(shuō)明PHP腳本已經(jīng)exit(0)跑完了1w用戶(hù)退出了,那么shell腳本啟動(dòng)該腳本,進(jìn)入下一個(gè)1w用戶(hù)名單的檢測(cè)。
上面我有講到,如果PHP腳本在連接數(shù)據(jù)庫(kù)的時(shí)候,無(wú)法連接上的時(shí)候,PHP會(huì)一直掛球在那里,無(wú)法退出了。我在shell腳本里加了一個(gè)時(shí)間檢測(cè),當(dāng)PHP腳本進(jìn)程存在的時(shí)候,計(jì)算已經(jīng)存在了多長(zhǎng)時(shí)間,如果超過(guò)了我預(yù)想的時(shí)間,則將PHP腳本kill掉,再重啟。
開(kāi)頭的舉例數(shù)據(jù),結(jié)果類(lèi)似如下:
testalexlee,1,0,1
codejia.net,0,0,1
haohdouywaa21,1,1,1
9873aaa,0,1,1
adddwwwd876222,1,0,1
說(shuō)在最后:以上用戶(hù)名單數(shù)據(jù)只是舉個(gè)栗子,不要太認(rèn)真,2000w數(shù)據(jù),我估計(jì)要跑一段時(shí)間了,因?yàn)闄z測(cè)接口比較慢,接口在接到請(qǐng)求后還要連表,查表,再返回。其實(shí),最好的方法還是直接從接口請(qǐng)求的表拉一份名單出來(lái),再用shell命令處理下很快就有結(jié)果了,可是在公司就是這樣,有些東西不開(kāi)放的,你懂的~~~
- PHP擴(kuò)展程序?qū)崿F(xiàn)守護(hù)進(jìn)程
- PHP將進(jìn)程作為守護(hù)進(jìn)程的方法
- PHP守護(hù)進(jìn)程實(shí)例
- PHP高級(jí)編程實(shí)例:編寫(xiě)守護(hù)進(jìn)程
- PHP實(shí)現(xiàn)多進(jìn)程并行操作的詳解(可做守護(hù)進(jìn)程)
- PHP程序級(jí)守護(hù)進(jìn)程的實(shí)現(xiàn)與優(yōu)化的使用概述
- php守護(hù)進(jìn)程 加linux命令nohup實(shí)現(xiàn)任務(wù)每秒執(zhí)行一次
- 詳解PHP解決守護(hù)進(jìn)程Redis假死
相關(guān)文章
為Plesk PHP7啟用Oracle OCI8擴(kuò)展方法總結(jié)
在本篇文章里小編給大家總結(jié)了關(guān)于為Plesk PHP7啟用Oracle OCI8擴(kuò)展方法和相關(guān)代碼,需要的朋友們學(xué)習(xí)下。2019-03-03PHP實(shí)現(xiàn)的消息實(shí)時(shí)推送功能【基于反ajax推送】
這篇文章主要介紹了PHP實(shí)現(xiàn)的消息實(shí)時(shí)推送功能,結(jié)合實(shí)例形式分析了php基于反ajax推送實(shí)現(xiàn)的消息實(shí)時(shí)推送前臺(tái)ajax提交、后臺(tái)數(shù)據(jù)處理等相關(guān)操作技巧,需要的朋友可以參考下2018-03-03php中的注釋、變量、數(shù)組、常量、函數(shù)應(yīng)用介紹
本文將詳細(xì)介紹php中的注釋、變量、數(shù)組、常量、函數(shù)應(yīng)用,需要的朋友可以參考下2012-11-11PHP連接及操作PostgreSQL數(shù)據(jù)庫(kù)的方法詳解
這篇文章主要介紹了PHP連接及操作PostgreSQL數(shù)據(jù)庫(kù)的方法,結(jié)合實(shí)例形式分析了php針對(duì)PostgreSQL數(shù)據(jù)庫(kù)的基本連接以及增刪改查等相關(guān)操作技巧,需要的朋友可以參考下2019-01-01PHP實(shí)現(xiàn)模仿socket請(qǐng)求返回頁(yè)面的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)模仿socket請(qǐng)求返回頁(yè)面的方法,是socket通信非常實(shí)用的技巧,需要的朋友可以參考下2014-11-11提高define性能的php擴(kuò)展hidef的安裝和使用
在apache啟動(dòng)前,PHP啟動(dòng)時(shí)創(chuàng)建并初始化了這些常量,這樣就不需要在php里define常量了,性能自然沒(méi)有任何問(wèn)題了!2011-06-06