一種對於多台服務器處理定時任務的方法 redis


最近要寫一個拉取其他項目數據的定時任務。

最先寫了一個,首先查詢主表,獲取主數據后,循環去拉取子數據。這種方式在同一個定時任務里,超級慢。

果斷改成多個定時任務,第一個定時任務獲取主數據存表。第二個定時任務查詢本地主表數據,循環去拉取。這種方式比在一個定時任務里快很多。

接下來說說線上出現的問題:

在跟進定時任務時,發現:1,數據沒有同步完全;2,服務器日志里報請求太頻繁。可能是其他項目的防刷機制,后來我想只是一個請求,又是定時的,沒有同時操作。

后來發現是多台服務的問題,定時到某個時間點,多台服務器會在毫秒級內一塊請求,就算是一個請求也會報頻繁。

 

解決方案:

在定時任務里加鎖機制,等某台服務器獲取權限,其他服務器將不再執行此次定時任務

if(redisTemplate.opsForValue().setIfAbsent("getsnInfo","11")){ //key的值放什么不重要,重要的是key.所以11或者aa都行。多個定時任務,是多個key,不能set一樣的,各管各的定時任務。懂redis的應該都明白
try{

// 業務代碼

  }catch(){ 
  redisTemplate.delete("getsnInfo"); 
  }
  redisTemplate.delete("getsnInfo");
}

 

注意:

異常里和方法結尾,都要加上刪除key標識。否則當系統異常退出和正常執行退出時,key還在,未來的定時任務將永遠不會被執行。

另外:redistemplate中的setIfAbsentsetnx是一樣的意思,都是不存在則set,返回boolean類型,判斷是否進入方法體。

          看你的redis使用版本和引用是哪種類型,一般都會有這兩種。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM