您好,登錄后才能下訂單哦!
這篇文章主要介紹使用Redis實現定時任務多節點部署及自動任務分發的方法,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
最近部署一個定時任務項目遇到一個問題:部署的代碼每天會定時啟動多個任務在后臺串行執行,且每個任務耗時比較長。我們的生產環境會自動開啟三個相同的節點把部署的代碼同步運行,這就導致三個節點的定時任務會重復執行,我只好強行關閉另外兩個節點,以單節點的方式串行執行定時任務。
這樣代碼是能跑起來,但是效率低且浪費了另外兩個服務器。我需要改造代碼以便能支持多節點運行,且能讓每個節點分發到不同的任務去執行。
思考過后,我借助redis實現了一個簡單的分布式定時任務,在這里記錄一下。
思路
要實現分布式,必須要使用到每個節點都能訪問到的公共變量作為全局鎖,這里我使用了redis來實現鎖。
對每個不同類的任務設置唯一的字符串鍵,當定時任務開始時,每個節點將會去遍歷任務搶占鎖,只有獲取到鎖的節點可以執行鎖對應的任務,而未獲取到鎖的節點將繼續遍歷其他任務鎖,直到所有任務鎖被獲取并執行。
示例代碼:task_manager.py
from redis import Redisfrom apscheduler.schedulers.blocking import BlockingSchedulerimport timeimport randomr = Redis(host='localhost', port=6379, db=0, decode_responses=True)TASK_LIST = ["任務參數1", "任務參數2", "任務參數3", "任務參數4"]# 存放當前已完成的集合鍵FINISHED_TASK_KEY = "task:finished"# 給每個任務順序分配不同的redis鍵TASK_KEYS = ["task: {}".format(task) for task in range(len(TASK_LIST))]# redis鍵對應的任務參數TASK_MAP = {key: task for key, task in zip(TASK_KEYS, TASK_LIST)}EXPIRE = 60 * 60 * 23# 模擬定時執行的任務,可接受不同的參數def task(param): print("----------------------------------") print("開始執行任務:{}....".format(param)) time.sleep(random.randint(15, 30)) print("完成{}".format(param)) print("----------------------------------")def start(): # 每日任務開始前先刪除redis中已完成任務集合 r.delete(FINISHED_TASK_KEY) # 添加redis中唯一任務鎖,若添加成功且任務完成表中無當前任務則執行 for key in TASK_KEYS: status = r.set(key, 1, ex=EXPIRE, nx=True) # 檢查當前任務是否已執行 is_finished = r.sismember(FINISHED_TASK_KEY, key) if status is True and is_finished is False: print("當前節點獲取任務:{} 成功, 準備執行。。".format(key)) # 獲取當前redis鍵對應的任務參數并執行任務 task_param = TASK_MAP.get(key) task(task_param) # 任務執行完成將當前任務添加到已完成集合,不允許其他節點再獲取該任務 r.sadd(FINISHED_TASK_KEY, key) r.delete(key) elif status is True and is_finished is True: print("未執行: {},其他節點已完成該任務".format(key)) else: print("未執行:{},其他節點正在執行當前任務".format(key))if __name__ == '__main__': # 這里可使用apscheduler定時任務框架調度start函數,該處模擬未使用定時任務 start()
模擬多節點運行
先同時打開三個命令行窗口,并鍵入執行命名,然后盡量相近時間點擊回車運行,模擬多節點下定時任務同時觸發的場景:
執行情況如下
模擬多節點同步運行結果
根據打印的執行情況看,整體符合預期,一個任務只能被一個節點執行,且能做到自動任務分發,執行完當前任務的節點會自動去獲取還未執行的任務,直到所有任務執行完畢。
最后
當然,以上只是一個demo,還需要處理很多異常判斷任務,任務完成情況之類的,針對不同的任務情景還可以有其他變通方法。這里只是整理一下思路和分享,希望對你也有所啟發。
以上是使用Redis實現定時任務多節點部署及自動任務分發的方法的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。