专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

如何实现一个任务调度系统

  阅读一篇定时任务框架选型的文章时,一位网友的留言电到了我:
  我看过那么多所谓的教程,大部分都是教如何使用工具的,没有多少是教如何制作工具的,能教如何仿制工具的都已经是凤毛麟角,中国软件行业,缺的是真正可以制作工具的程序员,而绝对不缺那些使用工具的程序员!。。。。。。这个业界最不需要的就是会使用XX工具的工程师,而是有创造力的软件工程师!业界所有的饭碗,本质就是有创造力的软件工程师提供出来的啊!
  写这篇文章,想和大家从头到脚说说任务调度,希望大家读完之后,能够理解实现一个任务调度系统的核心逻辑。
  1Quartz
  Quartz是一款Java开源任务调度框架,也是很多Java工程师接触任务调度的起点。
  下图显示了任务调度的整体流程:
  Quartz的核心是三个组件。任务:Job用于表示被调度的任务;触发器:Trigger定义调度时间的元素,即按照什么时间规则去执行任务。一个Job可以被多个Trigger关联,但是一个Trigger只能关联一个Job;调度器:工厂类创建Scheduler,根据触发器定义的时间规则调度任务。
  上图代码中Quartz的JobStore是RAMJobStore,Trigger和Job存储在内存中。
  执行任务调度的核心类是QuartzSchedulerThread。
  调度线程从JobStore中获取需要执行的的触发器列表,并修改触发器的状态;Fire触发器,修改触发器信息(下次执行触发器的时间,以及触发器状态),并存储起来。最后创建具体的执行任务对象,通过worker线程池执行任务。
  接下来再聊聊Quartz的集群部署方案。
  Quartz的集群部署方案,需要针对不同的数据库类型(MySQL,ORACLE)在数据库实例上创建Quartz表,JobStore是:JobStoreSupport。
  这种方案是分布式的,没有负责集中管理的节点,而是利用数据库行级锁的方式来实现集群环境下的并发控制。
  scheduler实例在集群模式下首先获取{0}LOCKS表中的行锁,Mysql获取行锁的语句:
  {0}会替换为配置文件默认配置的QRTZ。schedname为应用集群的实例名,lockname就是行级锁名。Quartz主要有两个行级锁触发器访问锁(TRIGGERACCESS)和状态访问锁(STATEACCESS)。
  这个架构解决了任务的分布式调度问题,同一个任务只能有一个节点运行,其他节点将不执行任务,当碰到大量短任务时,各个节点频繁的竞争数据库锁,节点越多性能就会越差。2分布式锁模式
  Quartz的集群模式可以水平扩展,也可以分布式调度,但需要业务方在数据库中添加对应的表,有一定的强侵入性。
  有不少研发同学为了避免这种侵入性,也探索出分布式锁模式。
  业务场景:电商项目,用户下单后一段时间没有付款,系统就会在超时后关闭该订单。
  通常我们会做一个定时任务每两分钟来检查前半小时的订单,将没有付款的订单列表查询出来,然后对订单中的商品进行库存的恢复,然后将该订单设置为无效。
  我们使用SpringSchedule的方式做一个定时任务。Scheduled(cron02?)publicvoiddoTask(){log。info(定时任务启动);执行关闭订单的操作orderService。closeExpireUnpayOrders();log。info(定时任务结束);}
  在单服务器运行正常,考虑到高可用,业务量激增,架构会演进成集群模式,在同一时刻有多个服务执行一个定时任务,有可能会导致业务紊乱。
  解决方案是在任务执行的时候,使用Redis分布式锁来解决这类问题。Scheduled(cron02?)publicvoiddoTask(){log。info(定时任务启动);StringlockNamecloseExpireUnpayOrdersLock;RedisLockredisLockredisClient。getLock(lockName);尝试加锁,最多等待3秒,上锁以后5分钟自动解锁booleanlockedredisLock。tryLock(3,300,TimeUnit。SECONDS);if(!locked){log。info(没有获得分布式锁:{},lockName);return;}try{执行关闭订单的操作orderService。closeExpireUnpayOrders();}finally{redisLock。unlock();}log。info(定时任务结束);}
  Redis的读写性能极好,分布式锁也比Quartz数据库行级锁更轻量级。当然Redis锁也可以替换成Zookeeper锁,也是同样的机制。
  在小型项目中,使用:定时任务框架(QuartzSpringSchedule)和分布式锁(rediszookeeper)有不错的效果。
  但是呢?我们可以发现这种组合有两个问题:定时任务在分布式场景下有空跑的情况,而且任务也无法做到分片;要想手工触发任务,必须添加额外的代码才能完成。3ElasticJobLite框架
  ElasticJobLite定位为轻量级无中心化解决方案,使用jar的形式提供分布式任务的协调服务。
  应用内部定义任务类,实现SimpleJob接口,编写自己任务的实际业务流程即可。publicclassMyElasticJobimplementsSimpleJob{Overridepublicvoidexecute(ShardingContextcontext){switch(context。getShardingItem()){case0:dosomethingbyshardingitem0break;case1:dosomethingbyshardingitem1break;case2:dosomethingbyshardingitem2break;casen:。。。}}}
  举例:应用A有五个任务需要执行,分别是A,B,C,D,E。任务E需要分成四个子任务,应用部署在两台机器上。
  应用A在启动后,5个任务通过Zookeeper协调后被分配到两台机器上,通过QuartzScheduler分开执行不同的任务。
  ElasticJob从本质上来讲,底层任务调度还是通过Quartz,相比Redis分布式锁或者Quartz分布式部署,它的优势在于可以依赖Zookeeper这个大杀器,将任务通过负载均衡算法分配给应用内的QuartzScheduler容器。
  从使用者的角度来讲,是非常简单易用的。但从架构来看,调度器和执行器依然在同一个应用方JVM内,而且容器在启动后,依然需要做负载均衡。应用假如频繁的重启,不断的去选主,对分片做负载均衡,这些都是相对比较重的操作。
  ElasticJob的控制台通过读取注册中心数据展现作业状态,更新注册中心数据修改全局任务配置。从一个任务调度平台的角度来看,控制台功能还是偏孱弱的。4中心化流派
  中心化的原理是:把调度和任务执行,隔离成两个部分:调度中心和执行器。调度中心模块只需要负责任务调度属性,触发调度命令。执行器接收调度命令,去执行具体的业务逻辑,而且两者都可以进行分布式扩容。4。1MQ模式
  先谈谈我在艺龙促销团队接触的第一种中心化架构。
  调度中心依赖Quartz集群模式,当任务调度时候,发送消息到RabbitMQ。业务应用收到任务消息后,消费任务信息。
  这种模型充分利用了MQ解耦的特性,调度中心发送任务,应用方作为执行器的角色,接收任务并执行。
  但这种设计强依赖消息队列,可扩展性和功能,系统负载都和消息队列有极大的关联。这种架构设计需要架构师对消息队列非常熟悉。4。2XXLJOB
  XXLJOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
  xxljob2。3。0架构图
  我们重点剖析下架构图:
  网络通讯serverworker模型
  调度中心和执行器两个模块之间通讯是serverworker模式。调度中心本身就是一个SpringBoot工程,启动会监听8080端口。
  执行器启动后,会启动内置服务(EmbedServer)监听9994端口。这样双方都可以给对方发送命令。
  那调度中心如何知道执行器的地址信息呢?上图中,执行器会定时发送注册命令,这样调度中心就可以获取在线的执行器列表。
  通过执行器列表,就可以根据任务配置的路由策略选择节点执行任务。常见的路由策略有如下三种:随机节点执行:选择集群中一个可用的执行节点执行调度任务。适用场景:离线订单结算。
  广播执行:在集群中所有的执行节点分发调度任务并执行。适用场景:批量更新应用本地缓存。分片执行:按照用户自定义分片逻辑进行拆分,分发到集群中不同节点并行执行,提升资源利用效率。适用场景:海量日志统计。
  调度器
  调度器是任务调度系统里面非常核心的组件。XXLJOB的早期版本是依赖Quartz。
  但在v2。1。0版本中完全去掉了Quartz的依赖,原来需要创建的Quartz表也替换成了自研的表。
  核心的调度类是:JobTriggerPoolHelper。调用start方法后,会启动两个线程:scheduleThread和ringThread。
  首先scheduleThread会定时从数据库加载需要调度的任务,这里从本质上还是基于数据库行锁保证同时只有一个调度中心节点触发任务调度。ConnectionconnXxlJobAdminConfig。getAdminConfig()。getDataSource()。getConnection();connAutoCommitconn。getAutoCommit();conn。setAutoCommit(false);preparedStatementconn。prepareStatement(selectfromxxljoblockwherelocknameschedulelockforupdate);preparedStatement。execute();触发任务调度(伪代码)for(XxlJobInfojobInfo:scheduleList){省略代码}事务提交conn。commit();
  调度线程会根据任务的下次触发时间,采取不同的动作:
  已过期的任务需要立刻执行的,直接放入线程池中触发执行,五秒内需要执行的任务放到ringData对象里。
  ringThread启动后,定时从ringData对象里获取需要执行的任务列表,放入到线程池中触发执行。
  5自研在巨人的肩膀上
  2018年,我有一段自研任务调度系统的经历。
  背景是:兼容技术团队自研的RPC框架,技术团队不需要修改代码,RPC注解方法可以托管在任务调度系统中,直接当做一个任务来执行。
  自研过程中,研读了XXLJOB源码,同时从阿里云分布式任务调度SchedulerX吸取了很多营养。
  SchedulerX1。0架构图Schedulerxconsole是任务调度的控制台,用于创建、管理定时任务。负责数据的创建、修改和查询。在产品内部与schedulerxserver交互。Schedulerxserver是任务调度的服务端,是Scheduler的核心组件。负责客户端任务的调度触发以及任务执行状态的监测。Schedulerxclient是任务调度的客户端。每个接入客户端的应用进程就是一个的Worker。Worker负责与Schedulerxserver建立通信,让schedulerxserver发现客户端的机器。并向schedulerxserver注册当前应用所在的分组,这样schedulerxserver才能向客户端定时触发任务。
  我们模仿了SchedulerX的模块,架构设计如下图:
  我选择了RocketMQ源码的通讯模块remoting作为自研调度系统的通讯框架。基于如下两点:我对业界大名鼎鼎的Dubbo不熟悉,而remoting我已经做了多个轮子,我相信自己可以搞定;在阅读SchedulerX1。0client源码中,发现SchedulerX的通讯框架和RocketMQRemoting很多地方都很类似。它的源码里有现成的工程实现,完全就是一个宝藏。
  我将RocketMQremoting模块去掉名字服务代码,做了一定程度的定制。
  在RocketMQ的remoting里,服务端采用Processor模式。
  调度中心需要注册两个处理器:回调结果处理器CallBackProcessor和心跳处理器HeartBeatProcessor。执行器需要注册触发任务处理器TriggerTaskProcessor。publicvoidregisterProcessor(intrequestCode,NettyRequestProcessorprocessor,ExecutorServiceexecutor);
  处理器的接口:publicinterfaceNettyRequestProcessor{RemotingCommandprocessRequest(ChannelHandlerContextctx,RemotingCommandrequest)throwsException;booleanrejectRequest();}
  对于通讯框架来讲,我并不需要关注通讯细节,只需要实现处理器接口即可。
  以触发任务处理器TriggerTaskProcessor举例:
  搞定网络通讯后,调度器如何设计?最终我还是选择了Quartz集群模式。主要是基于以下几点原因:调度量不大的情况下,Quartz集群模式足够稳定,而且可以兼容原来的XXLJOB任务;使用时间轮的话,本身没有足够的实践经验,担心出问题。另外,如何让任务通过不同的调度服务(scheduleserver)触发,需要有一个协调器。于是想到Zookeeper。但这样的话,又引入了新的组件。研发周期不能太长,想快点出成果。
  自研版的调度服务花费一个半月上线了。系统运行非常稳定,研发团队接入也很顺畅。调度量也不大,四个月总共接近4000万到5000万之间的调度量。
  坦率的讲,自研版的瓶颈,我的脑海里经常能看到。数据量大,我可以搞定分库分表,但Quartz集群基于行级锁的模式,注定上限不会太高。
  为了解除心中的困惑,我写一个轮子DEMO看看可否work:去掉外置的注册中心,调度服务(scheduleserver)管理会话;引入zookeeper,通过zk协调调度服务。但是HA机制很粗糙,相当于一个任务调度服务运行,另一个服务standby;Quartz替换成时间轮(参考Dubbo里的时间轮源码)。
  这个Demo版本在开发环境可以运行,但有很多细节需要优化,仅仅是个玩具,并没有机会运行到生产环境。
  最近读阿里云的一篇文章《如何通过任务调度实现百万规则报警》,SchedulerX2。0高可用架构见下图:
  文章提到:
  每个应用都会做三备份,通过zk抢锁,一主两备,如果某台Server挂了,会进行failover,由其他Server接管调度任务。
  这次自研任务调度系统从架构来讲,并不复杂,实现了XXLJOB的核心功能,也兼容了技术团队的RPC框架,但并没有实现工作流以及mapreduce分片。
  SchedulerX在升级到2。0之后基于全新的Akka架构,这种架构号称实现高性能工作流引擎,实现进程间通信,减少网络通讯代码。
  在我调研的开源任务调度系统中,PowerJob也是基于Akka架构,同时也实现了工作流和MapReduce执行模式。
  我对PowerJob非常感兴趣,也会在学习实践后输出相关文章,敬请期待。6技术选型
  首先我们将任务调度开源产品和商业产品SchedulerX放在一起,生成一张对照表:
  Quartz和ElasticJob从本质上还是属于框架的层面。
  中心化产品从架构上来讲更加清晰,调度层面更灵活,可以支持更复杂的调度(mapreduce动态分片,工作流)。
  XXLJOB从产品层面已经做到极简,开箱即用,调度模式可以满足大部分研发团队的需求。简单易用能打,所以非常受大家欢迎。
  其实每个技术团队的技术储备不尽相同,面对的场景也不一样,所以技术选型并不能一概而论。
  不管是使用哪种技术,在编写任务业务代码时,还是需要注意两点:幂等。当任务被重复执行的时候,或者分布式锁失效的时候,程序依然可以输出正确的结果;任务不跑了,千万别惊慌。查看调度日志,JVM层面使用Jstack命令查看堆栈,网络通讯要添加超时时间,一般能解决大部分问题。7写到最后
  2015年其实是非常有趣的一年。ElasticJob和XXLJOB这两种不同流派的任务调度项目都开源了。
  在XXLJOB源码里,至今还保留着许雪里老师在开源中国的一条动态截图:
  刚写的任务调度框架,Web动态管理任务,实时生效,热乎的。没有意外的话,明天中午推送到git。osc上去。哈哈,下楼炒个面加个荷包蛋庆祝下。
  看到这个截图,内心深处竟然会有一种共情,嘴角不自禁的上扬。
  我又想起:2016年,ElasticJob的作者张亮老师开源了shardingjdbc。我在github上创建了一个私有项目,参考shardingjdbc的源码,自己实现分库分表的功能。第一个类名叫:ShardingDataSource,时间定格在2016329。
  我不知道如何定义有创造力的软件工程师,但我相信:一个有好奇心,努力学习,乐于分享,愿意去帮助别人的工程师,运气肯定不会太差。

8月造车新势力交付榜哪吒零跑蔚来破万摘要8月,哪吒汽车UV交付16017辆,同比增长142零跑汽车交付量达12525辆,同比增长超180蔚来交付新车10677辆,同比增长81。6小鹏汽车交付9578辆,同比增长33极服贸观止浙江综合展区四大专区聚焦数字服务贸易北京商报讯(记者董亮丁宁)在2022年服贸会上,浙江综合展区以数动浙江潮涌钱塘为主线,设置中心展区与四大产业展区。其中,四大专区由数字技术数字服务数字文化和数字平台组成,主要展现浙脉脉被判赔百度25。1万法院构成商业诋毁21世纪经济报道见习记者钟雨欣北京报道提起脉脉,许多互联网大厂员工并不陌生。这一职场社交平台近年来的多次出圈,常与用户爆料公司八卦密切相连,在脉脉职言区,匿名交流机制下,用户既能吃记者探馆黑科技首个公众开放日观众热情满满央视网消息2022年中国国际服务贸易交易会9月3日迎来首个公众开放日。从9月3日起至9月5日,国家会议中心和首钢园两大展区将免费对普通观众开放。开放现场,哪些展区最受青睐?还有哪些携程ServiceMesh性能优化实践一背景为了支撑业务的高速发展,从17年开始,携程内部逐步推进应用容器化改造与业务上云工作,同期携程技术架构经历了从集中式单体应用到分布式微服务化的演进过程。随着Kubernetes院士何积丰路车智能互联是通往L4级自动驾驶的解题思路9月1日,世界人工智能大会在上海世博中心开幕,此次大会的主题是智联世界,元生无界。当日下午,在AI开源开放与产业智能化高峰论坛中,中国科学院院士何积丰对路车智能互联技术和产业化前景刚摸的两款神级SSD800GB容量价格过万,写入耐用可传家最近有机会摸了下当前最快的两款固态硬盘英特尔傲腾DCP5800X和大普微X2900P。当然这个最快是从低延迟角度来说的,如果单以顺序读写速度来看,PCIe5。0SSD早已超越了他们植物激活战时蛋白生产对抗入侵,有望研发抗病而不影响产量的农作物科技日报记者张梦然植物经常受到细菌病毒和其他病原体的攻击。当植物感知到微生物入侵时,其细胞内的蛋白质化学汤,也就是生命的主力分子中会发生根本性的变化。在发表于细胞杂志的一项新研究中METABENG。通过糖基转移酶合理设计和人工途径构建大肠杆菌生物合成肉桂醇二糖天然产物大家好,今天推送的文章来自MetabolicEngineering上的BiosynthesisofarosavinnaturalproductinEscherichiacoliby丰田上半年利润暴跌42,CEO把失败归咎于中美新能源车的崛起?丰田公布了2022年16月财报,受到日元贬值俄乌冲突原物料成本上升芯片等供应链短缺等问题,丰田上半年利润衰退高达42,今年上半年丰田虽然狂卖516万台车,比第二名大众多卖126万台蓝黛科技上半年营收13。53亿元新能源汽车零部件量产8月30日,重庆蓝黛科技(002765)公布2022年半年报,今年上半年实现营业收入13。53亿元,同比减少16。49归母净利润9174。33万元,同比减少23。74扣非后净利润8
早上的市民广场,人和鸽子是如此的和谐温馨每天上下班都要经过市民广场前的大路,只要是我步行上班,总要绕到广场看看,或跳舞的人群,漫步的老人,或周围的花草,更是常常被咕咕叫的鸽子吸引。鸽子们有的三五成群的站在屋檐,排排队,或十一不离沈,都可以到哪里玩呢?我想到这些,剩下的老铁们补充棋盘山樱桃山七星山马耳山莫子山怪坡鸟岛植物园世博园七星湿地公园方特故宫省博物馆中央公园八一公园沈水湾公园五里河公园长白森林公园中山公园皇姑英雄公园和平公园劳动公园铁西森林公园建设公夜店相识!切尔西巨星结新欢绝色美女加入英太太团将督战世界杯刚刚,八卦媒体太阳报消息,切尔西巨星奇尔韦尔又有新欢了,最近认识了英国真人秀明星法兰姬希姆斯,两人迅速陷入爱河。据悉,法兰姬将跟随英格兰太太团,在11月份前往卡塔尔,督战世界杯。过女篮世界杯中国女篮能否站在决赛场李梦能否拿下MVP女篮世界杯小组赛已经全部结束,最后进入8强的队伍分别是美国队中国队法国队塞尔维亚队澳大利亚队比利时队加拿大队波多黎各队。美国队以五战全胜位居小组赛榜首,中国队以四胜一负紧随其后。经利川神奇美丽百丈沟百丈沟梯田秋色湖北日报客户端(利川频道通讯员陈小林)百丈沟又叫百战沟,百丈是说这里的峡谷很深,百战是说这里过去曾经有过很多次战斗,所以,这沟里过去又叫百胜乡,百战百胜嘛。无论名字怎珠海横琴十大景点每一帧画面都浪漫绝美惊艳!附假期游玩攻略珠海没有四季,每个季节都是心中最美的那一季。比如九月,它有夏的暖风,春的蓝绿秋的炫酷,所到之处,随手可以捕捉到一幅幅绝美的大片。不信,这个国庆长假来珠海,小编给你介绍去处,定让你惊泰安召开文旅发展工作会议,签约10个项目总投资78。8亿元9月27日,泰安市文化旅游发展工作会议召开。会上举行泰安市文旅重点项目签约仪式,共签约10个项目,总投资78。8亿元,涵盖乡村旅游数字文化医养健康体育健身夜间旅游等多种业态。会议还惊险!女童玩扶梯被悬空带上楼这些安全知识要牢记9月25日,上海一女童在商场玩扶梯,险些发生意外。女童双手挂在扶梯外侧,双脚悬空,随着扶手被带上楼,夹在缝隙中危急时刻,路过的一男子及时上前拉住女童,并与赶来的弟弟一起将其救起。扶女子剖腹产刚出月子就怀孕!医生提醒产后不避孕是极大误区近日南京,28岁的新晋宝妈陈女士剖宫产产后3个月后,例行检查时发现自己竟又怀孕两个月。她是在恶露刚结束的时候进行了同房,并没有采取任何的避孕措施。她理所当然地认为她这段时间才生产完宝宝经常放屁?5种判断方法,教妈妈分清宝宝是正常还是健康预警有妈妈反应说自己的宝宝总是喜欢放屁,无缘无故就放屁,这让许多爸爸妈妈都非常的着急,担心是不是宝宝身体出现了一些问题,但其实,宝宝放屁是很正常的现象。如果宝宝放屁时没有不适感,吃睡都2009年,湖南女子生下2斤重的小猴子,坐出租车被拒坐不下在阅读此文前,麻烦您点击一下关注,既方便您进行讨论与分享,又给您带来不一样的参与感,感谢您的支持。2009年,湖南一孕妇正在手术室中进行分娩,好不容易等到孩子出生了,现场的所有医护
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网