前言
老黃前段時間遇到了一個資料清洗的需求,其實就是每天淩晨把昨天的資料清洗一遍,歸歸類。
這是一個比較典型的定時任務的處理場景。
定時任務可以說就一把利器,幾乎每個公司都離不開,它的應用場景也不在少數,比如:
- 生成前一天的統計資料
- 每隔幾天清理一次日志
- 定期處理失效的單據
- ...
對于定時任務,常見的解決方案有下面幾種
- quartz.net
- hangfire
- xxl-job
- saturn
對于1和2,無疑是要投入學習成本的,要習慣它們的用法,不好的地方就是不能讓開發人員集中精力去處理業務上面的内容。
對于3和4,這兩個算是分布式任務排程的平台,很好的與業務解耦了,可以通過HTTP的接口來觸發任務的執行。
3和4想在生産環境高可用,離不開叢集部署,在資源緊張的時候其實想部署這麼一套東西其實還是挺不容易的。
對于上面的幾種方案,老黃都沒有采用,卻而代之的是k8s的cronjob。
為什麼選擇cronjob
上面提到的幾種方案,也已經表達了不選用的原因了,無非就是成本和複雜度,下面來講講選擇k8s的cronjob的原因吧。
首先k8s的cronjob本身就可以當作是一個任務排程的平台了,排程的時候會建立一個POD來執行我們的任務。
其次的話,沒有複雜的依賴關系,隻要編寫一個簡單的控制台程式就好了。
還有一個是成本問題,老黃公司用的k8s是serverless的,沒有實實在在的伺服器資源,傳遞的隻是鏡像,執行這些定時任務,都是按時間計費的。
1C2G的配置隻要0.00006126塊錢一秒,假設你的任務執行要3分鐘,那這一次任務隻要1毛錢就可以了。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL4kjN5cTM4YDNtEDN5ATN1IDOwMjMxEDMyAjMtUDN5gTN18CXxEDMyAjMvwVN0kDO1UzLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
選擇什麼配置,最後要看的還是你業務的需要。
說了這麼多,來個僞例子吧。
簡單例子
要先準備一下我們的任務内容,其實就是寫個簡單的控制台程式。
using System; internal class Program { private static void Main(string[] args) { // 寫這個定時任務要處理的内容 Console.WriteLine($"Hello World! {a}"); } }
這裡有一個要注意的是,不要出現
Console.ReadLine
,
Console.ReadKey
之類的東西,不然是run不起來的。
Dockerfile就不寫了,隻要能把這個控制台程式打包成一個鏡像,可以run起來就可以了。
後面就是寫cronjob的配置了。
apiVersion: batch/v1beta1 kind: CronJob metadata: labels: etl: diagnosis name: xyzxyz namespace: prod spec: # 禁止并發運作 concurrencyPolicy: Forbid failedJobsHistoryLimit: 1 jobTemplate: metadata: {} spec: # 指定存活時長 activeDeadlineSeconds: 1200 # 指定失敗時可以重試2次 backoffLimit: 2 completions: 1 parallelism: 1 template: spec: containers: - env: - name: DOTNET_RUNNING_IN_CONTAINER value: 'true' - name: TZ value: Asia/Shanghai image: >- xxxxx:5000/xxxxx:version imagePullPolicy: IfNotPresent name: xyzxyz ports: - containerPort: 80 protocol: TCP resources: # 這裡隻用了0.25C 0.5G requests: cpu: 250m memory: 512Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Never schedulerName: default-scheduler # cron表達式, schedule: 22 4 1/1 * ? # 成功job曆史顯示個數 successfulJobsHistoryLimit: 1
裡面的配置其實還是挺多的,對老黃的場景來說,上面的配置足夠了,對更多的配置,可以參考k8s的官網。
執行
kubectl apply -f xxx.yml
就可以建立定時任務了,後面就會自動排程執行對應的任務了。
這裡就不執行了,直接拿線上正在跑的三個定時任務給大家參考一下。
點詳情可以看到具體的執行情況。
寫在最後
定時任務這個問題的答案有很多種解法,可以選擇适合公司的最優解。
因為每種解法都有它好或者不好的地方,k8s的cronjob也是有它不足的地方的,最為明顯的就是cron表達式第1位是分鐘而不是秒,也就是說最小粒度隻到分鐘,如果你的應用需要到秒的,可能就沒辦法支援到了。
如果您認為這篇文章還不錯或者有所收獲,可以點選右下角的【推薦】按鈕,因為你的支援是我繼續寫作,分享的最大動力!
作者:Catcher Wong ( 黃文清 )
來源:http://catcher1994.cnblogs.com/
聲明:
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。如果您發現部落格中出現了錯誤,或者有更好的建議、想法,請及時與我聯系!!如果想找我私下交流,可以私信或者加我微信。