防止 crontab 定時任務重複執行

2021-10-06 08:35:55 字數 2510 閱讀 1805

前言:

crontab 定時任務很好使用,它的定時是很強硬的,直接跟系統時間打交道,不會去管程式本身執行是否需要時間。

舉個栗子:

乙個指令碼執行需要 1 小時,使用 crontab 每隔2小時執行一次,一般情況下下次執行指令碼時上次指令碼執行肯定是跑完了的;但是,假如,程式卡住了呢?下次執行時上次指令碼還在,會咋樣?會再啟動乙個指令碼,這時候就有兩個指令碼在執行,如果產生衝突會把事情搞得更複雜。

咋整?

1.flock 來幫忙

直接在 linux 輸入 flock 命令,就會獲取使用說明:

usage:

flock [options] [command args]

flock [options] -c flock [options] options:

-s --shared get a shared lock(獲得共享鎖)

-x --exclusive get an exclusive lock (default)(獲得排他鎖)

-u --unlock remove a lock(移除鎖)

-n --nonblock fail rather than wait(不能獲得鎖就直接失敗而不是等待)

-w --timeout wait for a limited amount of time(如果沒有立即獲得鎖,等待指定時間)

-e --conflict-exit-code exit code after conflict or timeout(衝突或超時後的退出**)

-o --close close file descriptor before running command(在執行命令前關閉檔案的描述符號。用於如果命令產生子程序時會不受鎖的管控)

-c --command run a single command string through the shell(通過 shell 執行一條命令)

-h, --help display this help and exit(顯示幫助並退出)

-v, --version output version information and exit(輸出版本資訊並退出)

怎麼解決前言提到的問題?你看 -x 引數,排他鎖就是獨佔嘍,你再看-n引數,得不到就退出

如果我們執行指令碼的時候用 -x 獨佔乙個檔案的鎖,然後再加上-n引數(下次執行時如果上次執行沒完成獨佔鎖肯定不會釋放,所以肯定沒法獲取鎖,就不會再重複執行指令碼了)

2.舉個例子

先寫乙個定時命令

*/1 * * * * flock -xn /home/cron_test.py -c 'cd /home/;python -u cron_test.py >> test.log 2>&1 &'
解釋一下:

每隔一分鐘,在使用獨佔鎖鎖定 cron_test.py 檔案的基礎上,後台執行 cron_test.py 指令碼,並把結果列印到 test.log

cron_test.py 指令碼如下

import time

if __name__ == '__main__':

count = 0

print count

結果:

test.log 會每隔 1 分鐘列印乙個0,這個和普通定時沒啥區別

換指令碼

import time

if __name__ == '__main__':

count = 0

while true:

print count

time.sleep(120)

count = count + 1

指令碼加了乙個 2 分鐘的延遲,也就是說下次執行的時候上次執行的指令碼肯定沒完成,定時命令不變,等三五分鐘,檢視一下進行,命令如下

ps -ef | grep cron_test
結果:

root       676 20001  0 19:41 pts/0    00:00:00 grep --color=auto cron_test

root 30904 1 0 19:39 ? 00:00:00 /home/anaconda2/bin/python -u cron_test.py

如果 flock 沒生效的話,這時候 ps 應該會有很多個執行指令碼的程序,但是上面確實只有乙個執行指令碼的進行,也就是指令碼只執行了一次,同時test.log日誌如下:

012

345

並沒有指令碼重新執行列印的 0

3.tips

鎖定的檔案沒有啥特殊的要求,可以使用指令碼檔案,也可以隨便建乙個。

這種方式也可以用於守護程序。

集群環境下如何防止定時任務重複執行?

起因 最近做專案是遇到這樣乙個問題 系統需要在每天的16 00向一些符合特定條件的使用者傳送乙份郵件,傳送成功後修改掉資料庫中對應資料的標誌位。本來是沒有問題的,但後來系統被部署到了集群環境下,導致每天會向這些使用者傳送多次同樣的資料,遭到了客戶的抱怨。解決 下面來介紹一下處理這種問題的解決辦法 1...

集群環境下如何防止定時任務重複執行?

起因 最近做專案是遇到這樣乙個問題 系統需要在每天的16 00向一些符合特定條件的使用者傳送乙份郵件,傳送成功後修改掉資料庫中對應資料的標誌位。本來是沒有問題的,但後來系統被部署到了集群環境下,導致每天會向這些使用者傳送多次同樣的資料,遭到了客戶的抱怨。解決 下面來介紹一下處理這種問題的解決辦法 1...

crontab定時任務

今天工作項有個任務是讓ubuntu定時執行某個指令碼,對postgresql資料庫進行定時備份。linux 系統都有個cron定時任務的機制。今天做些筆記,以便日後翻查。注意 cron機制是有個使用者系統的概念的,即分系統cron和使用者cron,每個使用者所執行的cron任務可能不同。1.以roo...