From 1394a9fdb8200619eafff9d7223baaf993ef83cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E5=82=85=E5=93=A5?= <184172133@qq.com>
Date: Sat, 4 Nov 2023 12:31:15 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E5=82=85=E5=93=A5=EF=BC=8Cfeat?=
=?UTF-8?q?=EF=BC=9Axxl-job=20=E5=88=86=E5=B8=83=E5=BC=8F=E4=BB=BB?=
=?UTF-8?q?=E5=8A=A1=E8=B0=83=E5=BA=A6=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/dev-ops/environment/docker-compose.yml | 27 +++-
docs/dev-ops/environment/sql/xxl_job.sql | 121 ++++++++++++++++++
pom.xml | 5 +
xfg-frame-archetype-std-app/pom.xml | 4 +
.../cn/bugstack/config/XxlJobAutoConfig.java | 71 ++++++++++
.../src/main/resources/application-dev.yml | 22 ++++
xfg-frame-archetype-std-trigger/pom.xml | 6 +-
.../java/cn/bugstack/trigger/job/XXLJob.java | 20 +++
8 files changed, 274 insertions(+), 2 deletions(-)
create mode 100644 docs/dev-ops/environment/sql/xxl_job.sql
create mode 100644 xfg-frame-archetype-std-app/src/main/java/cn/bugstack/config/XxlJobAutoConfig.java
create mode 100644 xfg-frame-archetype-std-trigger/src/main/java/cn/bugstack/trigger/job/XXLJob.java
diff --git a/docs/dev-ops/environment/docker-compose.yml b/docs/dev-ops/environment/docker-compose.yml
index 816f0fe..2dd8372 100644
--- a/docs/dev-ops/environment/docker-compose.yml
+++ b/docs/dev-ops/environment/docker-compose.yml
@@ -28,7 +28,32 @@ services:
depends_on:
mysql:
condition: service_healthy
- # MySQL
+
+ # http://127.0.0.1:9090/xxl-job-admin admin/123456 - 安装后稍等会访问即可
+ # 官网镜像为 xuxueli/xxl-job-admin:2.4.0 但不支持ARM架构【需要自己打包】,所以找了一个 kuschzzp/xxl-job-aarch64:2.4.0 镜像支持 AMD/ARM
+ xxl-job-admin:
+ image: xuxueli/xxl-job-admin:2.4.0
+ container_name: xxl-job-admin
+ restart: always
+ depends_on:
+ mysql:
+ condition: service_healthy
+ ports:
+ - "9090:9090"
+ links:
+ - mysql
+ volumes:
+ - ./data/logs:/data/applogs
+ - ./data/xxl-job/:/xxl-job
+ environment:
+ - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/xxl_job?serverTimezone=UTC&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai
+ - SPRING_DATASOURCE_USERNAME=root
+ - SPRING_DATASOURCE_PASSWORD=123456
+ - SERVER_PORT=9090
+ networks:
+ - my-network
+
+ # MySQL 增加健康检测,避免
mysql:
image: mysql:8.0.32
container_name: mysql
diff --git a/docs/dev-ops/environment/sql/xxl_job.sql b/docs/dev-ops/environment/sql/xxl_job.sql
new file mode 100644
index 0000000..a2cc4c2
--- /dev/null
+++ b/docs/dev-ops/environment/sql/xxl_job.sql
@@ -0,0 +1,121 @@
+# 获取地址:https://github.com/xuxueli/xxl-job/tree/master/doc/db
+# XXL-JOB v2.4.1-SNAPSHOT
+# Copyright (c) 2015-present, xuxueli.
+
+CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_0900_ai_ci;
+use `xxl_job`;
+
+SET NAMES utf8mb4;
+
+CREATE TABLE `xxl_job_info` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
+ `job_desc` varchar(255) NOT NULL,
+ `add_time` datetime DEFAULT NULL,
+ `update_time` datetime DEFAULT NULL,
+ `author` varchar(64) DEFAULT NULL COMMENT '作者',
+ `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
+ `schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
+ `schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
+ `misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
+ `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
+ `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
+ `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
+ `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
+ `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
+ `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
+ `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
+ `glue_source` mediumtext COMMENT 'GLUE源代码',
+ `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
+ `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
+ `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
+ `trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
+ `trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
+ `trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_log` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
+ `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
+ `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
+ `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
+ `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
+ `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
+ `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
+ `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
+ `trigger_code` int(11) NOT NULL COMMENT '调度-结果',
+ `trigger_msg` text COMMENT '调度-日志',
+ `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
+ `handle_code` int(11) NOT NULL COMMENT '执行-状态',
+ `handle_msg` text COMMENT '执行-日志',
+ `alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
+ PRIMARY KEY (`id`),
+ KEY `I_trigger_time` (`trigger_time`),
+ KEY `I_handle_code` (`handle_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_log_report` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
+ `running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
+ `suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
+ `fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
+ `update_time` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_logglue` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
+ `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
+ `glue_source` mediumtext COMMENT 'GLUE源代码',
+ `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
+ `add_time` datetime DEFAULT NULL,
+ `update_time` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_registry` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `registry_group` varchar(50) NOT NULL,
+ `registry_key` varchar(255) NOT NULL,
+ `registry_value` varchar(255) NOT NULL,
+ `update_time` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_group` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
+ `title` varchar(12) NOT NULL COMMENT '执行器名称',
+ `address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
+ `address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
+ `update_time` datetime DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_user` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `username` varchar(50) NOT NULL COMMENT '账号',
+ `password` varchar(50) NOT NULL COMMENT '密码',
+ `role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
+ `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `i_username` (`username`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE `xxl_job_lock` (
+ `lock_name` varchar(50) NOT NULL COMMENT '锁名称',
+ PRIMARY KEY (`lock_name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
+INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
+INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
+INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');
+
+commit;
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9707eee..7301d74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,6 +131,11 @@
snakeyaml
1.33
+
+ com.xuxueli
+ xxl-job-core
+ 2.4.0
+
diff --git a/xfg-frame-archetype-std-app/pom.xml b/xfg-frame-archetype-std-app/pom.xml
index 4cf6c37..2932a86 100644
--- a/xfg-frame-archetype-std-app/pom.xml
+++ b/xfg-frame-archetype-std-app/pom.xml
@@ -102,6 +102,10 @@
org.yaml
snakeyaml
+
+ com.xuxueli
+ xxl-job-core
+
diff --git a/xfg-frame-archetype-std-app/src/main/java/cn/bugstack/config/XxlJobAutoConfig.java b/xfg-frame-archetype-std-app/src/main/java/cn/bugstack/config/XxlJobAutoConfig.java
new file mode 100644
index 0000000..88d24c1
--- /dev/null
+++ b/xfg-frame-archetype-std-app/src/main/java/cn/bugstack/config/XxlJobAutoConfig.java
@@ -0,0 +1,71 @@
+package cn.bugstack.config;
+
+import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Slf4j
+@Configuration
+public class XxlJobAutoConfig {
+
+ @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() {
+ log.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、引入依赖:
+ *
+ * org.springframework.cloud
+ * spring-cloud-commons
+ * ${version}
+ *
+ *
+ * 2、配置文件,或者容器启动变量
+ * spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
+ *
+ * 3、获取IP
+ * String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
+ **********************************************************************************************/
+
+}
diff --git a/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml b/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
index 38f3d51..95db537 100644
--- a/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
+++ b/xfg-frame-archetype-std-app/src/main/resources/application-dev.yml
@@ -52,6 +52,28 @@ dubbo:
scan:
base-packages: cn.bugstack.api
+# xxl-job https://www.xuxueli.com/xxl-job/#%E6%AD%A5%E9%AA%A4%E4%B8%80%EF%BC%9A%E8%B0%83%E5%BA%A6%E4%B8%AD%E5%BF%83%E9%85%8D%E7%BD%AE%EF%BC%9A
+xxl:
+ job:
+ # 验证信息 官网Bug https://github.com/xuxueli/xxl-job/issues/1951
+ accessToken: default_token
+ # 注册地址
+ admin:
+ addresses: http://localhost:9090/xxl-job-admin
+ # 注册执行器
+ executor:
+ # 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
+ address:
+ appname: xxl-job-executor-sample
+ # 执行器IP 配置为本机IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
+ ip:
+ # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
+ port: 9999
+ # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
+ logpath: ./data/applogs/xxl-job/jobhandler
+ # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
+ logretentiondays: 30
+
# 日志
logging:
level:
diff --git a/xfg-frame-archetype-std-trigger/pom.xml b/xfg-frame-archetype-std-trigger/pom.xml
index 4db8b62..58ae619 100644
--- a/xfg-frame-archetype-std-trigger/pom.xml
+++ b/xfg-frame-archetype-std-trigger/pom.xml
@@ -26,7 +26,6 @@
org.apache.commons
commons-lang3
-
org.apache.dubbo
dubbo
@@ -35,6 +34,11 @@
org.apache.dubbo
dubbo-spring-boot-starter
+
+ com.xuxueli
+ xxl-job-core
+
+
diff --git a/xfg-frame-archetype-std-trigger/src/main/java/cn/bugstack/trigger/job/XXLJob.java b/xfg-frame-archetype-std-trigger/src/main/java/cn/bugstack/trigger/job/XXLJob.java
new file mode 100644
index 0000000..1559fef
--- /dev/null
+++ b/xfg-frame-archetype-std-trigger/src/main/java/cn/bugstack/trigger/job/XXLJob.java
@@ -0,0 +1,20 @@
+package cn.bugstack.trigger.job;
+
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * XXL-Job
+ */
+@Slf4j
+@Component
+public class XXLJob {
+
+ @XxlJob("demoJobHandler")
+ public void doJob() {
+ // 可以在任务中,调用一些业务方法逻辑的实现,如定时扫描超时未支付订单为关单处理,恢复库存
+ log.info("执行任务 - XXL-Job - 01");
+ }
+
+}
--
GitLab