结合控制台程序和K8S的CronJob完成定时任务
前言
老黃前段時間遇到了一個數(shù)據(jù)清洗的需求,其實就是每天凌晨把昨天的數(shù)據(jù)清洗一遍,歸歸類。
這是一個比較典型的定時任務的處理場景。
定時任務可以說就一把利器,幾乎每個公司都離不開,它的應用場景也不在少數(shù),比如:
生成前一天的統(tǒng)計數(shù)據(jù)
每隔幾天清理一次日志
定期處理失效的單據(jù)
...
對于定時任務,常見的解決方案有下面幾種
quartz.net
hangfire
xxl-job
saturn
...
對于1和2,無疑是要投入學習成本的,要習慣它們的用法,不好的地方就是不能讓開發(fā)人員集中精力去處理業(yè)務上面的內(nèi)容。
對于3和4,這兩個算是分布式任務調(diào)度的平臺,很好的與業(yè)務解耦了,可以通過HTTP的接口來觸發(fā)任務的執(zhí)行。
3和4想在生產(chǎn)環(huán)境高可用,離不開集群部署,在資源緊張的時候其實想部署這么一套東西其實還是挺不容易的。
對于上面的幾種方案,老黃都沒有采用,取而代之的是k8s的cronjob。
為什么選擇cronjob
上面提到的幾種方案,也已經(jīng)表達了不選用的原因了,無非就是成本和復雜度,下面來講講選擇k8s的cronjob的原因吧。
首先k8s的cronjob本身就可以當作是一個任務調(diào)度的平臺了,調(diào)度的時候會創(chuàng)建一個POD來執(zhí)行我們的任務。
其次的話,沒有復雜的依賴關系,只要編寫一個簡單的控制臺程序就好了。
還有一個是成本問題,老黃公司用的k8s是serverless的,沒有實實在在的服務器資源,交付的只是鏡像,執(zhí)行這些定時任務,都是按時間計費的。
1C2G的配置只要0.00006126塊錢一秒,假設你的任務執(zhí)行要3分鐘,那這一次任務只要1毛錢就可以了。
選擇什么配置,最后要看的還是你業(yè)務的需要。
說了這么多,來個偽例子吧。
簡單例子
要先準備一下我們的任務內(nèi)容,其實就是寫個簡單的控制臺程序。
using?System;internal?class?Program {private?static?void?Main(string[]?args){//?寫這個定時任務要處理的內(nèi)容Console.WriteLine($"Hello?World!??{a}");} }這里有一個要注意的是,不要出現(xiàn) Console.ReadLine, Console.ReadKey之類的東西,不然是run不起來的。
Dockerfile就不寫了,只要能把這個控制臺程序打包成一個鏡像,可以run起來就可以了。
后面就是寫cronjob的配置了。
apiVersion:?batch/v1beta1 kind:?CronJob metadata:labels:etl:?diagnosisname:?xyzxyznamespace:?prod spec:#?禁止并發(fā)運行concurrencyPolicy:?ForbidfailedJobsHistoryLimit:?1jobTemplate:metadata:?{}spec:#?指定存活時長activeDeadlineSeconds:?1200#?指定失敗時可以重試2次backoffLimit:?2completions:?1parallelism:?1template:spec:containers:-?env:-?name:?DOTNET_RUNNING_IN_CONTAINERvalue:?'true'-?name:?TZvalue:?Asia/Shanghaiimage:?>-xxxxx:5000/xxxxx:versionimagePullPolicy:?IfNotPresentname:?xyzxyzports:-?containerPort:?80protocol:?TCPresources:#?這里只用了0.25C?0.5Grequests:cpu:?250mmemory:?512MiterminationMessagePath:?/dev/termination-logterminationMessagePolicy:?FilednsPolicy:?ClusterFirstrestartPolicy:?NeverschedulerName:?default-scheduler#?cron表達式,schedule:?22?4?1/1?*??#?成功job歷史顯示個數(shù)successfulJobsHistoryLimit:?1里面的配置其實還是挺多的,對老黃的場景來說,上面的配置足夠了,對更多的配置,可以參考k8s的官網(wǎng)。
執(zhí)行kubectl apply -f xxx.yml 就可以創(chuàng)建定時任務了,后面就會自動調(diào)度執(zhí)行對應的任務了。
這里就不執(zhí)行了,直接拿線上正在跑的三個定時任務給大家參考一下。
點詳情可以看到具體的執(zhí)行情況。
寫在最后
定時任務這個問題的答案有很多種解法,可以選擇適合公司的最優(yōu)解。
因為每種解法都有它好或者不好的地方,k8s的cronjob也是有它不足的地方的,最為明顯的就是cron表達式第1位是分鐘而不是秒,也就是說最小粒度只到分鐘,如果你的應用需要到秒的,可能就沒辦法支持到了。
總結
以上是生活随笔為你收集整理的结合控制台程序和K8S的CronJob完成定时任务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 中的本地函数
- 下一篇: 一个情怀引发的生产事故