内容来源:宜信技术学院第4期技术沙龙-线上直播|宜信微服务任务调度平台建设实践
成都创新互联成立与2013年,是专业互联网技术服务公司,拥有项目成都网站设计、做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元奈曼做网站,已为上家服务,为奈曼各地企业和个人服务,联系电话:13518219792
主讲人:宜信高级架构师&开发平台负责人 梁鑫
导读:如今,无论是互联网应用还是企业级应用,都充斥着大量的批处理任务,常常需要一些任务调度系统帮助我们解决问题。随着微服务化架构的逐步演进,单体架构逐渐演变为分布式、微服务架构。
在此背景下,很多之前的任务调度平台已经不能满足业务系统的需求,于是出现了一些基于分布式的任务调度平台。这些平台各有其特点,但也各有不足之处,比如不支持任务编排、与业务高耦合、不支持跨平台等问题,不是非常符合公司的需求,因此我们开发了微服务任务调度平台(SIA-TASK)。本次分享主要围绕SIA平台展开,包括研发背景设计思路和技术架构,以及如何支持业务方。
无论是互联网应用还是企业级应用,都充斥着大量的批处理任务,常常需要一些任务调度系统帮助我们解决问题。随着微服务化架构的逐步演进,单体架构逐渐演变为分布式、微服务架构。
在这样的背景下,很多之前的任务调度平台或组件已经不能满足业务系统的需求,于是出现了一些基于分布式的任务调度平台。这些平台各有其特点,但也各有不足之处,比如不支持任务编排、与业务高耦合、不支持跨平台等问题。
按照任务与时间的关系,我们把批处理任务分成三类,飞机型、地铁型、公共汽车型。
在跑批任务的过程中会遇到以下问题:
前文提到任务之间是有关系的,那到底存在哪些关系呢?我认为主要有以下3种:
基于上述的几种关系,我们在建设任务调度平台的时候会思考以下两个方面:
除了上述两个方面的考虑以外,我们还需要思考以下八个因素。
基于以上的背景与考虑,我们建设了微服务任务调度平台SIA-Task。
SIA是“Simple is Awesome”的简称。
SIA-TASK(微服务任务调度平台)是其中的一项重要产品,SIA-Task契合当前微服务架构模式,具有跨平台、可编排、高可用、无侵入、一致性、异步并行、动态扩展、实时监控等特点。
SIA-TASK是任务调度的一体式解决方案,对任务进行元数据采集,然后进行任务可视化编排,最终进行任务调度,并且对任务采取全流程监控,简单易用。对业务完全无侵入,通过简单灵活的配置即可生成符合预期的任务调度模型。
SIA-TASK借鉴微服务的设计思想,获取分布在每个任务执行器上的任务元数据,上传到任务注册中心。利用在线方式进行任务编排,可动态修改任务时钟,采用HTTP作为任务调度协议,统一使用JSON数据格式,由调度中心进行时钟解析,执行任务流程,进行任务通知。
简单介绍一下SIA-TASK的术语。
Task是业务执行的基本单元,执行器对外暴露的一个HTTP调用接口。若干个Task构成一个Job,而Plan是由若干个顺序执行的Job构成。
为什么这里需要一个Plan?有的时候两个任务不光有顺序关系(就是A任务执行完之后再执行B任务),还需要满足一定的时间要求,比如上午10点执行任务A,下午2点执行任务B,而且必须保证上午10点任务A按时执行完成。
打个比方,今晚8点有一场足球比赛的直播,如果晚上8点我还不能到家,那我就没办法看直播,而如果今天我下班早,下午6点多就到家,也必须等到8点才能开始看球赛,这就是Plan计划的来源。
SIA-TASK任务调度平台有以下几个部分组成:
接下来详细介绍SIA-TASK的运行逻辑。
首先,通过注解抓取任务执行器中的任务上报到任务注册中心。任务执行器在启动的时候,会有一个叫online Task的注解,只要把这个注解放到control代码的方法上,就会自动把HTTP接口抓取出来,然后上报到任务注册中心,这里我们用的是ZooKeeper。
任务编排中心从任务注册中心获取数据进行编排保存入持久化存储。也就是说,相当于在执行器里,把业务调用HTTP接口请求的URL地址、端口等实例抓取出来上传到ZooKeeper里,ZooKeeper就拿到了一个个的任务,ZooKeeper会把任务本身的信息抓取出来放到MySQL里。
这里要区别一下什么是任务,什么是任务实例。任务实例和任务的关系,有点像类和对象的关系,就是一份业务逻辑代码可能部署在多个节点上,也就是说这些节点的业务逻辑代码是一模一样的,在运行阶段抓取的时候会把每个节点上业务逻辑代码都抓取上来,针对这个业务它就是一个任务,但是每一个端口、每个IP地址对应的可能就是一个任务实例。比如高可用热备时,我们会把任务本身的信息经过处理之后保存到持久存储里,而实例本身的信息只会停留在ZooKeeper里。
任务配置中心可以根据ZooKeeper里的信息和MySQL里的信息进行配置,就是根据抓取的任务,给这些Task加时钟、策略,然后编排出Job和Plan,并把现在的这些信息保存到MySQL里。
任务调度中心从持久化存储获取调度信息,知道编排的Job、Plan、时钟、策略等逻辑,任务调度中心按照调度逻辑访问任务执行器,对这些从执行器上抓取来的Task进行调度。
这就是SIA-TASK的运行逻辑,同时我们会把调度日志存到Kafka里。
在暴露成HTTP服务的方法上加入@OnlineTask注解,@OnlineTask会自动抓取方法所在的IP地址、端口、请求路径、请求方法、请求参数格式等信息上传到任务注册中心(zookeeper),并同步把任务信息写入持久化存储中。
单一任务实例必须保持单线程运行,任务调度框架自动拦截@OnlineTask注解进行单线程运行控制,保持在一个任务运行时不会被再次调度。而且整个控制过程对开发者完全无感知。
就是在一个任务实例上,要保证任务在运行的时候是单线程状态。其实这是由用户自己控制的,如果需要是单线程的,这里可以加以控制;如果需要是多线程的,可以不加控制。这个控制并不需要另加代码,只需要在注解上去处理。
SIA-TASK的设计思想是以任务为原子,把多个任务按照执行的关系组合起来形成一个作业(Job)。同时运行时分为任务调度中心和任务编排中心,使得作业的调度和作业的编排分隔开来,互不影响。在我们需要调整作业的流程时,只需要在编排中心进行处理即可。同时编排中心支持任务按照串行、并行、分支等方式组织关系。在相同任务不同任务实例时,也支持多种调度方式进行处理,而且整个的处理编排都是在页面上完成的,这个功能非常好用,这也是SIA-TASK平台的一个亮点。
任务执行过程中出现失败、异常时,可以根据任务定制的策略进行多点重新唤醒任务,保证任务的不间断执行。我们设定了很多策略,比如某个Task出现问题了怎么办?是再唤醒一次?还是不管了?还是人工干预发警报?我们定制了很多策略去处理这些问题。
了解了平台特性,我们来梳理SIA-TASK的技术关键点。
任务调度管理首页主要包括三部分:调度器信息、调度次数、对接项目详情。
目前SIA-Task平台上已经接入了51个项目,上面跑的Job数有600多个,今年上线的版本,Job已经跑了3000多万次。
调度器上有几个值需要了解一下,每台调度器都有三个指标。
关于调度器有几个 信息需要了解,如图所示,点击某个调度器(柱状图),会显示该调度器所抢占的Job详情列表:
调度器包括工作调度器、下线调度器、离线调度器、白名单。
上图所示是SIA-TASK的调度监控页面,分着的一块一块区域属于不同项目组。目前SIA-Task接入了51个项目,准备中的有500多个,正在运行的有25个。
有的Job执行非常快,几秒钟就执行完了,有的Job执行非常慢,需要很长的时间,我们在状态抓取的时候,只能抓取到时间长的Job,这些被抓取的Job显示为正在运行,而时间短的捕捉不到,但它们都处于执行状态,这些没有被抓取到的Job就显示为准备中。
可能有的Job这段时间不需要运行,可以手动停止,剩下的就是异常停止的Job,需要发送邮件告警。
我们也提供了检索的能力,可以接受不同项目组登录查询自己的项目运行状态。
Task管理界面中,Task按项目组分组显示,主要提供Task的配置、修改与删除等功能。Task包含两部分:一部分Task使用了sia-Task-hunter组件,通过标准注解实现Task的自动抓取,这类Task不允许修改;另外一部分Task是由用户手动添加的,我知道访问的URL和HTTP地址,手动添加进来,这部分Task支持跨平台的抓取,而且可以修改和删除。
一个Task管理包含以下几个部分内容:项目名称、应用名称、任务名称、机器地址、描述、以及查看/修改/连通性测试等操作。同一个Task名称,不同的机器地址,代表一个任务和不同的任务实例。
前面介绍了一个Job由若干个Task组成,图中每一个不同的列代表项目名称,点击下拉列表可以显示所有的项目,可以进行过滤、添加、状态查看等操作。
其中状态操作可以手工执行,可以停止或激活Job,Job配置好之后属于未激活的状态,需要激活一下。还可以修改Job里的信息,配置Job等。
如何添加Job?假如我要添加一个Cron表达式类型的Job,需要添加哪些内容呢?
因为Job是Cron表达式类型的,首先我需要输入六位表达式内容,还要添加一个预警邮箱,再描述这个Job,每个Job都有一个key,最后还需要添加Job_key。这样一个新的Job就添加好了。
回过头来看,添加Job需要配置Task信息,这是一个比较复杂的过程。一个Job由若干个Task组成,我们可以用拖拉拽的方式根据Task之间的关系确定形成组成Job的所有Task的顺序关系。还可以以不同颜色代表不同项目进行区分,当然只有管理员才有权限看到所有项目,各个项目的负责人只能看到自己所属项目的状态。
上传Task的时候会带一些参数,所以还涉及到参数的处理,比如参数类型、参数值、过期时间等。重点聊聊过期时间。
通过HTTP方式调用会遇到一个问题:到底Task什么时间会执行完成。为解决这个问题,就需要设一个Task的过期时间,只要过期时间一到,就会转入其他策略,比如放弃或人工处理等。因为作为异步调用,不可能无休止地等待客户端返回结果。
当然也可能存在一种情况:我得到的结果是超时了,实际上任务是在正确执行,而且再过一段时间给我返回结果了。我们曾经设计了一种队列补偿机制来处理这个问题,但是好像意义不大。当然,这只是一种可能,平台上线至今没有出现过。
目前平台的Task_选取实例策略包括两种:
日志管理提供了Job的运行日志相关信息,按项目组分组显示,一条Job日志的关键元素包含:
SIA-TASK作为SIA团队的一个重要产品,在公司接入了数十个项目,运行着数百个Job,经受住了稳定性的考验。
SIA-TASK微服务调度平台于5月已经开源,开源地址:https://github.com/siaorg/sia-Task,感兴趣的同学可以登录查看详细介绍。
分享者:梁鑫
来源:宜信技术学院