在開發的過程中,專案中使用定時器已經不是乙個新鮮的事情了,但是如果你的專案後期部署到集群環境下,如果不做處理,就會出現意想不到的問題,原因:由於我們專案同時部署在多台集群機器上,因此到達指定的定時時間時,多台機器上的定時器可能會同時啟動,造成重複資料或者程式異常等問題,下面我提供幾種解決方案
一、固定執行定時任務的機器
方法:在多台機器中選擇一台執行定時任務,每次執行的時候回判斷當前機器和指定的機器是否一致或者啟動時就指定好執行機器
優缺點:這種方法是可以有效避免多次執行的情況,,但是最明顯的缺點就是單點故障問題,如果你指定的機器出現了宕機,,任務就不會執行了,業務邏輯就會奔潰。
二、在資料庫建立多張表,從定時任務表中獲取定時方法
方法:由於mysql存在表鎖和行鎖(myisam引擎只支援表鎖,而innodb支援行鎖和表鎖兩種),每次執行定時任務的時候從資料庫表中讀取記錄,只有讀取到的記錄標識當前任務狀態為未執行時,當前機器才會去觸發任務,並且更新資料庫狀態(先更新,再執行),由於存在表鎖和行鎖,因此同一時刻只能有乙個事務操作,可以保證只執行一次
優缺點:這種方法是一種比較合適的方式,但是需要有多張表,並且已經做了定時器邏輯上會有較大的改動
三、借助redis的過期機制和分布式鎖
方法:為你的定時器在redis中定義乙個鍵值對,可以用專案名稱和伺服器ip,執行任務前先從redis中讀取鍵,若沒有值代表任務未被執行,同樣的該台機器先更新redis,再觸發定時任務。由於redis存在過期機制,因此可以設定過期時間保證下次判斷正常
四、quartz的集群應用方式
方法:如果你的專案使用的是spring自帶有task定時任務機制,quartz框架本身就是支援集群環境,可以搭建集群環境下的定時器,也能解決上述問題 不過需要配置11張資料庫表
優缺點:該解決方案最大的問題是需要配置11張左右的資料庫表,工作量非常大
分布式定時任務
在做springboot專案的時候,需要定時做對賬任務。但因為專案是集群部署,就存在多個pod例項的定時任務同時執行,存在重複性。怎麼保證集群中不重複地完成定時任務?下面給出本人總結的方案。對賬任務表 merchant idname is done 是否對賬,0沒有對賬 1商家102 商家20 3商...
redis解決分布式定時任務問題
場景分析 多伺服器針對於定時任務帶來的問題,保證任務只在乙個伺服器上在執行。解決方案1 redis bean public defaultredisscript redisscript scheduled cron 40 public void testscheduled else catch in...
集群環境下,定時任務的簡單實現
專案中新增的乙個功能是定時解綁未登入超過30天的使用者。由於生產環境下是4臺伺服器,為防止集群伺服器定時任務多次執行和提高執行成功率,設計如下功能的實現。思路 資料庫新建一張表,以當天日期 yyyymmdd 作為主鍵。定時任務入口會新增到此表一條資料,新增成功,則執行接下來的定時任務 若新增失敗被c...