xxl-job 所有的任务触发最终都是通过这个类来执行 , 该类继承关系如下:
RemoteHttpJobBean > QuartzJobBean > Job
当quartz监听到有任务需要触发是,会调用 JobRunShell 的run方法, 在该类的run方法中,会调用当前任务的JOB_CLASS 的excute方法,
调用链最终会调用到remoteHttpJobBean 的 executeInternal()
|
|
继续往下面看, 着重看 runExecutor 这个方法 , 向执行器发送指令都是从这个方法中执行的
|
通过上面可知, XxlJobDynamicScheduler.getExecutorBiz (address) , 通过机器地址,获取一个executor , 看下他的源码。
|
NetComClientProxy 这是一个factoryBean , 所以我们主要看他的getObject 方法就知道怎么创建对象并返回的。
下面这个代理对象的invoke里面并没有执行目标类的方法,而是将目标类的信息包装好,发送给执行器那一端来做。
NetComCliendProxy
|
以上就是调度中心,触发任务之后执行的核心代码 , 接下来继续分析执行器服务端接收到请求之后的处理逻辑
服务端应用里面,实际上是在应用中,内嵌了一个jetty服务器, 服务器在xxlJobExecutor 初始化的时候启动。
本次示例代码中是由spring-boot 中截取而来, 该项目中,由XxlJobConfig 这个配置类来配置Executor
呈现代码宏出错: 参数'firstline'的值无效
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();
xxlJobExecutor.setAdminAddresses(adminAddresses);
xxlJobExecutor.setAppName(appName);
xxlJobExecutor.setIp(ip);
xxlJobExecutor.setPort(port);
xxlJobExecutor.setAccessToken(accessToken);
xxlJobExecutor.setLogPath(logPath);
xxlJobExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobExecutor;
}
由上面可以看出,初始化 XxlJobExecutor 这个bean之后,会默认执行start 方法
|
上面初始化的那些方法,着重看 initExecutorServer () 这个方法
|
JettyServer
|
JettyServerHandler
|
通过上面的handle中的代码可以知道,主要的执行逻辑在doInvoke 的方法中,
|
NetComServerFactory
|
通过调度中心发过来的参数,以及执行器的处理逻辑,我们有理由可以得出此时是执行的是ExecutorBizImpl中的run方法
ExecutorBizImpl
|
通过上面我们可以发现, 执行executorBiz的run 方法的时候, 首先会通过JOBID,从本地线程库里面获取该任务对应的线程,同时,如果任务的JobHandler有更新的话,
那么会自动使用最新的jobHandler , 同时根据任务的阻塞策略。 执行不同的操作。 最终,如果是第一次执行任务的时候,系统会分配给改任务一个线程,同时启动该线程。
接下来,可以在具体看一下JobThread 的run方法,看下最终的任务是如何执行的。
JobThread
|
最后来看一下,TriggerCallbackThread.pushCallBack ()这个方法,将本次任务记录的日志ID和处理结果放入队列中去了,
TriggerCallbackThread
|
以上就是XXL-JOB从调用到处理的核心代码分析。
sharedCode源码交流群,欢迎喜欢阅读源码的朋友加群,添加下面的微信, 备注”加群“ 。