一、需求
結合上一篇,使用djcelery模塊開發定時任務時,定時任務的參數都保存在djcelery_periodictask表的args、kwargs字段里,並且是json格式。那么,當定時任務多了之后,批量修改定時任務的某個參數時很草蛋,
比如,我的平台目前有100多個定時任務,定時任務的功能就是去生產數據庫里執行SQL,並將結果生成excel表,然后自動發送給相關收件人。定時任務的參數就是SQL語句、生產庫IP、收件人地址等等,當運營部門說,
我們需要在20個定時任務里增加3個人員的收件人地址,那就頭疼了,由於定時任務的所有參數都是以json格式保存在args字段里,沒法通過SQL語句批量修改,只能在頁面一個一個點!累死了!
而要實現批量修改的功能,之前想到的是以下3種:
1、通過寫腳本,先去數據庫里把args、kwargs字段的值取出來,然后一個個改,改完再回寫到djcelery_periodictask表里,但是感覺還是很繁瑣,沒有直接寫SQL語句來的簡單、靈活。(SQL寫一個單表查詢,python得寫10行)
2、使用SQL語句的json語法實現。MySQL5.7以后支持json格式字段的增刪改查,語法太復雜,拼了一整天SQL語句,放棄了。
3、拋棄djcelery模塊,基於Django + celery 重寫一個調度器來實現動態配置定時任務,並且可以使用SQL批量增刪改查。看了下djcelery源碼,算了。
現在想到了兩個個折中的辦法:
1、就是把定時任務的各個參數,單獨建表保存,然后將主表的id號保存在djcelery_periodictask表的args字段里。執行定時任務時,先通過args的字段獲取id號,再通過id去主表里查詢定時任務的各個參數,有了這些參數,就能
執行定時任務了,如果需要批量修改,直接寫SQL就能實現。
2、把djcelery_periodictask表的主鍵id號保存到args字段里,再新建表,保存定時任務的各個參數及djcelery_periodictask表的主鍵id。執行定時任務時,先獲取djcelery_periodictask表的主鍵id,再去新建表里,通過id獲取定時任務
的各個參數,這樣就能執行任務了。(我用的第二種,兩種方法原理一樣。)
二、實現方法
先看看原始的djcelery_periodictask表保存的args、kwargs字段。保存成一坨,沒辦法批量增刪改查。
現在改成,在args字段里只保存id號,注意:這個id號就是djcelery_periodictask表的主鍵id
我的定時任務主要功能是去生產庫執行SQL查詢數據,生成excel表,最后發郵件給各個收件人,所以我單獨建了四張表去保存這些參數。
主表是data_apply,通過和其它表進行關聯查詢,就能得到定時任務所需要的SQL語句、收件人、數據庫ip等等參數。而主表的djcelery_periodictask_id字段就
對應djcelery_periodictask表里的主鍵id。
因為arg字段就保存的就是djcelery_periodictask表里的主鍵id,在寫定時任務的模板函數時,通過arg獲取到djcelery_periodictask表的主鍵id后,就可以去主表data_apply里根據djcelery_periodictask_id號查詢定時任務的其它參數,
最后就可以執行后面的定時任務了。
1 @shared_task(name='fun1') 2 def fun1(_id): 3 """ 4 定義定時任務模板函數時,傳入的arg、kwargs參數,而arg里保存的是id號,通過id去主表里查詢任務參數 5 1.sql語句:select * from 主表 where djcelery_periodictask_id =_id 6 2.Django ORM 7 """ 8 9 ... ... 10 11 12 # 獲取到參數后再執行任務邏輯 13 14 ... ...
三、總結
單獨建表保存定時任務的相關參數,在對定時任務進行批量的增刪改查時更靈活,擴展也方便,但是需要一定的SQL基礎。
最理想的解決方案,還是單獨寫一個定時調度器,替代djcelery,但是難度較大。
如果會Java的話,可以使用Java的一些定時調度功能取代python celery 這塊,畢竟Java的生態圈要比python更豐富。