因为一般集群都带了xxl-job-admin微服务,这里只说如何集成。
我们常说的xxjob全称是xxl-job,之所以读xxjob,就是为了易读。
maven依赖:
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</dependency>
xxl:
job:
admin:
# 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
addresses: http://192.168.0.1/xxl-job-admin
# 执行器通讯TOKEN [选填]:非空时启用;
accessToken: default_token
executor:
# 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
appname: xxl-job-test
address:
# 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
# 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 9997
# 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath: /data/logs/xxl-job/jobhandler
# 执行器日志保存天数 [选填] :值大于3时生效,启用执行器Log文件定期清理功能,否则不生效;
logretentiondays: 7
直接从git项目复制过来一份。
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@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;
}
}
代码:
@Slf4j
@Component
public class EntranceJobHandler {
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
System.out.println("XXL-JOB Hello World");
// 获取参数
String param = XxlJobHelper.getJobParam();
log.info("接收调度中心参数:\n{}", param);
// 控制台输出日志
log.info("myXxlJobHandler execute...");
try {
//书写业务逻辑
// TODO-MICHAEL: 2018/10/25
// 写日志到调度中心日志中
XxlJobHelper.log("myXxlJobHandler execute Success...");
// 设置任务结果
XxlJobHelper.handleSuccess();
} catch (Exception e) {
log.error("myXxlJobHandler execute Fail ...", e);
//写日志到调度中心日志中
XxlJobHelper.log("myXxlJobHandler execute Fail...");
// 设置任务结果
XxlJobHelper.handleFail();
}
}
}
然后启动项目即可。
1、新增执行器(执行器可以理解为就是微服务)。
2、新增任务(一个执行器可以有多个任务),点立即执行,再点查看日志就可以看效果。
问: 为什么找不到@JobHandler了?
很简单,他过时了,最新的注解是 @XxlJob。
我们看下JobHandler的源码就一目了然:
// * will be replaced by {@link com.xxl.job.core.handler.annotation.XxlJob}
// *
// * @author 2016-5-17 21:06:49
// */
//@Target({ElementType.TYPE})
//@Retention(RetentionPolicy.RUNTIME)
//@Inherited
//@Deprecated
//public @interface JobHandler {
//
// String value();
//
//}
对,你没看错,都被注释掉了,关键的还有一句
will be replaced by {@link com.xxl.job.core.handler.annotation.XxlJob}
已经被@XxlJob替代了。
这个问题有多重因素,要逐个排查。
1、执行器地址对不对。
2、jobHandler的名称对不对。
3、jobConfig是否加载。
4、jobHandler是否加载。
XxlJobConfig 确认是否加载
发现果然没有加载,这个是启动的时候就加载。
@XxlJob(“demoJobHandler”) 所在类是否加载
实际上也没有加载,这个是使用的时候加载,所以方法里的日志不会直接打出来。
Application的package及子package的类会自动加载,否则不会加载。
调整下未加载类到Application的package及子package即可。
另外一种思路:
Application放到高层级的目录,例如直接放到com目录下。
码云的git地址(实测可用):
https://gitee.com/xuxueli0323/xxl-job
这里面有源码,包括示例等。
默认是在代码里面写死了,直接用就可以。
public class JobInfoControllerTest extends AbstractSpringMvcTest {
private static Logger logger = LoggerFactory.getLogger(JobInfoControllerTest.class);
private Cookie cookie;
@BeforeEach
public void login() throws Exception {
MvcResult ret = mockMvc.perform(
post("/login")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("userName", "admin")
.param("password", "123456")
).andReturn();
cookie = ret.getResponse().getCookie(LoginService.LOGIN_IDENTITY_KEY);
}
}