一.业务方如何接入
代码参考 xxl-job-executor-sample-springboot项目
1.引入jar包
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
2.往spring中注入一个bean
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
3.配置文件添加
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
xxl.job.accessToken=default_token
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.ip=
xxl.job.executor.port=9999
4.编写任务
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
// default success
}
二.业务方启动流程
从上面可以得知,业务方引入的时候,需要添加bean是XxlJobSpringExecutor,将自己作为一个执行器,后续等待xxl-admin的调用,接下来我们看看XxlJobSpringExecutor这个类做了什么
1.XxlJobSpringExecutor类的继承体系
2.XxlJobSpringExecutor类的afterSingletonsInstantiated方法
@Override
public void afterSingletonsInstantiated() {
// 1.初始化 被@XxlJob注解修饰的任务,存放在jobHandlerRepository的一个map中,key=任务的名称,value=任务对应的类-方法
initJobHandlerMethodRepository(applicationContext);
// refresh GlueFactory
// 和glue相关的,不用太专注
GlueFactory.refreshInstance(1);
// 调用start方法
try {
super.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
接下来我们分析这两个核心方法
2-1.initJobHandlerMethodRepository(applicationContext);
概要:这个方法就是扫码项目,找到被@xxljob标识的方法,封装成对象放入一个map中,等待admin的调用
2-2.super.start()方法
概要:这个方法就是启动一些线程,启动netty服务端,将自己作为一个执行器注册到xxl-admin上 具体代码如下
接着进入
public void startRegistry(final String appname, final String address) {
// start registry
ExecutorRegistryThread.getInstance().start(appname, address);
}
进入start方法
逻辑比较简单,概括如下
- 1.如果服务没有停止,就90秒一次,把自己作为执行器调用xxl-admin的/api/registry方法
- 2.如果服务停止了,就调用xxl-admind /api/remove方法,将自己移除,然后停止这个线程
3.再来看start方法中的 TriggerCallbackThread线程
TriggerCallbackThread.getInstance().start();
就是从阻塞队列callBackQueue中取出值,调用admin的/api/callback方法,回调结果,callback队列是在哪里存入值?
先说答案,当admin调用执行器来触发定时任务的时候,执行器会里面返回seccess, 然后去开启线程,执行这个任务,并发执行的结果放入callBackQueue阻塞队列中
三.总结
从源码来看,xxl-job的逻辑还是比较简单的,就是spring在启动的时候,会启动netty作为服务端,等待admin调用来触发任务,同时90秒一次将自己注册到admin上,并开启一些其他线程,如回调线程等