首頁  >  文章  >  後端開發  >  crond腳本執行並發衝突怎麼解決?

crond腳本執行並發衝突怎麼解決?

零下一度
零下一度原創
2017-06-23 14:31:501365瀏覽

在計畫任務中,偶爾會看到重複執行的情況:

例如我們公司的計畫任務範例:

*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1

這是兩分鐘執行一次的任務,並不能保證每次開啟的進程能夠在兩分鐘內絕對的執行完畢關閉,進程一直堆積的話,可能會把系統資源給耗盡,導致系統宕機。

範例:

新test.php文件,程式碼如下:

<?php
sleep(70);?>

新增排程任務:

*/1 * * * * root cd /home/ganjincheng;php test.php

等待執行,發生堆積

root     26722  0.0  0.0   9232  1064 ?        Ss   12:05   0:00 /bin/sh -c cd /home/ganjincheng;php test.php
root     26744  0.0  0.0 112304  8840 ?        S    12:05   0:00 php test.php
root     29102  0.0  0.0   9232  1060 ?        Ss   12:06   0:00 /bin/sh -c cd /home/ganjincheng;php test.php
root     29116  0.1  0.0 112304  8840 ?        S    12:06   0:00 php test.php
root     29906  0.0  0.0 103320   904 pts/3    S+   12:06   0:00 grep test.php

解決方案

第一種,程式碼中控制並發

這個方法,就是對程式碼進行改造。增加是否有進程執行的判斷。如下面的程式碼:

<?php  
$lockfile = &#39;/tmp/mytest.lock&#39;;  
   
if(file_exists($lockfile)){  
    exit();  
}
file_put_contents($lockfile, date("Y-m-d H:i:s"));
   
sleep(70);
 
unlink($lockfile);  
?>

這種判斷檔案是否不存在的方式,會有一個問題。那就是有可能程式未執行到最後,也就是沒有刪除先前建立的mytest.lock檔。這會導致,之後程式將無法正常執行。

第二種,資料庫控制並發

可以將第一種方案轉移到redis,memache中,進行鍵值判斷。

如果計劃任務是對資料庫進行訪問,那可以進行鎖定表操作。偶爾我們也可以利用唯一索引與聯合索引的唯一性來避免重複插入情況

第三種,判斷進程是否存在

範例:

$fp = popen("ps aux | grep 'test.php' | wc -l", "r");
$proc_num = fgets($fp);if ($proc_num > 3) { //这里要注意为什么进程数要大于3,实际操作一遍你就明白了exit;
}
sleep(70);

這種方式有一個弊端,就是ps指令要寫的精確。避免把不是執行test.php腳本的行程也統計到。如:
我們透過vim開啟test.php檔案。就會導致上面命令誤統計。所以當我們不小心vim開啟test.php檔案的時候,就執行不起來了。

第四種,使用linux的flock指令

讓linux幫我們去判斷啊,flock指令提供了檔案鎖的功能。指令參數如下:

[root@qkzj_Multi-Purpose_1A_113.107.248.124 ganjincheng]# flock -h
flock (util-linux-ng 2.17.2)
Usage: flock [-sxun][-w #] fd#
       flock [-sxon][-w #] file [-c] command...
       flock [-sxon][-w #] directory [-c] command...  -s  --shared     Get a shared lock
  -x  --exclusive  Get an exclusive lock
  -u  --unlock     Remove a lock
  -n  --nonblock   Fail rather than wait  -w  --timeout    Wait for a limited amount of time  -o  --close      Close file descriptor before running command  -c  --command    Run a single command string through the shell  -h  --help       Display this text  -V  --version    Display version

設定範例:

*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'

 

以上是crond腳本執行並發衝突怎麼解決?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn