开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
工作中我们需要用到定时任务、并且需要分布式操作,而且需要java 和 go的两种解决方案,调研下感觉xxl-job不错,而且还是开源的这里分享下使用步骤
使用步骤(java)
1.1 添加maven依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
1.2 配置文件添加
# xxl-job配置
xxl:
job:
admin:
# 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
addresses: https://xxljob-qa.hexcloud.cn/xxl-job-admin/
executor:
# 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
address:
# 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册,这里填写 服务名称
appname: m82-activity-service
# 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
# 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 9999
# 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath: ./xxl-job
# 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
logretentiondays: 15
# 执行器通讯TOKEN [选填]:非空时启用;这里固定为 default_token
accessToken: default_token
1.3 添加 config 类
@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;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
1.4 编写任务代码
这里使用调度的其中一种方式,Bean 模式 方法调用的方式
为Job方法添加注解"@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
@Slf4j
@Component
public class XxlJobService {
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("jobHandler1")
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
}
}
1.5 执行器管理配置
服务配置好调度中心的地址后,需要手动在执行器管理页面创建执行器,才会自动注入并发现服务地址
- 进入【执行器管理】页面
- 点击【新增】
- 【appname】填写服务名称
- 【名称】同 appname
- 【注册方式】根据自己需求
- 【机器地址】如果是自动注册可以不用填写
1.6 任务管理添加任务
进入【任务管理页面】-> 【新增】
1.7 启动任务
使用步骤(go)
1.1 代码示例
package main
import (
"fmt"
xxl "github.com/xxl-job/xxl-job-executor-go"
"github.com/xxl-job/xxl-job-executor-go/example/task"
"log"
)
func main() {
exec := xxl.NewExecutor(
// 调度中心服务地址
xxl.ServerAddr("https://xxljob-qa.hexcloud.cn/xxl-job-admin"),
// 默认的token
xxl.AccessToken("default_token"), //请求令牌(默认为空)
//xxl.ExecutorIp("127.0.0.1"), //可自动获取
// 客户端的端口
xxl.ExecutorPort("9998"), //默认9999(非必填)
xxl.RegistryKey("calculate-go-service"), //执行器名称(可使用rancher服务名称)
xxl.SetLogger(&logger{}), //自定义日志
)
exec.Init()
//设置日志查看handler
exec.LogHandler(func(req *xxl.LogReq) *xxl.LogRes {
return &xxl.LogRes{Code: 200, Msg: "", Content: xxl.LogResContent{
FromLineNum: req.FromLineNum,
ToLineNum: 2,
LogContent: "这个是自定义日志handler",
IsEnd: true,
}}
})
//注册任务handler
exec.RegTask("task.test", task.Test)
exec.RegTask("task.test2", task.Test2)
exec.RegTask("task.panic", task.Panic)
log.Fatal(exec.Run())
}
//xxl.Logger接口实现
type logger struct{}
func (l *logger) Info(format string, a ...interface{}) {
fmt.Println(fmt.Sprintf("自定义日志 - "+format, a...))
}
func (l *logger) Error(format string, a ...interface{}) {
log.Println(fmt.Sprintf("自定义日志 - "+format, a...))
}
1.2 启动服务
1.3 执行器任务管理配置(同java示例)
1.4任务管理添加任务(同java示例)
注意,使用BEAN模式,JobHandler与RegTask名称一致
参数传递
- 在任务处填写参数
- 代码中获取参数
String jobParam = XxlJobHelper.getJobParam();
日志查看
java 需要使用XxlJobHelper.log 进行日志记录,如下示例,这样才会在调度中心显示
@XxlJob("jobHandler1")
public void demoJobHandler(String param) throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
System.out.println("我是系统打印");
for (int i = 0; i < 100; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
System.out.println("我是系统打印"+i);
}
// default success
}
- 进入【调度日志】-> 【执行日志】
日志会实时打印,
监控告警
- 首先在钉钉群创建自定义机器人
- 复制链接到这里,保存
阻塞处理策略
单机串行
a 任务在运行中,此时 b 任务也启动了,b 需要等待 a 任务执行完才开始执行
丢弃后续调度
a 任务在运行中,此时b任务也启动了,调度器会丢弃 b 任务
覆盖之前调度
a 任务在运行中,此时b任务也启动了,调度器会停掉 a 任务,然后执行 b 任务
失败重试次数
需要注意的是:失败后,10秒再次执行
更多功能请参考官方文档
java
- 官方文档:www.xuxueli.com/xxl-job/
- GITEE 文档 gitee.com/xuxueli0323…
golang
xxl-job-go :github.com/xxl-job/xxl…