保證定時任務只在單個伺服器執行

2021-10-24 16:30:06 字數 1695 閱讀 3962

寫了乙個定時任務,半小時執行一次,上線之後發現12個伺服器都去執行了。

定時任務:讀取ftp檔案伺服器上某個路徑下的檔案,然後解析檔案提取每行特定列的字段,然後把符合條件的話單資料的id、手機號等資訊通過遠端介面送給第三方。由於所有伺服器都執行,導致所有伺服器差不多在1min左右先後讀取了同乙個檔案然後讀取解析把相同資料傳給第三方導致異常。

第一次修改:

定時任務加乙個判斷,先讀取伺服器ip位址,然後是特定的ip位址才可以執行,其他都不執行。方法很簡單,問題能很快處理。但是有乙個缺點,如果該台伺服器出現故障則無法執行定時任務。

第二次修改:

沒有使用redis或zk的分布式鎖,而是用資料庫的行鎖幫忙。建一張表,只有一行資料。switch欄位表示開關,決定是否開啟定時任務,start_time欄位表示最近一次定時任務開始執行的時間,status欄位表示是否加鎖防止其他伺服器再執行。

id switch start_time status

1 1  2020/10/11 21:08:00 1

假設有兩個事務a和b

事務a:

開始事務;

select * from schedule_status where id =1 for update;

update schedule_status set status= 0 where id=1;

提交事務;

事務b:

開始事務;

select * from schedule_status where id =1 for update;

update schedule_status set status= 0 where id=1;

提交事務;

如果事務a先執行了select,即使b也select到了status=1,但是事務a通過for update把該行資料鎖住(排他鎖),事務b只能查不能改。等事務a把status改為0,事務b則不能執行本次定時任務,等待下次時間點再爭奪。

至於‍start_time欄位是防止某台伺服器在執行完定時任務之後在恢復status為1時出現了故障,所以需要每次執行定時任務時,遇到status為0之後,再通過當前時間-start_time是否超時30min左右,如果超時我們可以認為上次執行定時任務的伺服器宕機之類的,此時我們接著返回true讓先發現這個故障的伺服器先執行,並且同時更新一下對應start_time。這樣即使節點掛掉,也不影響下一次定時任務的執行。

如果使用分布式鎖,需要給分布鎖加乙個超時時間,防止加鎖後再解鎖時出現故障,後面任務不再執行。再使用quartz元件來處理,也可以讓定時任務在伺服器集群下只需要讓集群中的一台執行。

北部白犀牛

北部白犀牛和南部白犀牛同屬白犀亞種,與非洲南部的白犀在基因上存在較大差異。2023年3月19日,世界上最後一頭雄性北方白犀牛「蘇丹」在肯亞去世,終年45歲。

儘管犀牛角的交易在全球範圍內被禁止,但在黑市內仍然熱火朝天,在葉門就有專門的犀牛角市場,在那裡以犀牛角製成手柄的匕首是眾多買家和賣家關注的焦點,是身份的象徵。利益薰心的偷獵者每年都大量獵殺這些珍貴的白犀,而面對偷獵猖獗,非洲國家由於落後的經濟技術無暇應對,這些問題已經導致北白犀成為即將滅絕在現代文明面前的大型動物。

在伺服器上配置linux定時任務

想在迭代群配置個定時提醒站會,打包的機械人,於是想到了在linux下配置個定時任務,查下資料,決定使用crontab 1 編寫qa zhanhui.sh指令碼,直接vi qa zhanhui.sh這個指令碼編輯儲存即可 2 配置crontab 檢視配置的定時任務 crontab e eg 0 5 r...

window2008伺服器定時任務

1.建立 bat 字尾檔案 d soft php package php5.5 php.exe c d soft php package php5.5 php.ini q d wwwroot chosetel fukuan ds.php 2.ds.php 應用入口檔案 檢測php環境 if vers...

PHP利用伺服器實現定時任務

利用伺服器實現簡單的定時任務,windows的計畫任務,linux的cron,適用於每天某一特點時間執行 windows下用定時任務執行auto.php檔案,auto.php檔案裡用curl請求指定的介面實現 auto.php 如下 function docurlgetrequest timeout...