現在的工作中,經常要寫一些指令碼做一些非同步的操作。
一般是大量的資料修改,或者解決部分併發問題。
為了能夠穩定的做好資料處理,一般情況下會用定時指令碼的方式。
那麼問題來了。
當我們處理大量資料的時候,指令碼的執行時間可能很長,或者重複處理某條資料(寫錯的情況下)。
為了避免資料的重複處理、執行指令碼過多導致伺服器壓力過大等問題,我們需要限制指令碼的執行數量。
查詢某種標識的程序數量,如果超過一定數量,則直接退出,不處理。
記錄每次的pid,可以使用檔案
、redis
、memcached
等來儲存。
當啟動乙個新程序的時候,去查一下這個標識下面有哪些pid,是否還在執行,且與當前標識有關係。
當超過一定數量的時候,直接退出,不處理。
這裡通過linux
的ps
、grep
、wc
的命令來獲取指定標識的執行程序數。
<?php
/** * 是否可以執行
* * @param string $ident 標識
* @param integer $maxnum 最大執行數量
* * @return bool
*/function
canrun
($ident
,$maxnum
)
這裡使用redis
儲存pid
資訊。
通過/proc//cmdline
檔案檢測指定程序是否還在執行。
<?php
/** * 檢查 pid 是否存活
* * @param string $pid pid
* @param string $ident 標識
* * @return bool
*/function
issurvive
($pid
,$ident
)$cmdline
=trim
(file_get_contents
($cmdlinepath))
;// 檢查標識是否在 cmdline 中
return
strpos
($cmdline
,$ident
)!==
false;}
/** * 是否可以執行
* * @param string $ident 標識
* @param integer $maxnum 最大執行數量
* * @return bool
*/function
canrun
($ident
,$maxnum
)// 檢查 pid 是否還在執行中if(
issurvive
($pid
,$ident))
// 若不再執行,則直接刪除
unset
($pids
[$index])
;$redis
->
sremove
($key
,$pid);
}return
count
($pids
)<=
$maxnum
;}
關於標識,可能我們在執行一些定時指令碼的時候,統一的部分可能就是php
了;或者,擁有相同標識的指令碼,我們要歸為幾類。
為了能夠實現這些需求,我們可以通過php
的內建函式cli_set_process_title
來實現自定義command
。
demo.php
:
<?php
cli_set_process_title
('job demo');
sleep(10
);
這個時候,我們執行demo.php
,然後通過ps ax
可以看到如下結果:
pid user time command
1 root 0:09 php-fpm: master process (/usr/local/etc/php-fpm.conf)
7 root 0:16 php-fpm: pool www
8 root 0:15 php-fpm: pool www
9 root 0:14 php-fpm: pool www
10 root 0:00 sh
663 root 0:00 sh
690 root 0:00 job demo
691 root 0:00 ps ax
修改指定指令碼的程序標題,我們就可以實現定義某些指令碼的標識了。
沒bug
的功能,也可能出現bug
,我們需要更多的思考和設計減少這類錯誤的發生。
PHP如何限制定時任務的程序數量
現在的工作中,經常要寫一些指令碼做一些非同步的操作。一般是大量的資料修改,或者解決部分併發問題。為了能夠穩定的做好資料處理,一般情況下會用定時指令碼的方式。那麼問題來了。當我們處理大量資料的時候,指令碼的執行時間可能很長,或者重複處理某條資料 寫錯的情況下 為了避免資料的重複處理 執行指令碼過多導致...
php定時任務
php中執行定時任務有兩種情況,一種是直接在linux伺服器上直接建立cron服務,一種是在瀏覽器中執行。在linux中時間是寫死的,不能靈活變動。在瀏覽器中執行比較靈活,比如開啟乙個網頁後,從開啟此網頁開始,每十秒傳送乙個資訊到手機端 當要實現這樣的需求時,用cron服務就不太理想啦!此篇主要說一...
php 定時任務
crontab第一次使用真是個坑 crontab e 問題 第一次使用crontab 時,會出現 no crontab for root using an empty one select a editor 下面有幾個選項,就是叫你選擇編輯器。選3就可以了。如果你選錯了 可以輸入命令 select ...