0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

xxl-job惊艳的设计,怎能叫人不爱

jf_ro2CN3Fa 来源:c1n.cn/N8Mln 2022-12-22 14:43 次阅读

  • 通信底层介绍
  • 通信整体流程
  • 惊艳的设计

通信底层介绍

xxl-job 使用 netty http 的方式进行通信,虽然也支持 Mina,jetty,netty tcp 等方式,但是代码里面固定写死的是 netty http。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

通信整体流程

我以调度器通知执行器执行任务为例,绘制的活动图:

cafb50e6-81b9-11ed-8abf-dac502259ad0.png活动图

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

惊艳的设计

看完了整个处理流程代码,设计上可以说独具匠心,将 netty,多线程的知识运用得行云流水。

我现在就将这些设计上出彩的点总结如下:

使用动态代理模式,隐藏通信细节

xxl-job 定义了两个接口 ExecutorBiz,AdminBiz,ExecutorBiz 接口中封装了向心跳,暂停,触发执行等操作,AdminBiz 封装了回调,注册,取消注册操作,接口的实现类中,并没有通信相关的处理。

XxlRpcReferenceBean 类的 getObject() 方法会生成一个代理类,这个代理类会进行远程通信。

全异步处理

执行器收到消息进行反序列化,并没有同步执行任务代码,而是将任务信息存储在 LinkedBlockingQueue 中,异步线程从这个队列中获取任务信息,然后执行。

而任务的处理结果,也不是说处理完之后,同步返回的,也是放到回调线程的阻塞队列中,异步的将处理结果返回回去。

这样处理的好处就是减少了 netty 工作线程的处理时间,提升了吞吐量。

对异步处理的包装

对异步处理进行了包装,代码看起来是同步调用的。

我们看下调度器,XxlJobTrigger 类触发任务执行的代码:

publicstaticReturnTrunExecutor(TriggerParamtriggerParam,Stringaddress){
ReturnTrunResult=null;
try{
ExecutorBizexecutorBiz=XxlJobScheduler.getExecutorBiz(address);
//这里面做了很多异步处理,最终同步得到处理结果
runResult=executorBiz.run(triggerParam);
}catch(Exceptione){
logger.error(">>>>>>>>>>>xxl-jobtriggererror,pleasecheckiftheexecutor[{}]isrunning.",address,e);
runResult=newReturnT(ReturnT.FAIL_CODE,ThrowableUtil.toString(e));
}

StringBufferrunResultSB=newStringBuffer(I18nUtil.getString("jobconf_trigger_run")+":");
runResultSB.append("
address:"
).append(address); runResultSB.append("
code:"
).append(runResult.getCode()); runResultSB.append("
msg:"
).append(runResult.getMsg()); runResult.setMsg(runResultSB.toString()); returnrunResult; }

ExecutorBiz.run 方法我们说过了,是走的动态代理,和执行器进行通信,执行器执行结果也是异步处理完,才返回的,而这里看到的 run 方法是同步等待处理结果返回。

我们看下xxl-job是如何同步获取处理结果的:调度器向执行器发出消息后,该线程阻塞。等到执行器处理完毕后,将处理结果返回,唤醒被阻塞的线程,调用处拿到返回值。

动态代理代码如下:

//代理类中的触发调用
if(CallType.SYNC==callType){
//future-responseset
XxlRpcFutureResponsefutureResponse=newXxlRpcFutureResponse(invokerFactory,xxlRpcRequest,null);
try{
//doinvoke
client.asyncSend(finalAddress,xxlRpcRequest);

//futureget
XxlRpcResponsexxlRpcResponse=futureResponse.get(timeout,TimeUnit.MILLISECONDS);
if(xxlRpcResponse.getErrorMsg()!=null){
thrownewXxlRpcException(xxlRpcResponse.getErrorMsg());
}
returnxxlRpcResponse.getResult();
}catch(Exceptione){
logger.info(">>>>>>>>>>>xxl-rpc,invokeerror,address:{},XxlRpcRequest{}",finalAddress,xxlRpcRequest);

throw(einstanceofXxlRpcException)?e:newXxlRpcException(e);
}finally{
//future-responseremove
futureResponse.removeInvokerFuture();
}
}

XxlRpcFutureResponse 类中实现了线程的等待,和线程唤醒的处理:

//返回结果,唤醒线程
publicvoidsetResponse(XxlRpcResponseresponse){
this.response=response;
synchronized(lock){
done=true;
lock.notifyAll();
}
}

@Override
publicXxlRpcResponseget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutException{
if(!done){
synchronized(lock){
try{
if(timeout< 0){
//线程阻塞
lock.wait();
}else{
longtimeoutMillis=(TimeUnit.MILLISECONDS==unit)?timeout:TimeUnit.MILLISECONDS.convert(timeout,unit);
lock.wait(timeoutMillis);
}
}catch(InterruptedExceptione){
throwe;
}
}
}

if(!done){
thrownewXxlRpcException("xxl-rpc,requesttimeoutat:"+System.currentTimeMillis()+",request:"+request.toString());
}
returnresponse;
}

有的同学可能会问了,调度器接收到返回结果,怎么确定唤醒哪个线程呢?

每一次远程调用,都会生成 uuid 的请求 id,这个 id 是在整个调用过程中一直传递的,就像一把钥匙,在你回家的的时候,拿着它就带开门。

这里拿着请求 id 这把钥匙,就能找到对应的 XxlRpcFutureResponse,然后调用 setResponse 方法,设置返回值,唤醒线程。

publicvoidnotifyInvokerFuture(StringrequestId,finalXxlRpcResponsexxlRpcResponse){

//通过requestId找到XxlRpcFutureResponse,
finalXxlRpcFutureResponsefutureResponse=futureResponsePool.get(requestId);
if(futureResponse==null){
return;
}
if(futureResponse.getInvokeCallback()!=null){

//callbacktype
try{
executeResponseCallback(newRunnable(){
@Override
publicvoidrun(){
if(xxlRpcResponse.getErrorMsg()!=null){
futureResponse.getInvokeCallback().onFailure(newXxlRpcException(xxlRpcResponse.getErrorMsg()));
}else{
futureResponse.getInvokeCallback().onSuccess(xxlRpcResponse.getResult());
}
}
});
}catch(Exceptione){
logger.error(e.getMessage(),e);
}
}else{
//里面调用lock的notify方法
futureResponse.setResponse(xxlRpcResponse);
}

//doremove
futureResponsePool.remove(requestId);

}


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 通信
    +关注

    关注

    18

    文章

    5977

    浏览量

    135871
  • 代码
    +关注

    关注

    30

    文章

    4753

    浏览量

    68368

原文标题:xxl-job惊艳的设计,怎能叫人不爱

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    联诚发LED屏惊艳亮相土耳其广告展

    近日,第25届国际广告业和数字印刷技术博览会(简称 Sign Istanbul )在土耳其伊斯坦布尔隆重举行。联诚发携多款创新LED显示产品及多领域的应用解决方案惊艳亮相,为全球客户打造沉浸式视觉盛宴,展会现场人流络绎不绝,热闹非凡。
    的头像 发表于 11-04 17:47 366次阅读

    【新品推介】可输出3A大电流的DC-DC电源降压芯片-XXL1509

    01产品说明XXL1509是一款高效降压型DC-DC电源转换器,固定150KHz开关频率,可提供3A输出电流能力,具有低纹波,出色的线性调整率与负载调整率特点。XXL1509内置固定频率振荡器与频率
    的头像 发表于 10-29 08:06 317次阅读
    【新品推介】可输出3A大电流的DC-DC电源降压芯片-<b class='flag-5'>XXL</b>1509

    北京安防博览会圆满闭幕!华电子智慧路灯全网运维管理惊艳全场!

    北京安防博览会圆满闭幕!华电子智慧路灯全网运维管理惊艳全场!
    的头像 发表于 10-28 10:32 160次阅读
    北京安防博览会圆满闭幕!华电子智慧路灯全网运维管理<b class='flag-5'>惊艳</b>全场!

    扬帆出海!九章云极DataCanvas公司惊艳亮相迪拜GITEX Global 2024

    近日,第44届GITEXGLOBAL展会(GITEXGLOBAL2024)及全球领先的创业与投资盛会ExpandNorthStar2024在迪拜盛大启幕。九章云极DataCanvas公司惊艳亮相盛会
    的头像 发表于 10-18 17:08 242次阅读
    扬帆出海!九章云极DataCanvas公司<b class='flag-5'>惊艳</b>亮相迪拜GITEX Global 2024

    智动未来!广和通AI解决方案惊艳2024世界机器人大会

    8月21-25日,2024世界机器人大会在北京经开区北人亦创国际会展中心顺利开幕,广和通携一系列端侧AI产品及解决方案惊艳亮相A馆A167展位,与产业伙伴探讨“机器人+”应用场景与AI技术,携手推进机器人领域的创新合作。
    的头像 发表于 08-22 10:57 533次阅读
    智动未来!广和通AI解决方案<b class='flag-5'>惊艳</b>2024世界机器人大会

    未来的智慧园区,充满令人惊艳的场景

    未来的智慧园区,充满了令人惊艳的场景。它将实现从能源管理到环境监测的多重使命,用科技的力量为人类打造宜居、绿色的工作生活空间。 首先,智慧园区的能源管理将进入全新阶段。通过智能化的能源管理系统,实时
    的头像 发表于 05-08 15:33 271次阅读

    不容忽视的PCB设计细节

    比起低价压力、紧迫交期、严苛品质、货款拖延等常规烦恼,订单里那些不起眼的设计失误和小BUG,带来的影响更叫人脑壳疼!
    发表于 04-10 11:46 357次阅读
    不容忽视的PCB设计细节

    哪吒汽车携畅销车型NETA V-II惊艳亮相曼谷国际车展

    哪吒汽车携畅销车型NETA V-II惊艳亮相曼谷国际车展
    的头像 发表于 03-28 10:11 385次阅读
    哪吒汽车携畅销车型NETA V-II<b class='flag-5'>惊艳</b>亮相曼谷国际车展

    京东方携前沿显示技术惊艳亮相MWC 2024

    2月26日至29日,备受全球瞩目的世界移动通信大会(MWC2024)在西班牙巴塞罗那盛大开幕。此次盛会,BOE(京东方)携手多家全球一线品牌合作伙伴惊艳亮相,带来了搭载其柔性OLED、3D显示、VR显示等尖端显示技术的10余款创新消费电子产品,包括手机、平板、笔记本电脑和显示器等。
    的头像 发表于 03-03 15:51 1170次阅读

    TC397寄存器DMU_HF_ECCS保留位不为0引发报错MEMIF_JOB_FAILED的原因?

    在dflash模块中做读日志动作时寄存器DMU_HF_ECCS保留位不为0引发报错MEMIF_JOB_FAILED
    发表于 02-04 07:13

    使能TC2xxL MCU的 SMU_FSP引脚,对应的SMU驱动如何配置呢?

    我想使能 TC2xxL MCU的 SMU_FSP引脚,对应的SMU驱动如何配置呢?比如SmuAlarmGroup里怎么配置
    发表于 02-04 06:00

    xxl-job通信设计流程

    每一次远程调用,都会生成 uuid 的请求 id,这个 id 是在整个调用过程中一直传递的,就像一把钥匙,在你回家的的时候,拿着它就带开门。
    的头像 发表于 01-30 09:34 603次阅读
    <b class='flag-5'>xxl-job</b>通信设计流程

    PDF输出时出现错误提醒的解决方案

    通过Output Job或Smart PDF创建PDF后,Adobe Acrobat Reader在打开文件时会出现以下错误消息:“An error exists on this page.
    的头像 发表于 01-12 09:50 1601次阅读
    PDF输出时出现错误提醒的解决方案

    触觉反馈执行器:业内首款应用于智能手机的触觉固态按钮惊艳CES

    拉斯维加斯国际会展中心正式开幕,各类前沿技术产品同场“竞技”,值得关注的是,以触觉反馈执行器为核心部件的业内首款应用于智能手机的触觉固态按钮惊艳亮相,重
    的头像 发表于 01-11 08:00 627次阅读
    触觉反馈执行器:业内首款应用于智能手机的触觉固态按钮<b class='flag-5'>惊艳</b>CES

    分布式定时调度:xxl-job最佳实践方法

    定时任务是按照指定时间周期运行任务。使用场景为在某个固定时间点执行,或者周期性的去执行某个任务,比如:每天晚上24点做数据汇总,定时发送短信等。
    的头像 发表于 11-30 11:06 1500次阅读
    分布式定时调度:<b class='flag-5'>xxl-job</b>最佳实践方法