好多系統中會用到郵件系統,咱們假設有一個 PHP 腳本用來發送郵件。使用 Linux cron 每分鐘執行一次php
咱們暫時不引入隊列系統,其實使用隊列處理此方式更優。shell
咱們獲得下面的基本配置bash
* * * * * php /home/app/email.php
複製代碼
假設因爲未知因素, email.php
腳本一直執行,沒有退出。極端的狀況,進入一個 while 死循環。app
這下倒好,原來講好的一分鐘執行一次,如今一直死這邊了,後面的腳本也不能跑了測試
解決辦法:ui
使用 timeout,假設咱們設定每一個腳本最多執行時間位 200秒,超過 200秒 就自動死掉。this
* * * * * timeout 200 php /home/app/email.php
複製代碼
php email.php
,若是避免重複執行?這樣會出現,有兩個進程同時在執行 php email.php
,那會不會出現同一個任務被執行了兩次?spa
解決辦法:日誌
使用 flock 進行互斥控制code
用法:
flock [選項] <文件|目錄> <命令> [<參數>...]
flock [選項] <文件|目錄> -c <命令>
flock [選項] <文件描述符號碼>
經過 shell 腳本管理文件鎖。
選項:
-s, --shared 獲取共享鎖
-x, --exclusive 獲取排他鎖(默認)
-u, --unlock 移除鎖
-n, --nonblock 失敗而非等待
-w, --timeout <秒> 等待限定的時間
-E, --conflict-exit-code <數字> 衝突或超時後的退出代碼
-o, --close 運行命令前關閉文件描述符
-c, --command <命令> 經過 shell 運行單個命令字符串
-F, --no-fork 執行命令時不 fork
--verbose 增長詳盡程度
-h, --help display this help
-V, --version display version
複製代碼
咱們用到其中的排他設置
* * * * * flock -xn /tmp/test.lock -c "timeout 200 php /home/app/email.php"
複製代碼
定時任務可能要記錄日誌呀,否則後期怎麼排查
* * * * * flock -xn /tmp/test.lock -c "timeout 200 php /home/app/email.php >> /home/log/test.log 2>&1"
複製代碼
* * * * * flock -xn /tmp/test.lock -c "timeout 200 php /home/app/email.php >> /home/log/test.log 2>&1"
複製代碼
我以爲一分鐘一次頻率過低,想 10s 執行一次怎麼辦?
* * * * * php /home/app/email.php >> /home/log/test.log 2>&1
* * * * * ( sleep 10 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 20 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 30 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 40 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
* * * * * ( sleep 50 ; php /home/app/email.php >> /home/log/test.log 2>&1 )
複製代碼
準備一個 php 腳本 /home/rovast/Code/flock/test.php
<?php
$i = 10000;
while ($i > 0) {
echo --$i . \PHP_EOL;
sleep(1);
}
複製代碼
執行
flock -xn /tmp/mytest.lock -c "timeout 30 php /home/rovast/Code/flock/test.php"
複製代碼
咱們看到終端不停輸出數值
9999
9998
9997
9996
9995
9994
9993
9992
9991
9990
複製代碼
咱們再打開另一個終端,執行
flock -xn /tmp/mytest.lock -c "timeout 30 php /home/rovast/Code/flock/test.php"
複製代碼
咱們發現: