结合控制台程序和K8S的CronJob完成定时任务

前言

老黄前段时间遇到了一个数据清洗的需求,其实就是每天凌晨把昨天的数据清洗一遍,归归类。

这是一个比较典型的定时任务的处理场景。

定时任务可以说就一把利器,几乎每个公司都离不开,它的应用场景也不在少数,比如:

  1. 生成前一天的统计数据

  2. 每隔几天清理一次日志

  3. 定期处理失效的单据

  4. ...

对于定时任务,常见的解决方案有下面几种

  1. quartz.net

  2. hangfire

  3. xxl-job

  4. saturn

  5. ...

对于1和2,无疑是要投入学习成本的,要习惯它们的用法,不好的地方就是不能让开发人员集中精力去处理业务上面的内容。

对于3和4,这两个算是分布式任务调度的平台,很好的与业务解耦了,可以通过HTTP的接口来触发任务的执行。

3和4想在生产环境高可用,离不开集群部署,在资源紧张的时候其实想部署这么一套东西其实还是挺不容易的。

对于上面的几种方案,老黄都没有采用,取而代之的是k8s的cronjob。

为什么选择cronjob

上面提到的几种方案,也已经表达了不选用的原因了,无非就是成本和复杂度,下面来讲讲选择k8s的cronjob的原因吧。

首先k8s的cronjob本身就可以当作是一个任务调度的平台了,调度的时候会创建一个POD来执行我们的任务。

其次的话,没有复杂的依赖关系,只要编写一个简单的控制台程序就好了。

还有一个是成本问题,老黄公司用的k8s是serverless的,没有实实在在的服务器资源,交付的只是镜像,执行这些定时任务,都是按时间计费的。

1C2G的配置只要0.00006126块钱一秒,假设你的任务执行要3分钟,那这一次任务只要1毛钱就可以了。

选择什么配置,最后要看的还是你业务的需要。

说了这么多,来个伪例子吧。

简单例子

要先准备一下我们的任务内容,其实就是写个简单的控制台程序。

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: diagnosisname: xyzxyznamespace: prod
spec:# 禁止并发运行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历史显示个数successfulJobsHistoryLimit: 1

里面的配置其实还是挺多的,对老黄的场景来说,上面的配置足够了,对更多的配置,可以参考k8s的官网。

执行kubectl apply -f xxx.yml 就可以创建定时任务了,后面就会自动调度执行对应的任务了。

这里就不执行了,直接拿线上正在跑的三个定时任务给大家参考一下。

点详情可以看到具体的执行情况。

写在最后

定时任务这个问题的答案有很多种解法,可以选择适合公司的最优解。

因为每种解法都有它好或者不好的地方,k8s的cronjob也是有它不足的地方的,最为明显的就是cron表达式第1位是分钟而不是秒,也就是说最小粒度只到分钟,如果你的应用需要到秒的,可能就没办法支持到了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——图-有向带权图的邻接表基础

#include <stdio.h> #include <stdlib.h> #define VertexType char //顶点的数据类型&#xff08;char&#xff09; #define VertexMax 20 //最大顶点个数 typedef struct ArcNode//边表 {int adjvex;//存储的是该顶点在顶点数组即AdjList[]中的位置int weight; …

vs里面mfc是什么_最近!一大批人正在前往文安,究竟发生了什么?

阅读本文前&#xff0c;请您先点击上面蓝色字体“文安家乡群”再点击“关注”&#xff0c;这样您就可以加入文安家乡群了。最近&#xff0c;文安的火车站汽车站&#xff0c;来了一大批外地人&#xff0c;挤爆了文安车站…究竟发生了什么事儿&#xff1f;让这么多人蜂拥而至&…

html 去除max-height,HTML Style maxHeight用法及代码示例

maxHeight属性设置/返回元素的最大高度。 maxHeight属性仅影响block-level元素&#xff0c;绝对或固定位置元素。用法:它用于设置maxHeight属性&#xff1a;object.style.maxHeight "none|length|%|initial|inherit"它用于返回maxHeight属性&#xff1a;object.styl…

数据结构——图-有向带权图的邻接表

#include <stdio.h> #include <stdlib.h> #define VertexType char //顶点的数据类型&#xff08;char&#xff09; #define VertexMax 20 //最大顶点个数 typedef struct ArcNode//边表 {int adjvex;//存储的是该顶点在顶点数组即AdjList[]中的位置int weight; …

ASP.NET Core使用HostingStartup增强启动操作

概念在ASP.NET Core中我们可以使用一种机制来增强启动时的操作&#xff0c;它就是HostingStartup。如何叫"增强"操作&#xff0c;相信了解过AOP概念的同学应该都非常的熟悉。我们常说AOP使用了关注点分离的方式&#xff0c;增强了对现有逻辑的操作。而我们今天要说的…

计算机网络实验arp协议分析,计算机网络ARP地址协议解析实验报告

计算机网络ARP地址协议解析实验报告 (5页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;9.9 积分计算机网络实验报告、实验目的:1. 掌握ARP协议的报文格式2. 掌握ARP协议的工作原理3. 理解ARP高速缓存…

数据结构——图-最短路径长度中最大的一个

#include<stdio.h> #include<string.h> #define INF 32767 #define MAXVEX 30 int dist[MAXVEX]; //建立dist数组int path[MAXVEX]; //建立path数组int S[MAXVEX]; //建立S数组typedef char VertexType;typedef struct graph {int n,e;VertexType vexs[MAXVE…

一个情怀引发的生产事故

在一个项目中&#xff0c;需要轻量级用到脚本语言&#xff0c;来提高应用服务的灵活性。因为知道Roslyn可以动态编辑C#&#xff0c;本着情怀&#xff0c;就自然用Roslyn来处理这块业务了。开在windows上执行&#xff0c;一次调用风平浪静&#xff0c;因为这个功能使用频次不高&…

python standardscaler_教你用python一步步解决“维度灾难”

全文共7016字&#xff0c;预计学习时长40分钟或更长现代科技时代产生和收集的数据越来越多。然而在机器学习中&#xff0c;太多的数据可不是件好事。某种意义上来说&#xff0c;特征或维度越多&#xff0c;越会降低模型的准确性&#xff0c;因为需要对更多的数据进行泛化——这…

c++的输入和输出

1. 输入/输出流的成员函数 put()函数 put函数常用的调用形式&#xff1a; cout.put(char ch); 功能&#xff1a;用于输出一个字符&#xff0c;还可以是ASCII代码&#xff08;或者是ASCII表达式&#xff09; cout.put(65)&#xff1b; get()函数 常用形式为&#xff1a;cin.g…

被 C# 的 ThreadStatic 标记的静态变量,都存放在哪里了?

一&#xff1a;背景 1. 讲故事前几天公号里有一位朋友留言说&#xff0c;你windbg玩的溜&#xff0c;能帮我分析下被 ThreadStatic 修饰的变量到底存放在哪里吗&#xff1f;能不能帮我挖出来????????????&#xff0c;其实这个问题问的挺深的&#xff0c;玩高级语言…

唐山师范学院计算机论文,唐山师范学院校园网络解决方案 毕业论文

唐山师范学院校园网络解决方案 毕业论文 (43页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;9.90 积分1 唐山师范学院 专 科毕业论文 题 目 唐山师范学院校园网络解决方案 学 生 指导教师 年 级 200…

基本系统设备感叹号更新不了_电脑识别不了U盘?别紧张,免费教你如何解决...

你的电脑会出现识别不了U盘的情况吗&#xff1f;为什么会识别不了U盘你了解过吗&#xff1f;首先我们说一下&#xff0c;U盘作为一个办公必备品&#xff0c;用来存储文件以便随时使用&#xff0c;简单方便。但是如果某一天你的电脑突然之间无法识别U盘的话&#xff0c;就代表新…

群同态基本定理证明_群论(7): 群代数, 群表示基础

内容提要:1 群代数; 2 域上的有限维群代数和Maschke定理; 3 函数环; 4 代数闭域上的群表示论; 本文主要参考文献.本文的前置内容为:格罗卜&#xff1a;群论(1): 群, 同构定理, 循环群格罗卜&#xff1a;群论(2): 群作用, Sylow定理更多内容&#xff0c;请移步专栏目录:格罗卜&a…

c++的文件输入/输出

1文件的概述 根据文件中数据的组织形式分为&#xff1a; 1 文本文件 文本文件又称ASCII文件&#xff0c;它的每一个字节存放一个ASCII代码&#xff0c;代表一个字符 输出文本&#xff1a;接收从内存输出的数据 输出文件&#xff0c;向它写入数据 ofstream fout; 输入文件&…

南阳理工计算机全国排名,全国工科实力最强的10所高校排名,

评价工科实力一个非常明显的指标就是学科实力&#xff0c;2017年公布的第四次学科评估结果就是最好的参考。下面就以学科评估排名全国5%的学科数作为评比基准&#xff0c;对国内主要高校的工科实力进行一个排名&#xff0c;结果如下&#xff1a;前3甲&#xff1a;清华大学、浙江…

真正的高手,都有增长思维!(深度好文)

点击蓝字关注&#xff0c;回复“职场进阶”获取职场进阶精品资料一份职场&认知洞察 丨 作者 / findyi这是findyi公众号分享的第99篇原创文章最近几年互联网红利消亡&#xff0c;老板们非常焦虑。这也一度让所谓的「首席增长官」被媒体热炒。仿佛来一个增长的救世主&#xf…

service层中有某个事物要立马提交_硬货你要的,binder机制来了

欢迎关注专栏&#xff1a;里面定期分享Android和Flutter架构技术知识点及解析&#xff0c;还会不断更新的BATJ面试专题&#xff0c;欢迎大家前来探讨交流&#xff0c;如有好的文章也欢迎投稿。Android高级进阶​zhuanlan.zhihu.com前言Binder做为Android中核心机制&#xff0c;…

学习笔记 | 传统企业互联网改革之道

【学习笔记】| 作者 / Edison Zhou这是EdisonTalk的第306篇学习分享最近在看刘润老师的《互联网战略版&#xff1a;传统企业&#xff0c;互联网在踢门》&#xff0c;学习了传统企业互联网改革的价值模型与三大模式&#xff0c;醍醐灌顶受益良多。因此&#xff0c;我将我学到的总…

蓝桥杯杂题

蓝桥杯杂题开始聊天吧气球升起度熊所居住开始聊天吧 #include<bits/stdc.h> using namespace std; set<char>S; int main() {string s;while(cin>>s){S.clear();for(auto x:s)//使用x拷贝s字符串 中的每一个字符 {S.insert(x); //将每一个字符插入到集合S中/…