新的一天,来点新的运维业务,今天是xxl-job的打通
其实在非集群中,xxl-job的使用相对是比较简单的,相信很多人都有使用的经验
这次我们的业务场景是在k8s集群中,用xxl-job来做定时调度
加上第一次倒腾,也是遇到了不少问题,在这里做一些记录
首先是xxl-job的集群安装
先贴上xxl-job sql初始化文件的地址:
xxl-job/doc/db/tables_xxl_job.sql at master · xuxueli/xxl-job · GitHub
因为k8s集群都有自己内部ip,且除了ingress通常不对外暴露ip
所以xxl-job也是推荐安装在集群内的
我的版本基于xxl-job 2.4.0,这是我的yaml:
xxl-job-admin.yaml
apiVersion: v1
kind: ConfigMap
apiVersion: v1
metadata:
name: xxl-job-config
data:
PARAMS: >-
--spring.datasource.url=jdbc:mysql://10.2.1.4:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
--spring.datasource.username=xxljob
--spring.datasource.password=abc123456
--xxl.job.accessToken=xxxxx
--server.servlet.context-path=/xxl-job-admin
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: xxl-job-admin
labels:
app: xxl-job-admin
spec:
replicas: 1
selector:
matchLabels:
app: xxl-job-admin
template:
metadata:
creationTimestamp: null
labels:
app: xxl-job-admin
spec:
containers:
- name: xxl-job-admin
image: xuxueli/xxl-job-admin:2.4.0
ports:
- containerPort: 8080
protocol: TCP
env:
- name: TZ
value: Asia/Shanghai
- name: PARAMS
valueFrom:
configMapKeyRef:
name: xxl-job-config
key: PARAMS
resources:
limits:
cpu: '1'
memory: 2Gi
requests:
cpu: 500m
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
---
apiVersion: v1
kind: Service
metadata:
name: xxl-job-admin-svc
labels:
app: xxl-job-admin-svc
spec:
ports:
- name: xxl-job-admin
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: xxl-job-admin
type: NodePort
执行kubectl apply -f xxl-job-admin.yaml等到pod成功启动即可完成xxl-job的安装了
在这里我使用的是自己集群外的mysql,觉得还是使用统一的mysql吧,也方便管理
PS: 其实刚开始根据gpt给的教程,使用env来做mysql配置的时候,访问mysql是失败的
后来找到一份网上的配置,通过这种params的方式配置docker启动参数是可以正常连接mysql了
转发端口: kubectl port-forward svc/xxl-job-admin-svc 8080:8080
访问控制台: http://localhost:8080/xxl-job-admin/jobinfo
默认的账号密码: admin 123456
访问控制台后,就是在项目里集成了
首先是添加依赖,可以使用对应版本的依赖:
com.xuxueli xxl-job-core 2.4.0
增加jobExecutor,其他配置都按照之前yaml里的填即可
有两个配置特别注明下:
1. accessToken,这里的值要跟之前yaml里配置的params里的值保持一致
2. 对于集群部署,这里ip要填null, xxl-job会自动获取集群ip
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appName);
xxlJobSpringExecutor.setIp(null);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
@Component
public class SampleJob {
@Autowired
SampleService sampleService;
@XxlJob("demoJobHandler")
public void demoJobHandler() {
XxlJobHelper.log("XXL-JOB, Hello World");
sampleService.sample(null);
}
}
根据自己的业务需要配置上所需的job,这里项目集成就做完了
其实按照网上的说法,一般服务启动以后,是可以自动注册到xxl-job上的
但是我并没有成功触发
但是通过在执行器管理里,手动添加自己填的appName对应的执行器
xxl-job也是可以正常获取到集群ip的
像这样服务就已经成功注册了
然后点击执行一次,就可以看到任务执行成功了
在服务日志里可以看到
>>>>>>>>>>> xxl-job regist JobThread success, jobId:4, handler:com.xxl.job.core.handler.impl.MethodJobHandler@5cf87cfd[class org.pjlab.xscholar.job.SampleJob#demoJobHandler]
但当我开启定时任务,5s执行一次的时候,却发现这行日志不打印了
但是在xxl-job的执行日志里,是可以看到执行都是成功的
然后了解了一下,知道是:
JobThread
,因此不会重复打印注册日志。那么到这里,xxl-job的集成也做完啦
-----------------分割线-------------------
刷到一道k8s面试题,也记录一下:
ENTRYPOINT node app.js (shell型)
ENTRYPOINT ["node", "app.js"] (exec型)
这两种启动方式有什么区别?
shell型会在容器启动以后在容器里面执行node app.js
进入容器会看到进程号1就是这个命令
这并不是我们期望的
所以一般我们用第二种(exec型)