pull/7199/head
JEECG 2024-08-22 15:15:04 +08:00
commit ca2a56248c
66 changed files with 1765 additions and 846 deletions

View File

@ -290,7 +290,7 @@ public class ShiroConfig {
RedisSentinelManager sentinelManager = new RedisSentinelManager();
sentinelManager.setMasterName(redisProperties.getSentinel().getMaster());
sentinelManager.setHost(String.join(",", redisProperties.getSentinel().getNodes()));
sentinelManager.setPassword(redisProperties.getSentinel().getPassword());
sentinelManager.setPassword(redisProperties.getPassword());
sentinelManager.setDatabase(redisProperties.getDatabase());
return sentinelManager;

View File

@ -1,119 +1,283 @@
#
# XXL-JOB v2.2.0
# Copyright (c) 2015-present, xuxueli.
/*
Navicat Premium Data Transfer
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci;
use `xxl_job`;
Source Server : mysql5.7
Source Server Type : MySQL
Source Server Version : 50738
Source Host : 127.0.0.1:3306
Source Schema : xxl_job_241
Target Server Type : MySQL
Target Server Version : 50738
File Encoding : 65001
Date: 21/08/2024 22:43:14
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `xxl_job_info` (
-- ----------------------------
-- Table structure for xxl_job_group
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_group`;
CREATE TABLE `xxl_job_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'AppName',
`title` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
`address_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0=1=',
`address_list` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '',
`update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of xxl_job_group
-- ----------------------------
INSERT INTO `xxl_job_group` VALUES (1, 'xxl-job-executor-sample', '', 0, NULL, '2024-08-21 22:42:43');
INSERT INTO `xxl_job_group` VALUES (2, 'jeecg-demo', 'Demo', 0, 'http://192.168.0.105:10001/', '2024-08-21 22:42:43');
INSERT INTO `xxl_job_group` VALUES (3, 'jeecg-system', 'System', 0, 'http://192.168.0.105:10002/', '2024-08-21 22:42:43');
-- ----------------------------
-- Table structure for xxl_job_info
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_info`;
CREATE TABLE `xxl_job_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT 'ID',
`job_cron` varchar(128) NOT NULL COMMENT 'CRON',
`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 '',
`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;
`job_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`add_time` datetime NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL,
`author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`alarm_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`schedule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NONE' COMMENT '',
`schedule_conf` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`misfire_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DO_NOTHING' COMMENT '',
`executor_route_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'handler',
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_block_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE',
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE',
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE',
`glue_updatetime` datetime NULL DEFAULT NULL COMMENT 'GLUE',
`child_jobid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL 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`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `xxl_job_log` (
-- ----------------------------
-- Records of xxl_job_info
-- ----------------------------
INSERT INTO `xxl_job_info` VALUES (1, 1, '1', '2018-11-03 22:21:31', '2024-08-21 22:30:30', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE', '2018-11-03 22:21:31', '', 1, 0, 1724256000000);
INSERT INTO `xxl_job_info` VALUES (2, 3, 'jeecg xxljob', '2024-08-21 22:41:10', '2024-08-21 22:41:30', 'JEECG', '', 'CRON', '* * * * * ?', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE', '2024-08-21 22:41:10', '', 1, 1724251373000, 1724251374000);
-- ----------------------------
-- Table structure for xxl_job_lock
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_lock`;
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
PRIMARY KEY (`lock_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of xxl_job_lock
-- ----------------------------
INSERT INTO `xxl_job_lock` VALUES ('schedule_lock');
-- ----------------------------
-- Table structure for xxl_job_log
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_log`;
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 '-',
`executor_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'handler',
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_sharding_param` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT ' 1/2',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '',
`trigger_time` datetime NULL DEFAULT NULL COMMENT '-',
`trigger_code` int(11) NOT NULL COMMENT '-',
`trigger_msg` text COMMENT '-',
`handle_time` datetime DEFAULT NULL COMMENT '-',
`trigger_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '-',
`handle_time` datetime NULL 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;
`handle_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '-',
`alarm_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-1-2-3-',
PRIMARY KEY (`id`) USING BTREE,
INDEX `I_trigger_time`(`trigger_time`) USING BTREE,
INDEX `I_handle_code`(`handle_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 82 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `xxl_job_log_report` (
-- ----------------------------
-- Records of xxl_job_log
-- ----------------------------
INSERT INTO `xxl_job_log` VALUES (1, 1, 1, NULL, 'demoJobHandler', '', NULL, 0, '2024-08-21 22:29:07', 500, '<br>192.168.0.105<br>-<br>-null<br><br><br>0<br>0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>><<<<<<<<<<< </span><br><br><br>', NULL, 0, NULL, 2);
INSERT INTO `xxl_job_log` VALUES (2, 1, 1, NULL, 'demoJobHandler', '', NULL, 0, '2024-08-21 22:29:48', 500, '<br>192.168.0.105<br>-<br>-null<br><br><br>0<br>0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>><<<<<<<<<<< </span><br><br><br>', NULL, 0, NULL, 2);
INSERT INTO `xxl_job_log` VALUES (3, 1, 1, NULL, 'demoJob', '', NULL, 0, '2024-08-21 22:30:34', 500, '<br>192.168.0.105<br>-<br>-null<br><br><br>0<br>0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>><<<<<<<<<<< </span><br><br><br>', NULL, 0, NULL, 2);
INSERT INTO `xxl_job_log` VALUES (4, 1, 1, NULL, 'demoJob', '', NULL, 0, '2024-08-21 22:30:40', 500, '<br>192.168.0.105<br>-<br>-null<br><br><br>0<br>0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>><<<<<<<<<<< </span><br><br><br>', NULL, 0, NULL, 2);
INSERT INTO `xxl_job_log` VALUES (5, 2, 2, 'http://192.168.0.105:10001/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:14', 500, '任务触发类型:手动触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10001/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10001/<br>code500<br>msgjob handler [demoJob] not found.', NULL, 0, NULL, 2);
INSERT INTO `xxl_job_log` VALUES (6, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:27', 200, '任务触发类型:手动触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:27', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (7, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:36', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:36', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (8, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:37', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:37', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (9, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:38', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:38', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (10, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:39', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:39', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (11, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:40', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:40', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (12, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:40', 200, '任务触发类型:手动触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:40', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (13, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:41', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:41', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (14, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:42', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:42', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (15, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:43', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:43', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (16, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:44', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:44', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (17, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:45', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:45', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (18, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:46', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:46', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (19, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:47', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:47', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (20, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:48', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:48', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (21, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:49', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:49', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (22, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:50', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:50', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (23, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:51', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:51', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (24, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:52', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:52', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (25, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:53', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:53', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (26, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:54', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:54', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (27, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:55', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:55', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (28, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:56', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:56', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (29, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:57', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:57', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (30, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:58', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:58', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (31, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:41:59', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:41:59', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (32, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:00', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:00', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (33, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:01', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:01', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (34, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:02', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:02', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (35, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:03', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:03', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (36, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:04', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:04', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (37, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:05', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:05', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (38, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:06', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:06', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (39, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:07', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:07', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (40, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:08', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:08', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (41, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:09', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:09', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (42, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:10', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:10', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (43, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:11', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:11', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (44, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:12', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:12', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (45, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:13', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:13', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (46, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:14', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:14', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (47, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:15', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:15', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (48, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:16', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:16', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (49, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:17', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:17', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (50, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:18', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:18', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (51, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:19', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:19', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (52, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:20', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:20', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (53, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:21', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:21', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (54, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:22', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:22', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (55, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:23', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:23', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (56, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:24', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:24', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (57, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:25', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:25', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (58, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:26', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:26', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (59, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:27', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:27', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (60, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:28', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:28', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (61, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:29', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:29', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (62, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:30', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:30', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (63, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:31', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:31', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (64, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:32', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:32', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (65, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:33', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:33', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (66, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:34', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:34', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (67, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:35', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:35', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (68, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:36', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:36', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (69, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:37', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:37', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (70, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:38', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:38', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (71, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:39', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:39', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (72, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:40', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:40', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (73, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:41', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:41', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (74, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:42', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:42', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (75, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:43', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:43', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (76, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:44', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:44', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (77, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:45', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:45', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (78, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:46', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:46', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (79, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:47', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:47', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (80, 3, 2, 'http://192.168.0.105:10002/', 'demoJob', '', NULL, 0, '2024-08-21 22:42:48', 200, '任务触发类型Cron触发<br>调度机器192.168.0.105<br>执行器-注册方式:自动注册<br>执行器-地址列表:[http://192.168.0.105:10002/]<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间0<br>失败重试次数0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>触发调度:<br>addresshttp://192.168.0.105:10002/<br>code200<br>msgnull', '2024-08-21 22:42:48', 0, '', 0);
INSERT INTO `xxl_job_log` VALUES (81, 3, 2, NULL, NULL, NULL, NULL, 0, '2024-08-21 22:42:49', 0, NULL, NULL, 0, NULL, 0);
-- ----------------------------
-- Table structure for xxl_job_log_report
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_log_report`;
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 '-',
PRIMARY KEY (`id`),
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`trigger_day` datetime NULL 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 NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `i_trigger_day`(`trigger_day`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `xxl_job_logglue` (
-- ----------------------------
-- Records of xxl_job_log_report
-- ----------------------------
INSERT INTO `xxl_job_log_report` VALUES (1, '2024-08-21 00:00:00', 70, 0, 5, NULL);
INSERT INTO `xxl_job_log_report` VALUES (2, '2024-08-20 00:00:00', 0, 0, 0, NULL);
INSERT INTO `xxl_job_log_report` VALUES (3, '2024-08-19 00:00:00', 0, 0, 0, NULL);
-- ----------------------------
-- Table structure for xxl_job_logglue
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_logglue`;
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;
`glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE',
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE',
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE',
`add_time` datetime NULL DEFAULT NULL,
`update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
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;
-- ----------------------------
-- Records of xxl_job_logglue
-- ----------------------------
CREATE TABLE `xxl_job_group` (
-- ----------------------------
-- Table structure for xxl_job_registry
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_registry`;
CREATE TABLE `xxl_job_registry` (
`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` varchar(512) DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
`registry_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`registry_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`registry_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `i_g_k_v`(`registry_group`, `registry_key`, `registry_value`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `xxl_job_user` (
-- ----------------------------
-- Records of xxl_job_registry
-- ----------------------------
INSERT INTO `xxl_job_registry` VALUES (1, 'EXECUTOR', 'jeecg-demo', 'http://192.168.0.105:10001/', '2024-08-21 22:42:43');
INSERT INTO `xxl_job_registry` VALUES (3, 'EXECUTOR', 'jeecg-system', 'http://192.168.0.105:10002/', '2024-08-21 22:42:21');
-- ----------------------------
-- Table structure for xxl_job_user
-- ----------------------------
DROP TABLE IF EXISTS `xxl_job_user`;
CREATE TABLE `xxl_job_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '',
`password` varchar(50) NOT NULL COMMENT '',
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci 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;
`permission` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ID',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `i_username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
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`) VALUES (1, 'xxl-job-executor-sample', '', 0, NULL);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_cron`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `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, '0 0 0 * * ? *', '1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', '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;
-- ----------------------------
-- Records of xxl_job_user
-- ----------------------------
INSERT INTO `xxl_job_user` VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -39,7 +39,7 @@
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
<version>2.3.2</version>
</dependency>
<!-- mysql -->
<dependency>

View File

@ -1,16 +1,27 @@
package com.xxl.job.admin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
/**
* @author xuxueli 2018-10-28 00:38:13
*/
@SpringBootApplication
@Slf4j
public class XxlJobAdminApplication {
public static void main(String[] args) {
SpringApplication.run(XxlJobAdminApplication.class, args);
ConfigurableApplicationContext application = SpringApplication.run(XxlJobAdminApplication.class, args);
Environment env = application.getEnvironment();
String port = env.getProperty("server.port");
String path = env.getProperty("server.servlet.context-path");
log.info("\n----------------------------------------------------------\n\t" +
"Application XxlJobAdmin is running! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port + path + "/\n\t" +
"----------------------------------------------------------");
}
}

View File

@ -12,6 +12,8 @@ import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@ -51,11 +53,12 @@ public class IndexController {
@RequestMapping("/toLogin")
@PermissionLimit(limit=false)
public String toLogin(HttpServletRequest request, HttpServletResponse response) {
public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response,ModelAndView modelAndView) {
if (loginService.ifLogin(request, response) != null) {
return "redirect:/";
modelAndView.setView(new RedirectView("/",true,false));
return modelAndView;
}
return "login";
return new ModelAndView("login");
}
@RequestMapping(value="login", method=RequestMethod.POST)

View File

@ -1,5 +1,6 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.admin.core.util.I18nUtil;
@ -34,12 +35,14 @@ public class JobGroupController {
private XxlJobRegistryDao xxlJobRegistryDao;
@RequestMapping
@PermissionLimit(adminuser = true)
public String index(Model model) {
return "jobgroup/jobgroup.index";
}
@RequestMapping("/pageList")
@ResponseBody
@PermissionLimit(adminuser = true)
public Map<String, Object> pageList(HttpServletRequest request,
@RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length,
@ -59,6 +62,7 @@ public class JobGroupController {
@RequestMapping("/save")
@ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> save(XxlJobGroup xxlJobGroup){
// valid
@ -68,13 +72,23 @@ public class JobGroupController {
if (xxlJobGroup.getAppname().length()<4 || xxlJobGroup.getAppname().length()>64) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length") );
}
if (xxlJobGroup.getAppname().contains(">") || xxlJobGroup.getAppname().contains("<")) {
return new ReturnT<String>(500, "AppName"+I18nUtil.getString("system_unvalid") );
}
if (xxlJobGroup.getTitle()==null || xxlJobGroup.getTitle().trim().length()==0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) );
}
if (xxlJobGroup.getTitle().contains(">") || xxlJobGroup.getTitle().contains("<")) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_title")+I18nUtil.getString("system_unvalid") );
}
if (xxlJobGroup.getAddressType()!=0) {
if (xxlJobGroup.getAddressList()==null || xxlJobGroup.getAddressList().trim().length()==0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit") );
}
if (xxlJobGroup.getAddressList().contains(">") || xxlJobGroup.getAddressList().contains("<")) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_registryList")+I18nUtil.getString("system_unvalid") );
}
String[] addresss = xxlJobGroup.getAddressList().split(",");
for (String item: addresss) {
if (item==null || item.trim().length()==0) {
@ -83,12 +97,16 @@ public class JobGroupController {
}
}
// process
xxlJobGroup.setUpdateTime(new Date());
int ret = xxlJobGroupDao.save(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
}
@RequestMapping("/update")
@ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> update(XxlJobGroup xxlJobGroup){
// valid
if (xxlJobGroup.getAppname()==null || xxlJobGroup.getAppname().trim().length()==0) {
@ -126,6 +144,9 @@ public class JobGroupController {
}
}
// process
xxlJobGroup.setUpdateTime(new Date());
int ret = xxlJobGroupDao.update(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
}
@ -154,6 +175,7 @@ public class JobGroupController {
@RequestMapping("/remove")
@ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> remove(int id){
// valid
@ -173,6 +195,7 @@ public class JobGroupController {
@RequestMapping("/loadById")
@ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<XxlJobGroup> loadById(int id){
XxlJobGroup jobGroup = xxlJobGroupDao.load(id);
return jobGroup!=null?new ReturnT<XxlJobGroup>(jobGroup):new ReturnT<XxlJobGroup>(ReturnT.FAIL_CODE, null);

View File

@ -1,13 +1,13 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.service.LoginService;
@ -16,6 +16,8 @@ import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.glue.GlueTypeEnum;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@ -24,7 +26,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*;
/**
@ -34,6 +35,7 @@ import java.util.*;
@Controller
@RequestMapping("/jobinfo")
public class JobInfoController {
private static Logger logger = LoggerFactory.getLogger(JobInfoController.class);
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@ -47,6 +49,8 @@ public class JobInfoController {
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典
model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型
model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略
// 执行器列表
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
@ -131,36 +135,38 @@ public class JobInfoController {
@RequestMapping("/trigger")
@ResponseBody
//@PermissionLimit(limit = false)
public ReturnT<String> triggerJob(int id, String executorParam, String addressList) {
// force cover job param
if (executorParam == null) {
executorParam = "";
}
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
return ReturnT.SUCCESS;
public ReturnT<String> triggerJob(HttpServletRequest request, int id, String executorParam, String addressList) {
// login user
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
// trigger
return xxlJobService.trigger(loginUser, id, executorParam, addressList);
}
@RequestMapping("/nextTriggerTime")
@ResponseBody
public ReturnT<List<String>> nextTriggerTime(String cron) {
public ReturnT<List<String>> nextTriggerTime(String scheduleType, String scheduleConf) {
XxlJobInfo paramXxlJobInfo = new XxlJobInfo();
paramXxlJobInfo.setScheduleType(scheduleType);
paramXxlJobInfo.setScheduleConf(scheduleConf);
List<String> result = new ArrayList<>();
try {
CronExpression cronExpression = new CronExpression(cron);
Date lastTime = new Date();
for (int i = 0; i < 5; i++) {
lastTime = cronExpression.getNextValidTimeAfter(lastTime);
lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
if (lastTime != null) {
result.add(DateUtil.formatDateTime(lastTime));
} else {
break;
}
}
} catch (ParseException e) {
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid"));
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) + e.getMessage());
}
return new ReturnT<List<String>>(result);
}
}

View File

@ -1,5 +1,6 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.core.complete.XxlJobCompleter;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
@ -19,9 +20,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@ -128,27 +131,38 @@ public class JobLogController {
model.addAttribute("triggerCode", jobLog.getTriggerCode());
model.addAttribute("handleCode", jobLog.getHandleCode());
model.addAttribute("executorAddress", jobLog.getExecutorAddress());
model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime());
model.addAttribute("logId", jobLog.getId());
return "joblog/joblog.detail";
}
@RequestMapping("/logDetailCat")
@ResponseBody
public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum){
public ReturnT<LogResult> logDetailCat(long logId, int fromLineNum){
try {
ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress);
ReturnT<LogResult> logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum));
// valid
XxlJobLog jobLog = xxlJobLogDao.load(logId); // todo, need to improve performance
if (jobLog == null) {
return new ReturnT<LogResult>(ReturnT.FAIL_CODE, I18nUtil.getString("joblog_logid_unvalid"));
}
// log cat
ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(jobLog.getExecutorAddress());
ReturnT<LogResult> logResult = executorBiz.log(new LogParam(jobLog.getTriggerTime().getTime(), logId, fromLineNum));
// is end
if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
XxlJobLog jobLog = xxlJobLogDao.load(logId);
if (jobLog.getHandleCode() > 0) {
logResult.getContent().setEnd(true);
}
}
// fix xss
if (logResult.getContent()!=null && StringUtils.hasText(logResult.getContent().getLogContent())) {
String newLogContent = logResult.getContent().getLogContent();
newLogContent = HtmlUtils.htmlEscape(newLogContent, "UTF-8");
logResult.getContent().setLogContent(newLogContent);
}
return logResult;
} catch (Exception e) {
logger.error(e.getMessage(), e);
@ -183,7 +197,7 @@ public class JobLogController {
log.setHandleCode(ReturnT.FAIL_CODE);
log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():""));
log.setHandleTime(new Date());
xxlJobLogDao.updateHandleInfo(log);
XxlJobCompleter.updateHandleInfoAndFinish(log);
return new ReturnT<String>(runResult.getMsg());
} else {
return new ReturnT<String>(500, runResult.getMsg());

View File

@ -56,6 +56,13 @@ public class UserController {
List<XxlJobUser> list = xxlJobUserDao.pageList(start, length, username, role);
int list_count = xxlJobUserDao.pageListCount(start, length, username, role);
// filter
if (list!=null && list.size()>0) {
for (XxlJobUser item: list) {
item.setPassword(null);
}
}
// package result
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数

View File

@ -3,8 +3,8 @@ package com.xxl.job.admin.controller.interceptor;
import com.xxl.job.admin.core.util.FtlUtil;
import com.xxl.job.admin.core.util.I18nUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@ -17,7 +17,7 @@ import java.util.HashMap;
* @author xuxueli 2015-12-12 18:09:04
*/
@Component
public class CookieInterceptor extends HandlerInterceptorAdapter {
public class CookieInterceptor implements AsyncHandlerInterceptor {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@ -36,8 +36,7 @@ public class CookieInterceptor extends HandlerInterceptorAdapter {
if (modelAndView != null) {
modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName()));
}
super.postHandle(request, response, handler, modelAndView);
}
}

View File

@ -6,7 +6,7 @@ import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.service.LoginService;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@ -18,7 +18,7 @@ import javax.servlet.http.HttpServletResponse;
* @author xuxueli 2015-12-12 18:09:04
*/
@Component
public class PermissionInterceptor extends HandlerInterceptorAdapter {
public class PermissionInterceptor implements AsyncHandlerInterceptor {
@Resource
private LoginService loginService;
@ -27,7 +27,7 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return super.preHandle(request, response, handler);
return true; // proceed with the next interceptor
}
// if need login
@ -43,8 +43,8 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
if (needLogin) {
XxlJobUser loginUser = loginService.ifLogin(request, response);
if (loginUser == null) {
response.sendRedirect(request.getContextPath() + "/toLogin");
//request.getRequestDispatcher("/toLogin").forward(request, response);
response.setStatus(302);
response.setHeader("location", request.getContextPath()+"/toLogin");
return false;
}
if (needAdminuser && loginUser.getRole()!=1) {
@ -53,7 +53,7 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
}
return super.preHandle(request, response, handler);
return true; // proceed with the next interceptor
}
}

View File

@ -34,10 +34,12 @@ public class WebExceptionResolver implements HandlerExceptionResolver {
// if json
boolean isJson = false;
HandlerMethod method = (HandlerMethod)handler;
ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
if (responseBody != null) {
isJson = true;
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod)handler;
ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
if (responseBody != null) {
isJson = true;
}
}
// error result

View File

@ -66,7 +66,7 @@ public class EmailJobAlarm implements JobAlarm {
MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailUserName(), personal);
helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailFrom(), personal);
helper.setTo(email);
helper.setSubject(title);
helper.setText(content, true);

View File

@ -0,0 +1,99 @@
package com.xxl.job.admin.core.complete;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
/**
* @author xuxueli 2020-10-30 20:43:10
*/
public class XxlJobCompleter {
private static Logger logger = LoggerFactory.getLogger(XxlJobCompleter.class);
/**
* common fresh handle entrance (limit only once)
*
* @param xxlJobLog
* @return
*/
public static int updateHandleInfoAndFinish(XxlJobLog xxlJobLog) {
// finish
finishJob(xxlJobLog);
// text最大64kb 避免长度过长
if (xxlJobLog.getHandleMsg().length() > 15000) {
xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg().substring(0, 15000) );
}
// fresh handle
return XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(xxlJobLog);
}
/**
* do somethind to finish job
*/
private static void finishJob(XxlJobLog xxlJobLog){
// 1、handle success, to trigger child job
String triggerChildMsg = null;
if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getHandleCode()) {
XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< </span><br>";
String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
for (int i = 0; i < childJobIds.length; i++) {
int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
if (childJobId > 0) {
JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
ReturnT<String> triggerChildResult = ReturnT.SUCCESS;
// add msg
triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"),
(i+1),
childJobIds.length,
childJobIds[i],
(triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")),
triggerChildResult.getMsg());
} else {
triggerChildMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"),
(i+1),
childJobIds.length,
childJobIds[i]);
}
}
}
}
if (triggerChildMsg != null) {
xxlJobLog.setHandleMsg( xxlJobLog.getHandleMsg() + triggerChildMsg );
}
// 2、fix_delay trigger next
// on the way
}
private static boolean isNumeric(String str){
try {
int result = Integer.valueOf(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}

View File

@ -55,8 +55,8 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${spring.mail.username}")
private String emailUserName;
@Value("${spring.mail.from}")
private String emailFrom;
@Value("${xxl.job.triggerpool.fast.max}")
private int triggerPoolFastMax;
@ -98,8 +98,8 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
return accessToken;
}
public String getEmailUserName() {
return emailUserName;
public String getEmailFrom() {
return emailFrom;
}
public int getTriggerPoolFastMax() {

View File

@ -265,7 +265,7 @@ public final class CronExpression implements Serializable, Cloneable {
*
* @param cronExpression String representation of the cron expression the
* new object should represent
* @throws java.text.ParseException
* @throws ParseException
* if the string expression cannot be parsed into a valid
* <CODE>CronExpression</CODE>
*/
@ -363,9 +363,8 @@ public final class CronExpression implements Serializable, Cloneable {
// the second immediately following it.
while (difference == 1000) {
newDate = getTimeAfter(lastDate);
if(newDate == null) {
if(newDate == null)
break;
}
difference = newDate.getTime() - lastDate.getTime();
@ -533,7 +532,7 @@ public final class CronExpression implements Serializable, Cloneable {
return i;
}
char c = s.charAt(i);
if ((c >= 'A') && (c <= 'Z') && (!"L".equals(s)) && (!"LW".equals(s)) && (!s.matches("^L-[0-9]*[W]?"))) {
if ((c >= 'A') && (c <= 'Z') && (!s.equals("L")) && (!s.equals("LW")) && (!s.matches("^L-[0-9]*[W]?"))) {
String sub = s.substring(i, i + 3);
int sval = -1;
int eval = -1;
@ -669,9 +668,8 @@ public final class CronExpression implements Serializable, Cloneable {
if(c == '-') {
ValueSet vs = getValue(0, s, i+1);
lastdayOffset = vs.value;
if(lastdayOffset > 30) {
if(lastdayOffset > 30)
throw new ParseException("Offset from last day must be <= 30", i+1);
}
i = vs.pos;
}
if(s.length() > i) {
@ -734,9 +732,8 @@ public final class CronExpression implements Serializable, Cloneable {
if (c == 'L') {
if (type == DAY_OF_WEEK) {
if(val < 1 || val > 7) {
if(val < 1 || val > 7)
throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
}
lastdayOfWeek = true;
} else {
throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
@ -753,9 +750,8 @@ public final class CronExpression implements Serializable, Cloneable {
} else {
throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
}
if(val > 31) {
throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
}
if(val > 31)
throw new ParseException("The 'W' option does not make sense with values larger than 31 (max number of days in a month)", i);
TreeSet<Integer> set = getSet(type);
set.add(val);
i++;
@ -1284,7 +1280,7 @@ public final class CronExpression implements Serializable, Cloneable {
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
day -= lastdayOffset;
java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
Calendar tcal = Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0);
@ -1320,7 +1316,7 @@ public final class CronExpression implements Serializable, Cloneable {
t = day;
day = daysOfMonth.first();
java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
Calendar tcal = Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0);
@ -1584,9 +1580,9 @@ public final class CronExpression implements Serializable, Cloneable {
* @param hour the hour to set
*/
protected void setCalendarHour(Calendar cal, int hour) {
cal.set(java.util.Calendar.HOUR_OF_DAY, hour);
if (cal.get(java.util.Calendar.HOUR_OF_DAY) != hour && hour != 24) {
cal.set(java.util.Calendar.HOUR_OF_DAY, hour + 1);
cal.set(Calendar.HOUR_OF_DAY, hour);
if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) {
cal.set(Calendar.HOUR_OF_DAY, hour + 1);
}
}

View File

@ -2,6 +2,7 @@ package com.xxl.job.admin.core.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
@ -14,6 +15,7 @@ public class XxlJobGroup {
private String title;
private int addressType; // 执行器地址类型0=自动注册、1=手动录入
private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
private Date updateTime;
// registry list
private List<String> registryList; // 执行器地址列表(系统注册)
@ -60,6 +62,14 @@ public class XxlJobGroup {
return addressList;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public void setAddressList(String addressList) {
this.addressList = addressList;
}

View File

@ -12,7 +12,6 @@ public class XxlJobInfo {
private int id; // 主键ID
private int jobGroup; // 执行器主键ID
private String jobCron; // 任务执行CRON表达式
private String jobDesc;
private Date addTime;
@ -21,6 +20,10 @@ public class XxlJobInfo {
private String author; // 负责人
private String alarmEmail; // 报警邮件
private String scheduleType; // 调度类型
private String scheduleConf; // 调度配置,值含义取决于调度类型
private String misfireStrategy; // 调度过期策略
private String executorRouteStrategy; // 执行器路由策略
private String executorHandler; // 执行器任务Handler名称
private String executorParam; // 执行器,任务参数
@ -56,14 +59,6 @@ public class XxlJobInfo {
this.jobGroup = jobGroup;
}
public String getJobCron() {
return jobCron;
}
public void setJobCron(String jobCron) {
this.jobCron = jobCron;
}
public String getJobDesc() {
return jobDesc;
}
@ -104,6 +99,30 @@ public class XxlJobInfo {
this.alarmEmail = alarmEmail;
}
public String getScheduleType() {
return scheduleType;
}
public void setScheduleType(String scheduleType) {
this.scheduleType = scheduleType;
}
public String getScheduleConf() {
return scheduleConf;
}
public void setScheduleConf(String scheduleConf) {
this.scheduleConf = scheduleConf;
}
public String getMisfireStrategy() {
return misfireStrategy;
}
public void setMisfireStrategy(String misfireStrategy) {
this.misfireStrategy = misfireStrategy;
}
public String getExecutorRouteStrategy() {
return executorRouteStrategy;
}

View File

@ -1,4 +1,4 @@
//package com.xxl.job.admin.core.jobbean;
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.jobbean;
//
//import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
//import com.xxl.job.admin.core.trigger.TriggerTypeEnum;

View File

@ -1,4 +1,4 @@
//package com.xxl.job.admin.core.schedule;
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.schedule;
//
//import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
//import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;

View File

@ -1,4 +1,4 @@
//package com.xxl.job.admin.core.quartz;
package com.xxl.job.admin.core.old;//package com.xxl.job.admin.core.quartz;
//
//import org.quartz.SchedulerConfigException;
//import org.quartz.spi.ThreadPool;

View File

@ -8,14 +8,16 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by xuxueli on 17/3/10.
*/
public class ExecutorRouteRound extends ExecutorRouter {
private static ConcurrentMap<Integer, Integer> routeCountEachJob = new ConcurrentHashMap<Integer, Integer>();
private static ConcurrentMap<Integer, AtomicInteger> routeCountEachJob = new ConcurrentHashMap<>();
private static long CACHE_VALID_TIME = 0;
private static int count(int jobId) {
// cache clear
if (System.currentTimeMillis() > CACHE_VALID_TIME) {
@ -23,11 +25,16 @@ public class ExecutorRouteRound extends ExecutorRouter {
CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
}
// count++
Integer count = routeCountEachJob.get(jobId);
count = (count==null || count>1000000)?(new Random().nextInt(100)):++count; // 初始化时主动Random一次缓解首次压力
AtomicInteger count = routeCountEachJob.get(jobId);
if (count == null || count.get() > 1000000) {
// 初始化时主动Random一次缓解首次压力
count = new AtomicInteger(new Random().nextInt(100));
} else {
// count++
count.addAndGet(1);
}
routeCountEachJob.put(jobId, count);
return count;
return count.get();
}
@Override

View File

@ -0,0 +1,39 @@
package com.xxl.job.admin.core.scheduler;
import com.xxl.job.admin.core.util.I18nUtil;
/**
* @author xuxueli 2020-10-29 21:11:23
*/
public enum MisfireStrategyEnum {
/**
* do nothing
*/
DO_NOTHING(I18nUtil.getString("misfire_strategy_do_nothing")),
/**
* fire once now
*/
FIRE_ONCE_NOW(I18nUtil.getString("misfire_strategy_fire_once_now"));
private String title;
MisfireStrategyEnum(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public static MisfireStrategyEnum match(String name, MisfireStrategyEnum defaultItem){
for (MisfireStrategyEnum item: MisfireStrategyEnum.values()) {
if (item.name().equals(name)) {
return item;
}
}
return defaultItem;
}
}

View File

@ -0,0 +1,46 @@
package com.xxl.job.admin.core.scheduler;
import com.xxl.job.admin.core.util.I18nUtil;
/**
* @author xuxueli 2020-10-29 21:11:23
*/
public enum ScheduleTypeEnum {
NONE(I18nUtil.getString("schedule_type_none")),
/**
* schedule by cron
*/
CRON(I18nUtil.getString("schedule_type_cron")),
/**
* schedule by fixed rate (in seconds)
*/
FIX_RATE(I18nUtil.getString("schedule_type_fix_rate")),
/**
* schedule by fix delay (in seconds) after the last time
*/
/*FIX_DELAY(I18nUtil.getString("schedule_type_fix_delay"))*/;
private String title;
ScheduleTypeEnum(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public static ScheduleTypeEnum match(String name, ScheduleTypeEnum defaultItem){
for (ScheduleTypeEnum item: ScheduleTypeEnum.values()) {
if (item.name().equals(name)) {
return item;
}
}
return defaultItem;
}
}

View File

@ -24,22 +24,22 @@ public class XxlJobScheduler {
// init i18n
initI18n();
// admin trigger pool start
JobTriggerPoolHelper.toStart();
// admin registry monitor run
JobRegistryMonitorHelper.getInstance().start();
JobRegistryHelper.getInstance().start();
// admin fail-monitor run
JobFailMonitorHelper.getInstance().start();
// admin lose-monitor run
JobLosedMonitorHelper.getInstance().start();
// admin trigger pool start
JobTriggerPoolHelper.toStart();
// admin lose-monitor run ( depend on JobTriggerPoolHelper )
JobCompleteHelper.getInstance().start();
// admin log report start
JobLogReportHelper.getInstance().start();
// start-schedule
// start-schedule ( depend on JobTriggerPoolHelper )
JobScheduleHelper.getInstance().start();
logger.info(">>>>>>>>> init xxl-job admin success.");
@ -54,17 +54,17 @@ public class XxlJobScheduler {
// admin log report stop
JobLogReportHelper.getInstance().toStop();
// admin trigger pool stop
JobTriggerPoolHelper.toStop();
// admin lose-monitor stop
JobLosedMonitorHelper.getInstance().toStop();
JobCompleteHelper.getInstance().toStop();
// admin fail-monitor stop
JobFailMonitorHelper.getInstance().toStop();
// admin registry stop
JobRegistryMonitorHelper.getInstance().toStop();
JobRegistryHelper.getInstance().toStop();
// admin trigger pool stop
JobTriggerPoolHelper.toStop();
}

View File

@ -0,0 +1,184 @@
package com.xxl.job.admin.core.thread;
import com.xxl.job.admin.core.complete.XxlJobCompleter;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.model.HandleCallbackParam;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
/**
* job lose-monitor instance
*
* @author xuxueli 2015-9-1 18:05:56
*/
public class JobCompleteHelper {
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
private static JobCompleteHelper instance = new JobCompleteHelper();
public static JobCompleteHelper getInstance(){
return instance;
}
// ---------------------- monitor ----------------------
private ThreadPoolExecutor callbackThreadPool = null;
private Thread monitorThread;
private volatile boolean toStop = false;
public void start(){
// for callback
callbackThreadPool = new ThreadPoolExecutor(
2,
20,
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode());
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now).");
}
});
// for monitor
monitorThread = new Thread(new Runnable() {
@Override
public void run() {
// wait for JobTriggerPoolHelper-init
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
// monitor
while (!toStop) {
try {
// 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min且对应执行器心跳注册失败不在线则将本地调度主动标记失败
Date losedTime = DateUtil.addMinutes(new Date(), -10);
List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);
if (losedJobIds!=null && losedJobIds.size()>0) {
for (Long logId: losedJobIds) {
XxlJobLog jobLog = new XxlJobLog();
jobLog.setId(logId);
jobLog.setHandleTime(new Date());
jobLog.setHandleCode(ReturnT.FAIL_CODE);
jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") );
XxlJobCompleter.updateHandleInfoAndFinish(jobLog);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(60);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop");
}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobLosedMonitorHelper");
monitorThread.start();
}
public void toStop(){
toStop = true;
// stop registryOrRemoveThreadPool
callbackThreadPool.shutdownNow();
// stop monitorThread (interrupt and wait)
monitorThread.interrupt();
try {
monitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// ---------------------- helper ----------------------
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
callbackThreadPool.execute(new Runnable() {
@Override
public void run() {
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
ReturnT<String> callbackResult = callback(handleCallbackParam);
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult);
}
}
});
return ReturnT.SUCCESS;
}
private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) {
// valid log item
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId());
if (log == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found.");
}
if (log.getHandleCode() > 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc
}
// handle msg
StringBuffer handleMsg = new StringBuffer();
if (log.getHandleMsg()!=null) {
handleMsg.append(log.getHandleMsg()).append("<br>");
}
if (handleCallbackParam.getHandleMsg() != null) {
handleMsg.append(handleCallbackParam.getHandleMsg());
}
// success, save log
log.setHandleTime(new Date());
log.setHandleCode(handleCallbackParam.getHandleCode());
log.setHandleMsg(handleMsg.toString());
XxlJobCompleter.updateHandleInfoAndFinish(log);
return ReturnT.SUCCESS;
}
}

View File

@ -60,7 +60,7 @@ public class JobFailMonitorHelper {
// 2、fail alarm monitor
int newAlarmStatus = 0; // 告警状态0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
if (info != null) {
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult?2:3;
} else {

View File

@ -1,95 +0,0 @@
package com.xxl.job.admin.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* job lose-monitor instance
*
* @author xuxueli 2015-9-1 18:05:56
*/
public class JobLosedMonitorHelper {
private static Logger logger = LoggerFactory.getLogger(JobLosedMonitorHelper.class);
private static JobLosedMonitorHelper instance = new JobLosedMonitorHelper();
public static JobLosedMonitorHelper getInstance(){
return instance;
}
// ---------------------- monitor ----------------------
private Thread monitorThread;
private volatile boolean toStop = false;
public void start(){
monitorThread = new Thread(new Runnable() {
@Override
public void run() {
// monitor
while (!toStop) {
try {
// 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min且对应执行器心跳注册失败不在线则将本地调度主动标记失败
Date losedTime = DateUtil.addMinutes(new Date(), -10);
List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);
if (losedJobIds!=null && losedJobIds.size()>0) {
for (Long logId: losedJobIds) {
XxlJobLog jobLog = new XxlJobLog();
jobLog.setId(logId);
jobLog.setHandleTime(new Date());
jobLog.setHandleCode(ReturnT.FAIL_CODE);
jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") );
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateHandleInfo(jobLog);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(60);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop");
}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobLosedMonitorHelper");
monitorThread.start();
}
public void toStop(){
toStop = true;
// interrupt and wait
monitorThread.interrupt();
try {
monitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,204 @@
package com.xxl.job.admin.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.core.biz.model.RegistryParam;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.RegistryConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.*;
/**
* job registry instance
* @author xuxueli 2016-10-02 19:10:24
*/
public class JobRegistryHelper {
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
private static JobRegistryHelper instance = new JobRegistryHelper();
public static JobRegistryHelper getInstance(){
return instance;
}
private ThreadPoolExecutor registryOrRemoveThreadPool = null;
private Thread registryMonitorThread;
private volatile boolean toStop = false;
public void start(){
// for registry or remove
registryOrRemoveThreadPool = new ThreadPoolExecutor(
2,
10,
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
}
});
// for monitor
registryMonitorThread = new Thread(new Runnable() {
@Override
public void run() {
while (!toStop) {
try {
// auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
if (groupList!=null && !groupList.isEmpty()) {
// remove dead address (admin/executor)
List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids!=null && ids.size()>0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// fresh online address (admin/executor)
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item: list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname);
if (registryList == null) {
registryList = new ArrayList<String>();
}
if (!registryList.contains(item.getRegistryValue())) {
registryList.add(item.getRegistryValue());
}
appAddressMap.put(appname, registryList);
}
}
}
// fresh group address
for (XxlJobGroup group: groupList) {
List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null;
if (registryList!=null && !registryList.isEmpty()) {
Collections.sort(registryList);
StringBuilder addressListSB = new StringBuilder();
for (String item:registryList) {
addressListSB.append(item).append(",");
}
addressListStr = addressListSB.toString();
addressListStr = addressListStr.substring(0, addressListStr.length()-1);
}
group.setAddressList(addressListStr);
group.setUpdateTime(new Date());
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
}
});
registryMonitorThread.setDaemon(true);
registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread");
registryMonitorThread.start();
}
public void toStop(){
toStop = true;
// stop registryOrRemoveThreadPool
registryOrRemoveThreadPool.shutdownNow();
// stop monitir (interrupt and wait)
registryMonitorThread.interrupt();
try {
registryMonitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// ---------------------- helper ----------------------
public ReturnT<String> registry(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
if (ret < 1) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
public ReturnT<String> registryRemove(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
if (ret > 0) {
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
private void freshGroupRegistryInfo(RegistryParam registryParam){
// Under consideration, prevent affecting core tables
}
}

View File

@ -1,111 +0,0 @@
package com.xxl.job.admin.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.core.enums.RegistryConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* job registry instance
* @author xuxueli 2016-10-02 19:10:24
*/
public class JobRegistryMonitorHelper {
private static Logger logger = LoggerFactory.getLogger(JobRegistryMonitorHelper.class);
private static JobRegistryMonitorHelper instance = new JobRegistryMonitorHelper();
public static JobRegistryMonitorHelper getInstance(){
return instance;
}
private Thread registryThread;
private volatile boolean toStop = false;
public void start(){
registryThread = new Thread(new Runnable() {
@Override
public void run() {
while (!toStop) {
try {
// auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
if (groupList!=null && !groupList.isEmpty()) {
// remove dead address (admin/executor)
List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids!=null && ids.size()>0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// fresh online address (admin/executor)
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item: list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname);
if (registryList == null) {
registryList = new ArrayList<String>();
}
if (!registryList.contains(item.getRegistryValue())) {
registryList.add(item.getRegistryValue());
}
appAddressMap.put(appname, registryList);
}
}
}
// fresh group address
for (XxlJobGroup group: groupList) {
List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null;
if (registryList!=null && !registryList.isEmpty()) {
Collections.sort(registryList);
addressListStr = "";
for (String item:registryList) {
addressListStr += item + ",";
}
addressListStr = addressListStr.substring(0, addressListStr.length()-1);
}
group.setAddressList(addressListStr);
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
}
});
registryThread.setDaemon(true);
registryThread.setName("xxl-job, admin JobRegistryMonitorHelper");
registryThread.start();
}
public void toStop(){
toStop = true;
// interrupt and wait
registryThread.interrupt();
try {
registryThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
}

View File

@ -3,6 +3,8 @@ package com.xxl.job.admin.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -10,7 +12,6 @@ import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@ -86,7 +87,15 @@ public class JobScheduleHelper {
// 2.1、trigger-expire > 5spass && make next-trigger-time
logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
// fresh next
// 1、misfire match
MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING);
if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) {
// FIRE_ONCE_NOW 》 trigger
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null);
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );
}
// 2、fresh next
refreshNextValidTime(jobInfo, new Date());
} else if (nowTime > jobInfo.getTriggerNextTime()) {
@ -213,17 +222,17 @@ public class JobScheduleHelper {
@Override
public void run() {
// align second
try {
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis()%1000 );
} catch (InterruptedException e) {
if (!ringThreadToStop) {
logger.error(e.getMessage(), e);
}
}
while (!ringThreadToStop) {
// align second
try {
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
} catch (InterruptedException e) {
if (!ringThreadToStop) {
logger.error(e.getMessage(), e);
}
}
try {
// second data
List<Integer> ringItemData = new ArrayList<>();
@ -251,15 +260,6 @@ public class JobScheduleHelper {
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e);
}
}
// next second, align second
try {
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis()%1000);
} catch (InterruptedException e) {
if (!ringThreadToStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
}
@ -269,8 +269,8 @@ public class JobScheduleHelper {
ringThread.start();
}
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws ParseException {
Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(fromTime);
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
if (nextValidTime != null) {
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
jobInfo.setTriggerNextTime(nextValidTime.getTime());
@ -278,6 +278,8 @@ public class JobScheduleHelper {
jobInfo.setTriggerStatus(0);
jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(0);
logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}",
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf());
}
}
@ -351,4 +353,17 @@ public class JobScheduleHelper {
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper stop");
}
// ---------------------- tools ----------------------
public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (ScheduleTypeEnum.CRON == scheduleTypeEnum) {
Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime);
return nextValidTime;
} else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) {
return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 );
}
return null;
}
}

View File

@ -13,7 +13,8 @@ public enum TriggerTypeEnum {
CRON(I18nUtil.getString("jobconf_trigger_type_cron")),
RETRY(I18nUtil.getString("jobconf_trigger_type_retry")),
PARENT(I18nUtil.getString("jobconf_trigger_type_parent")),
API(I18nUtil.getString("jobconf_trigger_type_api"));
API(I18nUtil.getString("jobconf_trigger_type_api")),
MISFIRE(I18nUtil.getString("jobconf_trigger_type_misfire"));
private TriggerTypeEnum(String title){
this.title = title;

View File

@ -2,6 +2,7 @@ package com.xxl.job.admin.service;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.core.biz.model.ReturnT;
import java.util.Date;
@ -67,6 +68,17 @@ public interface XxlJobService {
*/
public ReturnT<String> stop(int id);
/**
* trigger
*
* @param loginUser
* @param jobId
* @param executorParam
* @param addressList
* @return
*/
public ReturnT<String> trigger(XxlJobUser loginUser, int jobId, String executorParam, String addressList);
/**
* dashboard info
*

View File

@ -1,27 +1,13 @@
package com.xxl.job.admin.service.impl;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobInfoDao;
import com.xxl.job.admin.dao.XxlJobLogDao;
import com.xxl.job.admin.dao.XxlJobRegistryDao;
import com.xxl.job.admin.core.thread.JobCompleteHelper;
import com.xxl.job.admin.core.thread.JobRegistryHelper;
import com.xxl.job.core.biz.AdminBiz;
import com.xxl.job.core.biz.model.HandleCallbackParam;
import com.xxl.job.core.biz.model.RegistryParam;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
/**
@ -29,147 +15,21 @@ import java.util.List;
*/
@Service
public class AdminBizImpl implements AdminBiz {
private static Logger logger = LoggerFactory.getLogger(AdminBizImpl.class);
@Resource
public XxlJobLogDao xxlJobLogDao;
@Resource
private XxlJobInfoDao xxlJobInfoDao;
@Resource
private XxlJobRegistryDao xxlJobRegistryDao;
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Override
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
ReturnT<String> callbackResult = callback(handleCallbackParam);
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
(callbackResult.getCode()==IJobHandler.SUCCESS.getCode()?"success":"fail"), handleCallbackParam, callbackResult);
}
return ReturnT.SUCCESS;
}
private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) {
// valid log item
XxlJobLog log = xxlJobLogDao.load(handleCallbackParam.getLogId());
if (log == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found.");
}
if (log.getHandleCode() > 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc
}
// trigger success, to trigger child job
String callbackMsg = null;
if (IJobHandler.SUCCESS.getCode() == handleCallbackParam.getExecuteResult().getCode()) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(log.getJobId());
if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
callbackMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< </span><br>";
String[] childJobIds = xxlJobInfo.getChildJobId().split(",");
for (int i = 0; i < childJobIds.length; i++) {
int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
if (childJobId > 0) {
JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
ReturnT<String> triggerChildResult = ReturnT.SUCCESS;
// add msg
callbackMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg1"),
(i+1),
childJobIds.length,
childJobIds[i],
(triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?I18nUtil.getString("system_success"):I18nUtil.getString("system_fail")),
triggerChildResult.getMsg());
} else {
callbackMsg += MessageFormat.format(I18nUtil.getString("jobconf_callback_child_msg2"),
(i+1),
childJobIds.length,
childJobIds[i]);
}
}
}
}
// handle msg
StringBuffer handleMsg = new StringBuffer();
if (log.getHandleMsg()!=null) {
handleMsg.append(log.getHandleMsg()).append("<br>");
}
if (handleCallbackParam.getExecuteResult().getMsg() != null) {
handleMsg.append(handleCallbackParam.getExecuteResult().getMsg());
}
if (callbackMsg != null) {
handleMsg.append(callbackMsg);
}
if (handleMsg.length() > 15000) {
handleMsg = new StringBuffer(handleMsg.substring(0, 15000)); // text最大64kb 避免长度过长
}
// success, save log
log.setHandleTime(new Date());
log.setHandleCode(handleCallbackParam.getExecuteResult().getCode());
log.setHandleMsg(handleMsg.toString());
xxlJobLogDao.updateHandleInfo(log);
return ReturnT.SUCCESS;
}
private boolean isNumeric(String str){
try {
int result = Integer.valueOf(str);
return true;
} catch (NumberFormatException e) {
return false;
}
return JobCompleteHelper.getInstance().callback(callbackParamList);
}
@Override
public ReturnT<String> registry(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
int ret = xxlJobRegistryDao.registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
if (ret < 1) {
xxlJobRegistryDao.registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
// fresh
freshGroupRegistryInfo(registryParam);
}
return ReturnT.SUCCESS;
return JobRegistryHelper.getInstance().registry(registryParam);
}
@Override
public ReturnT<String> registryRemove(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
int ret = xxlJobRegistryDao.registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
if (ret > 0) {
// fresh
freshGroupRegistryInfo(registryParam);
}
return ReturnT.SUCCESS;
}
private void freshGroupRegistryInfo(RegistryParam registryParam){
// Under consideration, prevent affecting core tables
return JobRegistryHelper.getInstance().registryRemove(registryParam);
}
}

View File

@ -1,11 +1,16 @@
package com.xxl.job.admin.service.impl;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobLogReport;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.*;
import com.xxl.job.admin.service.XxlJobService;
@ -19,7 +24,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.*;
/**
@ -58,40 +62,67 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override
public ReturnT<String> add(XxlJobInfo jobInfo) {
// valid
// valid base
XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
if (group == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) );
}
if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
}
if (jobInfo.getJobDesc()==null || jobInfo.getJobDesc().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
}
if (jobInfo.getAuthor()==null || jobInfo.getAuthor().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
}
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
// valid trigger
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (scheduleTypeEnum == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid"));
}
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
if (jobInfo.getScheduleConf() == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")) );
}
try {
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
if (fixSecond < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
} catch (Exception e) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
}
// valid job
if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) );
}
if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && (jobInfo.getExecutorHandler()==null || jobInfo.getExecutorHandler().trim().length()==0) ) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") );
}
// fix "\r" in shell
// 》fix "\r" in shell
if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) {
jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
}
// ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) {
// valid advanced
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
}
if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy")+I18nUtil.getString("system_unvalid")) );
}
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
}
// 》ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) {
String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
@ -140,25 +171,50 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override
public ReturnT<String> update(XxlJobInfo jobInfo) {
// valid
if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
}
// valid base
if (jobInfo.getJobDesc()==null || jobInfo.getJobDesc().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) );
}
if (jobInfo.getAuthor()==null || jobInfo.getAuthor().trim().length()==0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) );
}
// valid trigger
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (scheduleTypeEnum == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid") );
}
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
if (jobInfo.getScheduleConf() == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
try {
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
if (fixSecond < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
} catch (Exception e) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
}
// valid advanced
if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) );
}
if (MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("misfire_strategy")+I18nUtil.getString("system_unvalid")) );
}
if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
}
// ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) {
// ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) {
String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
@ -197,24 +253,27 @@ public class XxlJobServiceImpl implements XxlJobService {
// next trigger time (5s后生效避开预读周期)
long nextTriggerTime = exists_jobInfo.getTriggerNextTime();
if (exists_jobInfo.getTriggerStatus() == 1 && !jobInfo.getJobCron().equals(exists_jobInfo.getJobCron()) ) {
boolean scheduleDataNotChanged = jobInfo.getScheduleType().equals(exists_jobInfo.getScheduleType()) && jobInfo.getScheduleConf().equals(exists_jobInfo.getScheduleConf());
if (exists_jobInfo.getTriggerStatus() == 1 && !scheduleDataNotChanged) {
try {
Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
Date nextValidTime = JobScheduleHelper.generateNextValidTime(jobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_never_fire"));
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
nextTriggerTime = nextValidTime.getTime();
} catch (ParseException e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid")+" | "+ e.getMessage());
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
}
exists_jobInfo.setJobGroup(jobInfo.getJobGroup());
exists_jobInfo.setJobCron(jobInfo.getJobCron());
exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
exists_jobInfo.setAuthor(jobInfo.getAuthor());
exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail());
exists_jobInfo.setScheduleType(jobInfo.getScheduleType());
exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf());
exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy());
exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
@ -248,17 +307,23 @@ public class XxlJobServiceImpl implements XxlJobService {
public ReturnT<String> start(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
// valid
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE);
if (ScheduleTypeEnum.NONE == scheduleTypeEnum) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")) );
}
// next trigger time (5s后生效避开预读周期)
long nextTriggerTime = 0;
try {
Date nextValidTime = new CronExpression(xxlJobInfo.getJobCron()).getNextValidTimeAfter(new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_never_fire"));
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
nextTriggerTime = nextValidTime.getTime();
} catch (ParseException e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid")+" | "+ e.getMessage());
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
xxlJobInfo.setTriggerStatus(1);
@ -283,6 +348,42 @@ public class XxlJobServiceImpl implements XxlJobService {
return ReturnT.SUCCESS;
}
@Override
public ReturnT<String> trigger(XxlJobUser loginUser, int jobId, String executorParam, String addressList) {
// permission
if (loginUser == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("system_permission_limit"));
}
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(jobId);
if (xxlJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
if (!hasPermission(loginUser, xxlJobInfo.getJobGroup())) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("system_permission_limit"));
}
// force cover job param
if (executorParam == null) {
executorParam = "";
}
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
return ReturnT.SUCCESS;
}
private boolean hasPermission(XxlJobUser loginUser, int jobGroup){
if (loginUser.getRole() == 1) {
return true;
}
List<String> groupIdStrs = new ArrayList<>();
if (loginUser.getPermission()!=null && loginUser.getPermission().trim().length()>0) {
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
}
return groupIdStrs.contains(String.valueOf(jobGroup));
}
@Override
public Map<String, Object> dashboardInfo() {

View File

@ -1,7 +1,7 @@
server:
port: 9080
servlet:
context-path: /xxl-job-admin
context-path: /xxl-job-admin
#数据源配置
spring:
datasource:
@ -24,6 +24,7 @@ spring:
host: smtphz.qiye.163.com
port: 994
username: zhuwei@aboatedu.com
from: zhuwei@aboatedu.com
password: zwass1314
properties:
mail:

View File

@ -1,6 +1,6 @@
admin_name=Scheduling Center
admin_name_full=Distributed Task Scheduling Platform XXL-JOB
admin_version=2.2.0
admin_version=2.4.2-SNAPSHOT
admin_i18n=en
## system
@ -117,8 +117,6 @@ jobinfo_field_jobdesc=Job description
jobinfo_field_timeout=Job timeout period
jobinfo_field_gluetype=GLUE Type
jobinfo_field_executorparam=Param
jobinfo_field_cron_unvalid=The Cron is illegal
jobinfo_field_cron_never_fire=The Cron will never fire
jobinfo_field_author=Author
jobinfo_field_alarmemail=Alarm email
jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated
@ -144,6 +142,19 @@ jobinfo_glue_rollback=Version Backtrack
jobinfo_glue_jobid_unvalid=Job ID is illegal
jobinfo_glue_gluetype_unvalid=The job is not GLUE Type
jobinfo_field_executorTimeout_placeholder=Job Timeout periodin seconds. effect if greater than zero
schedule_type=Schedule Type
schedule_type_none=None
schedule_type_cron=Cron
schedule_type_fix_rate=Fix rate
schedule_type_fix_delay=Fix delay
schedule_type_none_limit_start=The current schedule type disables startup
misfire_strategy=Misfire strategy
misfire_strategy_do_nothing=Do nothing
misfire_strategy_fire_once_now=Fire once now
jobinfo_conf_base=Base configuration
jobinfo_conf_schedule=Schedule configuration
jobinfo_conf_job=Job configuration
jobinfo_conf_advanced=Advanced configuration
## job log
joblog_name=Trigger Log
@ -243,6 +254,7 @@ jobconf_trigger_type_manual=Manual trigger
jobconf_trigger_type_parent=Parent job trigger
jobconf_trigger_type_api=Api trigger
jobconf_trigger_type_retry=Fail retry trigger
jobconf_trigger_type_misfire=Misfire compensation trigger
## user
user_manage=User Manage

View File

@ -1,6 +1,6 @@
admin_name=任务调度中心
admin_name_full=分布式任务调度平台XXL-JOB
admin_version=2.2.0
admin_version=2.4.2-SNAPSHOT
admin_i18n=
## system
@ -116,8 +116,6 @@ jobinfo_field_jobgroup=执行器
jobinfo_field_jobdesc=任务描述
jobinfo_field_gluetype=运行模式
jobinfo_field_executorparam=任务参数
jobinfo_field_cron_unvalid=Cron格式非法
jobinfo_field_cron_never_fire=Cron非法永远不会触发
jobinfo_field_author=负责人
jobinfo_field_timeout=任务超时时间
jobinfo_field_alarmemail=报警邮件
@ -144,6 +142,19 @@ jobinfo_glue_rollback=版本回溯
jobinfo_glue_jobid_unvalid=任务ID非法
jobinfo_glue_gluetype_unvalid=该任务非GLUE模式
jobinfo_field_executorTimeout_placeholder=任务超时时间,单位秒,大于零时生效
schedule_type=调度类型
schedule_type_none=
schedule_type_cron=CRON
schedule_type_fix_rate=固定速度
schedule_type_fix_delay=固定延迟
schedule_type_none_limit_start=当前调度类型禁止启动
misfire_strategy=调度过期策略
misfire_strategy_do_nothing=忽略
misfire_strategy_fire_once_now=立即执行一次
jobinfo_conf_base=基础配置
jobinfo_conf_schedule=调度配置
jobinfo_conf_job=任务配置
jobinfo_conf_advanced=高级配置
## job log
joblog_name=调度日志
@ -243,6 +254,7 @@ jobconf_trigger_type_manual=手动触发
jobconf_trigger_type_parent=父任务触发
jobconf_trigger_type_api=API触发
jobconf_trigger_type_retry=失败重试触发
jobconf_trigger_type_misfire=调度过期补偿
## user
user_manage=用户管理

View File

@ -1,6 +1,6 @@
admin_name=任務調度中心
admin_name_full=分布式任務調度平臺XXL-JOB
admin_version=2.2.0
admin_version=2.4.2-SNAPSHOT
admin_i18n=
## system
@ -116,8 +116,6 @@ jobinfo_field_jobgroup=執行器
jobinfo_field_jobdesc=任務描述
jobinfo_field_gluetype=運行模式
jobinfo_field_executorparam=任務參數
jobinfo_field_cron_unvalid=Cron 格式非法
jobinfo_field_cron_never_fire=Cron 格式非法,永遠不會觸發
jobinfo_field_author=負責人
jobinfo_field_timeout=任務超時秒數
jobinfo_field_alarmemail=告警郵件
@ -144,6 +142,19 @@ jobinfo_glue_rollback=版本回復
jobinfo_glue_jobid_unvalid=任務ID非法
jobinfo_glue_gluetype_unvalid=該任務非GLUE模式
jobinfo_field_executorTimeout_placeholder=任務超時時間,單位秒,大於零時生效
schedule_type=調度類型
schedule_type_none=
schedule_type_cron=CRON
schedule_type_fix_rate=固定速度
schedule_type_fix_delay=固定延遲
schedule_type_none_limit_start=當前調度類型禁止啟動
misfire_strategy=調度過期策略
misfire_strategy_do_nothing=忽略
misfire_strategy_fire_once_now=立即執行壹次
jobinfo_conf_base=基礎配置
jobinfo_conf_schedule=調度配置
jobinfo_conf_job=任務配置
jobinfo_conf_advanced=高級配置
## job log
joblog_name=調度日誌
@ -243,6 +254,7 @@ jobconf_trigger_type_manual=手動觸發
jobconf_trigger_type_parent=父任務觸發
jobconf_trigger_type_api=API觸發
jobconf_trigger_type_retry=失敗重試觸發
jobconf_trigger_type_misfire=調度過期補償
## user
user_manage=用户管理

View File

@ -2,7 +2,7 @@
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="../xxl-job/xxl-job-admin.log"/>
<property name="log.path" value="/data/applogs/xxl-job/xxl-job-admin.log"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>

View File

@ -9,6 +9,7 @@
<result column="title" property="title" />
<result column="address_type" property="addressType" />
<result column="address_list" property="addressList" />
<result column="update_time" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
@ -16,7 +17,8 @@
t.app_name,
t.title,
t.address_type,
t.address_list
t.address_list,
t.update_time
</sql>
<select id="findAll" resultMap="XxlJobGroup">
@ -33,8 +35,8 @@
</select>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_group ( `app_name`, `title`, `address_type`, `address_list`)
values ( #{appname}, #{title}, #{addressType}, #{addressList});
INSERT INTO xxl_job_group ( `app_name`, `title`, `address_type`, `address_list`, `update_time`)
values ( #{appname}, #{title}, #{addressType}, #{addressList}, #{updateTime} );
</insert>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
@ -42,7 +44,8 @@
SET `app_name` = #{appname},
`title` = #{title},
`address_type` = #{addressType},
`address_list` = #{addressList}
`address_list` = #{addressList},
`update_time` = #{updateTime}
WHERE id = #{id}
</update>

View File

@ -7,7 +7,6 @@
<result column="id" property="id" />
<result column="job_group" property="jobGroup" />
<result column="job_cron" property="jobCron" />
<result column="job_desc" property="jobDesc" />
<result column="add_time" property="addTime" />
@ -16,6 +15,10 @@
<result column="author" property="author" />
<result column="alarm_email" property="alarmEmail" />
<result column="schedule_type" property="scheduleType" />
<result column="schedule_conf" property="scheduleConf" />
<result column="misfire_strategy" property="misfireStrategy" />
<result column="executor_route_strategy" property="executorRouteStrategy" />
<result column="executor_handler" property="executorHandler" />
<result column="executor_param" property="executorParam" />
@ -38,12 +41,14 @@
<sql id="Base_Column_List">
t.id,
t.job_group,
t.job_cron,
t.job_desc,
t.add_time,
t.update_time,
t.author,
t.alarm_email,
t.schedule_type,
t.schedule_conf,
t.misfire_strategy,
t.executor_route_strategy,
t.executor_handler,
t.executor_param,
@ -109,12 +114,14 @@
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_info (
job_group,
job_cron,
job_desc,
add_time,
update_time,
author,
alarm_email,
schedule_type,
schedule_conf,
misfire_strategy,
executor_route_strategy,
executor_handler,
executor_param,
@ -131,12 +138,14 @@
trigger_next_time
) VALUES (
#{jobGroup},
#{jobCron},
#{jobDesc},
#{addTime},
#{updateTime},
#{author},
#{alarmEmail},
#{scheduleType},
#{scheduleConf},
#{misfireStrategy},
#{executorRouteStrategy},
#{executorHandler},
#{executorParam},
@ -168,11 +177,13 @@
UPDATE xxl_job_info
SET
job_group = #{jobGroup},
job_cron = #{jobCron},
job_desc = #{jobDesc},
update_time = #{updateTime},
author = #{author},
alarm_email = #{alarmEmail},
schedule_type = #{scheduleType},
schedule_conf = #{scheduleConf},
misfire_strategy = #{misfireStrategy},
executor_route_strategy = #{executorRouteStrategy},
executor_handler = #{executorHandler},
executor_param = #{executorParam},

View File

@ -247,15 +247,27 @@
</update>
<select id="findLostJobIds" resultType="long" >
SELECT t.id
FROM xxl_job_log AS t
WHERE t.trigger_code = 200
and t.handle_code = 0
and t.trigger_time <![CDATA[ <= ]]> #{losedTime}
and t.executor_address not in (
SELECT t2.registry_value
FROM xxl_job_registry AS t2
)
SELECT
t.id
FROM
xxl_job_log t
LEFT JOIN xxl_job_registry t2 ON t.executor_address = t2.registry_value
WHERE
t.trigger_code = 200
AND t.handle_code = 0
AND t.trigger_time <![CDATA[ <= ]]> #{losedTime}
AND t2.id IS NULL;
</select>
<!--
SELECT t.id
FROM xxl_job_log AS t
WHERE t.trigger_code = 200
and t.handle_code = 0
and t.trigger_time <![CDATA[ <= ]]> #{losedTime}
and t.executor_address not in (
SELECT t2.registry_value
FROM xxl_job_registry AS t2
)
-->
</mapper>

View File

@ -123,7 +123,7 @@ $(function() {
var id = $(this).attr("_id");
var row = tableData['key'+id];
var html = '<div>';
/*var html = '<div>';
if (row.registryList) {
for (var index in row.registryList) {
html += (parseInt(index)+1) + '. <span class="badge bg-green" >' + row.registryList[index] + '</span><br>';
@ -135,8 +135,19 @@ $(function() {
title: I18n.jobinfo_opt_registryinfo ,
btn: [ I18n.system_ok ],
content: html
});
});*/
var html = '<table class="table table-bordered"><tbody>';
if (row.registryList) {
for (var index in row.registryList) {
html += '<tr><th>' + (parseInt(index)+1) + '</th>';
html += '<th><span class="badge bg-green" >' + row.registryList[index] + '</span></th><tr>';
}
}
html += '</tbody></table>';
$('#showRegistryListModal .data').html(html);
$('#showRegistryListModal').modal({backdrop: false, keyboard: false}).modal('show');
});

View File

@ -48,6 +48,18 @@ $(function() {
"visible" : true,
"width":'25%'
},
{
"data": 'scheduleType',
"visible" : true,
"width":'13%',
"render": function ( data, type, row ) {
if (row.scheduleConf) {
return row.scheduleType + ''+ row.scheduleConf;
} else {
return row.scheduleType;
}
}
},
{
"data": 'glueType',
"width":'25%',
@ -62,11 +74,6 @@ $(function() {
}
},
{ "data": 'executorParam', "visible" : false},
{
"data": 'jobCron',
"visible" : true,
"width":'13%'
},
{
"data": 'addTime',
"visible" : false,
@ -111,10 +118,16 @@ $(function() {
start_stop_div = '<li><a href="javascript:void(0);" class="job_operate" _type="job_resume" >'+ I18n.jobinfo_opt_start +'</a></li>\n';
}
// job_next_time_html
var job_next_time_html = '';
if (row.scheduleType == 'CRON' || row.scheduleType == 'FIX_RATE') {
job_next_time_html = '<li><a href="javascript:void(0);" class="job_next_time" >' + I18n.jobinfo_opt_next_time + '</a></li>\n';
}
// log url
var logHref = base_url +'/joblog?jobId='+ row.id;
// log url
// code url
var codeBtn = "";
if ('BEAN' != row.glueType) {
var codeUrl = base_url +'/jobcode?jobId='+ row.id;
@ -136,7 +149,7 @@ $(function() {
' <li><a href="javascript:void(0);" class="job_trigger" >'+ I18n.jobinfo_opt_run +'</a></li>\n' +
' <li><a href="'+ logHref +'">'+ I18n.jobinfo_opt_log +'</a></li>\n' +
' <li><a href="javascript:void(0);" class="job_registryinfo" >' + I18n.jobinfo_opt_registryinfo + '</a></li>\n' +
' <li><a href="javascript:void(0);" class="job_next_time" >' + I18n.jobinfo_opt_next_time + '</a></li>\n' +
job_next_time_html +
' <li class="divider"></li>\n' +
codeBtn +
start_stop_div +
@ -322,17 +335,16 @@ $(function() {
var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id];
var jobCron = row.jobCron;
$.ajax({
type : 'POST',
url : base_url + "/jobinfo/nextTriggerTime",
data : {
"cron" : jobCron
"scheduleType" : row.scheduleType,
"scheduleConf" : row.scheduleConf
},
dataType : "json",
success : function(data){
if (data.code != 200) {
layer.open({
title: I18n.jobinfo_opt_next_time ,
@ -364,8 +376,14 @@ $(function() {
$(".add").click(function(){
// init-cronGen
$("#addModal .form input[name='jobCron']").show().siblings().remove();
$("#addModal .form input[name='jobCron']").cronGen({});
$("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
$("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
// 》init scheduleType
$("#updateModal .form select[name=scheduleType]").change();
// 》init glueType
$("#updateModal .form select[name=glueType]").change();
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
});
@ -378,35 +396,29 @@ $(function() {
required : true,
maxlength: 50
},
jobCron : {
required : true
},
author : {
required : true
},
}/*,
executorTimeout : {
digits:true
},
executorFailRetryCount : {
digits:true
}
}*/
},
messages : {
jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
},
jobCron : {
required : I18n.system_please_input + "Cron"
},
author : {
required : I18n.system_please_input + I18n.jobinfo_field_author
},
}/*,
executorTimeout : {
digits: I18n.system_please_input + I18n.system_digits
},
executorFailRetryCount : {
digits: I18n.system_please_input + I18n.system_digits
}
}*/
},
highlight : function(element) {
$(element).closest('.form-group').addClass('has-error');
@ -420,7 +432,7 @@ $(function() {
},
submitHandler : function(form) {
// process
// process executorTimeout+executorFailRetryCount
var executorTimeout = $("#addModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0;
@ -432,8 +444,17 @@ $(function() {
}
$("#addModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
// process-cronGen
$("#addModal .form input[name='jobCron']").val( $("#addModal .form input[name='cronGen_display']").val() );
// process schedule_conf
var scheduleType = $("#addModal .form select[name='scheduleType']").val();
var scheduleConf;
if (scheduleType == 'CRON') {
scheduleConf = $("#addModal .form input[name='cronGen_display']").val();
} else if (scheduleType == 'FIX_RATE') {
scheduleConf = $("#addModal .form input[name='schedule_conf_FIX_RATE']").val();
} else if (scheduleType == 'FIX_DELAY') {
scheduleConf = $("#addModal .form input[name='schedule_conf_FIX_DELAY']").val();
}
$("#addModal .form input[name='scheduleConf']").val( scheduleConf );
$.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) {
if (data.code == "200") {
@ -468,6 +489,13 @@ $(function() {
$("#addModal .form input[name='executorHandler']").removeAttr("readonly");
});
// scheduleType change
$(".scheduleType").change(function(){
var scheduleType = $(this).val();
$(this).parents("form").find(".schedule_conf").hide();
$(this).parents("form").find(".schedule_conf_" + scheduleType).show();
});
// glueType change
$(".glueType").change(function(){
@ -508,27 +536,46 @@ $(function() {
var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id];
// base data
// fill base
$("#updateModal .form input[name='id']").val( row.id );
$('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
$("#updateModal .form input[name='jobDesc']").val( row.jobDesc );
$("#updateModal .form input[name='jobCron']").val( row.jobCron );
$("#updateModal .form input[name='author']").val( row.author );
$("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
// fill trigger
$('#updateModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true);
$("#updateModal .form input[name='scheduleConf']").val( row.scheduleConf );
if (row.scheduleType == 'CRON') {
$("#updateModal .form input[name='schedule_conf_CRON']").val( row.scheduleConf );
} else if (row.scheduleType == 'FIX_RATE') {
$("#updateModal .form input[name='schedule_conf_FIX_RATE']").val( row.scheduleConf );
} else if (row.scheduleType == 'FIX_DELAY') {
$("#updateModal .form input[name='schedule_conf_FIX_DELAY']").val( row.scheduleConf );
}
// 》init scheduleType
$("#updateModal .form select[name=scheduleType]").change();
// fill job
$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
$("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
$("#updateModal .form textarea[name='executorParam']").val( row.executorParam );
$("#updateModal .form input[name='childJobId']").val( row.childJobId );
// 》init glueType
$("#updateModal .form select[name=glueType]").change();
// 》init-cronGen
$("#updateModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
$("#updateModal .form input[name='schedule_conf_CRON']").cronGen({});
// fill advanced
$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
$("#updateModal .form input[name='childJobId']").val( row.childJobId );
$('#updateModal .form select[name=misfireStrategy] option[value='+ row.misfireStrategy +']').prop('selected', true);
$('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
$("#updateModal .form select[name=glueType]").change();
// init-cronGen
$("#updateModal .form input[name='jobCron']").show().siblings().remove();
$("#updateModal .form input[name='jobCron']").cronGen({});
$("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
// show
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
@ -543,35 +590,17 @@ $(function() {
required : true,
maxlength: 50
},
jobCron : {
required : true
},
author : {
required : true
},
executorTimeout : {
digits:true
},
executorFailRetryCount : {
digits:true
}
}
},
messages : {
jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
},
jobCron : {
required : I18n.system_please_input + "Cron"
},
author : {
required : I18n.system_please_input + I18n.jobinfo_field_author
},
executorTimeout : {
digits: I18n.system_please_input + I18n.system_digits
},
executorFailRetryCount : {
digits: I18n.system_please_input + I18n.system_digits
}
}
},
highlight : function(element) {
$(element).closest('.form-group').addClass('has-error');
@ -585,7 +614,7 @@ $(function() {
},
submitHandler : function(form) {
// process
// process executorTimeout + executorFailRetryCount
var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0;
@ -597,8 +626,18 @@ $(function() {
}
$("#updateModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
// process-cronGen
$("#updateModal .form input[name='jobCron']").val( $("#updateModal .form input[name='cronGen_display']").val() );
// process schedule_conf
var scheduleType = $("#updateModal .form select[name='scheduleType']").val();
var scheduleConf;
if (scheduleType == 'CRON') {
scheduleConf = $("#updateModal .form input[name='cronGen_display']").val();
} else if (scheduleType == 'FIX_RATE') {
scheduleConf = $("#updateModal .form input[name='schedule_conf_FIX_RATE']").val();
} else if (scheduleType == 'FIX_DELAY') {
scheduleConf = $("#updateModal .form input[name='schedule_conf_FIX_DELAY']").val();
}
$("#updateModal .form input[name='scheduleConf']").val( scheduleConf );
// post
$.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) {
@ -653,27 +692,45 @@ $(function() {
var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id];
// base data
//$("#addModal .form input[name='id']").val( row.id );
// fill base
$('#addModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
$("#addModal .form input[name='jobDesc']").val( row.jobDesc );
$("#addModal .form input[name='jobCron']").val( row.jobCron );
$("#addModal .form input[name='author']").val( row.author );
$("#addModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#addModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#addModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
$('#addModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
// fill trigger
$('#addModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true);
$("#addModal .form input[name='scheduleConf']").val( row.scheduleConf );
if (row.scheduleType == 'CRON') {
$("#addModal .form input[name='schedule_conf_CRON']").val( row.scheduleConf );
} else if (row.scheduleType == 'FIX_RATE') {
$("#addModal .form input[name='schedule_conf_FIX_RATE']").val( row.scheduleConf );
} else if (row.scheduleType == 'FIX_DELAY') {
$("#addModal .form input[name='schedule_conf_FIX_DELAY']").val( row.scheduleConf );
}
// 》init scheduleType
$("#addModal .form select[name=scheduleType]").change();
// fill job
$('#addModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
$("#addModal .form input[name='executorHandler']").val( row.executorHandler );
$("#addModal .form textarea[name='executorParam']").val( row.executorParam );
$("#addModal .form input[name='childJobId']").val( row.childJobId );
$('#addModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
$('#addModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
// 》init glueType
$("#addModal .form select[name=glueType]").change();
// init-cronGen
$("#addModal .form input[name='jobCron']").show().siblings().remove();
$("#addModal .form input[name='jobCron']").cronGen({});
// 》init-cronGen
$("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
$("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
// fill advanced
$('#addModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
$("#addModal .form input[name='childJobId']").val( row.childJobId );
$('#addModal .form select[name=misfireStrategy] option[value='+ row.misfireStrategy +']').prop('selected', true);
$('#addModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
$("#addModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#addModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
// show
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');

View File

@ -25,8 +25,6 @@ $(function() {
async: false, // sync, make log ordered
url : base_url + '/joblog/logDetailCat',
data : {
"executorAddress":executorAddress,
"triggerTime":triggerTime,
"logId":logId,
"fromLineNum":fromLineNum
},

View File

@ -116,7 +116,7 @@ $(function() {
"data": 'triggerTime',
"width":'20%',
"render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
return data?moment(data).format("YYYY-MM-DD HH:mm:ss"):"";
}
},
{
@ -145,7 +145,7 @@ $(function() {
"data": 'handleTime',
"width":'20%',
"render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
return data?moment(data).format("YYYY-MM-DD HH:mm:ss"):"";
}
},
{
@ -187,6 +187,12 @@ $(function() {
}*/
//return temp;
var logKillDiv = '';
if(row.handleCode == 0){
logKillDiv = ' <li class="divider"></li>\n' +
' <li><a href="javascript:void(0);" class="logKill" _id="'+ row.id +'" >'+ I18n.joblog_kill_log +'</a></li>\n';
}
var html = '<div class="btn-group">\n' +
' <button type="button" class="btn btn-primary btn-sm">'+ I18n.system_opt +'</button>\n' +
' <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown">\n' +
@ -195,8 +201,7 @@ $(function() {
' </button>\n' +
' <ul class="dropdown-menu" role="menu" _id="'+ row.id +'" >\n' +
' <li><a href="javascript:void(0);" class="logDetail" _id="'+ row.id +'" >'+ I18n.joblog_rolling_log +'</a></li>\n' +
' <li class="divider"></li>\n' +
' <li><a href="javascript:void(0);" class="logKill" _id="'+ row.id +'" >'+ I18n.joblog_kill_log +'</a></li>\n' +
logKillDiv +
' </ul>\n' +
' </div>';

View File

@ -50,7 +50,7 @@ $(function(){
if (data.code == "200") {
layer.msg( I18n.login_success );
setTimeout(function(){
window.location.href = base_url;
window.location.href = base_url + "/";
}, 500);
} else {
layer.open({

View File

@ -33,7 +33,7 @@ $(function() {
},
{
"data": 'password',
"visible" : true,
"visible" : false,
"width":'20%',
"render": function ( data, type, row ) {
return '*********';

View File

@ -10,7 +10,7 @@
options = $.extend({}, $.fn.cronGen.defaultOptions, options);
//create top menu
var cronContainer = $("<div/>", { id: "CronContainer", style: "display:none;width:300px;height:300px;" });
var mainDiv = $("<div/>", { id: "CronGenMainDiv", style: "width:410px;height:300px;" });
var mainDiv = $("<div/>", { id: "CronGenMainDiv", style: "width:410px;height:420px;" });
var topMenu = $("<ul/>", { "class": "nav nav-tabs", id: "CronGenTabs" });
$('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu);
$('<li/>').html($('<a id="MinutesTab" href="#Minutes"></a>')).appendTo(topMenu);
@ -318,9 +318,12 @@
// resultsName = $(this).prop("id");
// $(this).prop("name", resultsName);
var runTime = '<br style="padding-top: 10px"><label>: </label></br><textarea id="runTime" rows="6" style="width: 90%;resize: none;background: none;border: none;outline: none;" readonly = readonly></textarea></div>';
$(span12).appendTo(row);
$(row).appendTo(container);
$(container).appendTo(mainDiv);
$(runTime).appendTo(mainDiv);
$(cronContainer).append(mainDiv);
var that = $(this);
@ -351,9 +354,13 @@
return $(cronContainer).html();
},
template: '<div class="popover" style="max-width:500px !important; width:425px;left:-341.656px;"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>',
sanitize:false,
placement: options.direction
}).on('click', function (e) {
if (inputElement.val().trim() !== '') {
refreshRunTime();
}
e.preventDefault();
//fillDataOfMinutesAndHoursSelectOptions();
@ -374,6 +381,7 @@
});
$("#CronGenMainDiv select,input").change(function (e) {
generate();
refreshRunTime();
});
$("#CronGenMainDiv input").focus(function (e) {
generate();
@ -628,6 +636,25 @@
displayElement.val(results);
};
var refreshRunTime = function () {
$.ajax({
type : 'GET',
url : base_url + "/jobinfo/nextTriggerTime",
data : {
"scheduleType" : 'CRON',
"scheduleConf" : inputElement.val()
},
dataType : "json",
success : function(data){
if (data.code === 200) {
$('#runTime').val(data.content.join("\n"));
} else {
$('#runTime').val(data.msg);
}
}
});
};
})(jQuery);
(function($) {
@ -1011,12 +1038,12 @@
//获取参数中表达式的值
if (cronExpress) {
var regs = cronExpress.split(' ');
$("input[name=secondHidden]").val(regs[0]);
$("input[name=minHidden]").val(regs[1]);
$("input[name=hourHidden]").val(regs[2]);
$("input[name=dayHidden]").val(regs[3]);
$("input[name=monthHidden]").val(regs[4]);
$("input[name=weekHidden]").val(regs[5]);
$("#secondHidden").val(regs[0]);
$("#minHidden").val(regs[1]);
$("#hourHidden").val(regs[2]);
$("#dayHidden").val(regs[3]);
$("#monthHidden").val(regs[4]);
$("#weekHidden").val(regs[5]);
$.fn.cronGen.tools.initObj(regs[0], "second");
$.fn.cronGen.tools.initObj(regs[1], "min");

View File

@ -10,7 +10,7 @@
options = $.extend({}, $.fn.cronGen.defaultOptions, options);
//create top menu
var cronContainer = $("<div/>", { id: "CronContainer", style: "display:none;width:300px;height:300px;" });
var mainDiv = $("<div/>", { id: "CronGenMainDiv", style: "width:410px;height:300px;" });
var mainDiv = $("<div/>", { id: "CronGenMainDiv", style: "width:410px;height:420px;" });
var topMenu = $("<ul/>", { "class": "nav nav-tabs", id: "CronGenTabs" });
$('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu);
$('<li/>').html($('<a id="MinutesTab" href="#Minutes">Minute</a>')).appendTo(topMenu);
@ -318,9 +318,12 @@
// resultsName = $(this).prop("id");
// $(this).prop("name", resultsName);
var runTime = '<br style="padding-top: 10px"><label>Recent Run Time: </label></br><textarea id="runTime" rows="6" style="width: 90%;resize: none;background: none;border: none;outline: none;" readonly = readonly></textarea></div>';
$(span12).appendTo(row);
$(row).appendTo(container);
$(container).appendTo(mainDiv);
$(runTime).appendTo(mainDiv);
$(cronContainer).append(mainDiv);
var that = $(this);
@ -351,9 +354,13 @@
return $(cronContainer).html();
},
template: '<div class="popover" style="max-width:500px !important; width:425px;left:-341.656px;"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>',
sanitize:false,
placement: options.direction
}).on('click', function (e) {
if (inputElement.val().trim() !== '') {
refreshRunTime();
}
e.preventDefault();
//fillDataOfMinutesAndHoursSelectOptions();
@ -374,6 +381,7 @@
});
$("#CronGenMainDiv select,input").change(function (e) {
generate();
refreshRunTime();
});
$("#CronGenMainDiv input").focus(function (e) {
generate();
@ -628,6 +636,25 @@
displayElement.val(results);
};
var refreshRunTime = function () {
$.ajax({
type : 'GET',
url : base_url + "/jobinfo/nextTriggerTime",
data : {
"scheduleType" : 'CRON',
"scheduleConf" : inputElement.val()
},
dataType : "json",
success : function(data){
if (data.code === 200) {
$('#runTime').val(data.content.join("\n"));
} else {
$('#runTime').val(data.msg);
}
}
});
};
})(jQuery);
(function($) {
@ -1011,12 +1038,12 @@
//获取参数中表达式的值
if (cronExpress) {
var regs = cronExpress.split(' ');
$("input[name=secondHidden]").val(regs[0]);
$("input[name=minHidden]").val(regs[1]);
$("input[name=hourHidden]").val(regs[2]);
$("input[name=dayHidden]").val(regs[3]);
$("input[name=monthHidden]").val(regs[4]);
$("input[name=weekHidden]").val(regs[5]);
$("#secondHidden").val(regs[0]);
$("#minHidden").val(regs[1]);
$("#hourHidden").val(regs[2]);
$("#dayHidden").val(regs[3]);
$("#monthHidden").val(regs[4]);
$("#weekHidden").val(regs[5]);
$.fn.cronGen.tools.initObj(regs[0], "second");
$.fn.cronGen.tools.initObj(regs[1], "min");

View File

@ -34,9 +34,9 @@
</#macro>
<#macro commonScript>
<!-- jQuery 2.1.4 -->
<!-- jQuery -->
<script src="${request.contextPath}/static/adminlte/bower_components/jquery/jquery.min.js"></script>
<!-- Bootstrap 3.3.5 -->
<!-- Bootstrap -->
<script src="${request.contextPath}/static/adminlte/bower_components/bootstrap/js/bootstrap.min.js"></script>
<!-- FastClick -->
<script src="${request.contextPath}/static/adminlte/bower_components/fastclick/fastclick.js"></script>

View File

@ -28,13 +28,13 @@
<div class="col-xs-3">
<div class="input-group">
<span class="input-group-addon">AppName</span>
<input type="text" class="form-control" id="appname" autocomplete="on" placeholder="${I18n.system_please_input}AppName" >
<input type="text" class="form-control" id="appname" placeholder="${I18n.system_please_input}AppName" >
</div>
</div>
<div class="col-xs-3">
<div class="input-group">
<span class="input-group-addon">${I18n.jobgroup_field_title}</span>
<input type="text" class="form-control" id="title" autocomplete="on" placeholder="${I18n.jobgroup_field_title}" >
<input type="text" class="form-control" id="title" placeholder="${I18n.jobgroup_field_title}" >
</div>
</div>
<div class="col-xs-2">
@ -70,6 +70,25 @@
</section>
</div>
<!-- 注册列表查看.模态框 -->
<div class="modal fade" id="showRegistryListModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" >${I18n.jobinfo_opt_registryinfo}</h4>
</div>
<div class="modal-body">
<div class="data" style="word-wrap: break-word;"></div>
</div>
<div class="modal-footer">
<div class="text-center" >
<button type="button" class="btn btn-info ok" data-dismiss="modal" >${I18n.system_ok}</button>
</div>
</div>
</div>
</div>
</div>
<!-- 新增.模态框 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog ">
@ -98,7 +117,7 @@
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label>
<div class="col-sm-10">
<textarea class="textarea" name="addressList" maxlength="512" placeholder="${I18n.jobgroup_field_registryList_placeholder}" readonly="readonly" style="background-color:#eee; width: 100%; height: 100px; font-size: 14px; line-height: 15px; border: 1px solid #dddddd; padding: 5px;"></textarea>
<textarea class="textarea" name="addressList" maxlength="20000" placeholder="${I18n.jobgroup_field_registryList_placeholder}" readonly="readonly" style="background-color:#eee; width: 100%; height: 100px; font-size: 14px; line-height: 15px; border: 1px solid #dddddd; padding: 5px;"></textarea>
</div>
</div>
<hr>
@ -142,7 +161,7 @@
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label>
<div class="col-sm-10">
<textarea class="textarea" name="addressList" maxlength="512" placeholder="${I18n.jobgroup_field_registryList_placeholder}" readonly="readonly" style="background-color:#eee; width: 100%; height: 100px; font-size: 14px; line-height: 15px; border: 1px solid #dddddd; padding: 5px;"></textarea>
<textarea class="textarea" name="addressList" maxlength="20000" placeholder="${I18n.jobgroup_field_registryList_placeholder}" readonly="readonly" style="background-color:#eee; width: 100%; height: 100px; font-size: 14px; line-height: 15px; border: 1px solid #dddddd; padding: 5px;"></textarea>
</div>
</div>
<hr>

View File

@ -46,17 +46,17 @@
</div>
<div class="col-xs-2">
<div class="input-group">
<input type="text" class="form-control" id="jobDesc" autocomplete="on" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" >
<input type="text" class="form-control" id="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" >
</div>
</div>
<div class="col-xs-2">
<div class="input-group">
<input type="text" class="form-control" id="executorHandler" autocomplete="on" placeholder="${I18n.system_please_input}JobHandler" >
<input type="text" class="form-control" id="executorHandler" placeholder="${I18n.system_please_input}JobHandler" >
</div>
</div>
<div class="col-xs-2">
<div class="input-group">
<input type="text" class="form-control" id="author" autocomplete="on" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" >
<input type="text" class="form-control" id="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" >
</div>
</div>
<div class="col-xs-1">
@ -80,9 +80,9 @@
<th name="id" >${I18n.jobinfo_field_id}</th>
<th name="jobGroup" >${I18n.jobinfo_field_jobgroup}</th>
<th name="jobDesc" >${I18n.jobinfo_field_jobdesc}</th>
<th name="scheduleType" >${I18n.schedule_type}</th>
<th name="glueType" >${I18n.jobinfo_field_gluetype}</th>
<th name="executorParam" >${I18n.jobinfo_field_executorparam}</th>
<th name="jobCron" >Cron</th>
<th name="executorParam" >${I18n.jobinfo_field_executorparam}</th>
<th name="addTime" >addTime</th>
<th name="updateTime" >updateTime</th>
<th name="author" >${I18n.jobinfo_field_author}</th>
@ -114,6 +114,8 @@
</div>
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_base}</p> <#-- 基础信息 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4">
@ -123,11 +125,74 @@
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_schedule}</p> <#-- 调度 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.schedule_type}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control scheduleType" name="scheduleType" >
<#list ScheduleTypeEnum as item>
<option value="${item}" <#if 'CRON' == item >selected</#if> >${item.title}</option>
</#list>
</select>
</div>
<input type="hidden" name="scheduleConf" />
<div class="schedule_conf schedule_conf_NONE" style="display: none" >
</div>
<div class="schedule_conf schedule_conf_CRON" >
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_CRON" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
</div>
<div class="schedule_conf schedule_conf_FIX_RATE" style="display: none" >
<label for="lastname" class="col-sm-2 control-label">${I18n.schedule_type_fix_rate}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_FIX_RATE" placeholder="${I18n.system_please_input} Second " maxlength="10" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
<div class="schedule_conf schedule_conf_FIX_DELAY" style="display: none" >
<label for="lastname" class="col-sm-2 control-label">${I18n.schedule_type_fix_delay}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_FIX_DELAY" placeholder="${I18n.system_please_input} Second " maxlength="10" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_job}</p> <#-- 任务配置 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control glueType" name="glueType" >
<#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option>
</#list>
</select>
</div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-10">
<textarea class="textarea form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" style="height: 63px; line-height: 1.2;"></textarea>
</div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_advanced}</p> <#-- 高级配置 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="black">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item>
@ -135,23 +200,22 @@
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<label for="firstname" class="col-sm-2 control-label">${I18n.misfire_strategy}<font color="black">*</font></label>
<div class="col-sm-4">
<select class="form-control glueType" name="glueType" >
<#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option>
</#list>
<select class="form-control" name="misfireStrategy" >
<#list MisfireStrategyEnum as item>
<option value="${item}" <#if 'DO_NOTHING' == item >selected</#if> >${item.title}</option>
</#list>
</select>
</div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label>
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="black">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item>
@ -159,26 +223,13 @@
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-10">
<textarea class="textarea form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" style="height: 63px; line-height: 1.2;"></textarea>
</div>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
<hr>
@ -194,16 +245,14 @@
<textarea class="glueSource_java" style="display:none;" >
package com.xxl.job.service.handler;
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.IJobHandler;
public class DemoGlueJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
XxlJobLogger.log("XXL-JOB, Hello World.");
return ReturnT.SUCCESS;
public void execute() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
}
}
@ -310,71 +359,122 @@ exit 0
</div>
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<div class="form-group">
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_base}</p> <#-- 基础信息 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="jobGroup" >
<#list JobGroupList as group>
<option value="${group.id}" >${group.title}</option>
</#list>
<#list JobGroupList as group>
<option value="${group.id}" >${group.title}</option>
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_jobdesc}" maxlength="50" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item>
<option value="${item}" >${item.title}</option>
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control glueType" name="glueType" disabled >
<#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option>
</#list>
</select>
</div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item>
<option value="${item}" >${item.title}</option>
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_author}" maxlength="50" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_alarmemail}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_schedule}</p> <#-- 调度配置 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.schedule_type}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control scheduleType" name="scheduleType" >
<#list ScheduleTypeEnum as item>
<option value="${item}" >${item.title}</option>
</#list>
</select>
</div>
<input type="hidden" name="scheduleConf" />
<div class="schedule_conf schedule_conf_NONE" style="display: none" >
</div>
<div class="schedule_conf schedule_conf_CRON" >
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_CRON" placeholder="${I18n.system_please_input}Cron" maxlength="128" ></div>
</div>
<div class="schedule_conf schedule_conf_FIX_RATE" style="display: none" >
<label for="lastname" class="col-sm-2 control-label">${I18n.schedule_type_fix_rate}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_FIX_RATE" placeholder="${I18n.system_please_input} Second " maxlength="10" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
<div class="schedule_conf schedule_conf_FIX_DELAY" style="display: none" >
<label for="lastname" class="col-sm-2 control-label">${I18n.schedule_type_fix_delay}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="schedule_conf_FIX_DELAY" placeholder="${I18n.system_please_input} Second " maxlength="10" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_job}</p> <#-- 任务配置 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_gluetype}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control glueType" name="glueType" disabled >
<#list GlueTypeEnum as item>
<option value="${item}" >${item.desc}</option>
</#list>
</select>
</div>
<label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="${I18n.system_please_input}JobHandler" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-10">
<textarea class="textarea form-control" name="executorParam" placeholder="${I18n.system_please_input}${I18n.jobinfo_field_executorparam}" maxlength="512" style="height: 63px; line-height: 1.2;"></textarea>
</div>
</div>
</div>
<br>
<p style="margin: 0 0 10px;text-align: left;border-bottom: 1px solid #e5e5e5;color: gray;">${I18n.jobinfo_conf_advanced}</p> <#-- 高级配置 -->
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorRouteStrategy}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item>
<option value="${item}" >${item.title}</option>
</#list>
</select>
</div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_childJobId}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="childJobId" placeholder="${I18n.jobinfo_field_childJobId_placeholder}" maxlength="100" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.misfire_strategy}<font color="black">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="misfireStrategy" >
<#list MisfireStrategyEnum as item>
<option value="${item}" <#if 'DO_NOTHING' == item >selected</#if> >${item.title}</option>
</#list>
</select>
</div>
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="red">*</font></label>
<div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item>
<option value="${item}" >${item.title}</option>
</#list>
</select>
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorTimeout" placeholder="${I18n.jobinfo_field_executorTimeout_placeholder}" maxlength="6" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorFailRetryCount}<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorFailRetryCount" placeholder="${I18n.jobinfo_field_executorFailRetryCount_placeholder}" maxlength="4" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" ></div>
</div>
<hr>

View File

@ -48,7 +48,6 @@
<pre style="font-size:12px;position:relative;" >
<div id="logConsole"></div>
<li class="fa fa-refresh fa-spin" style="font-size: 20px;float: left;" id="logConsoleRunning" ></li>
<div><hr><hr></div>
</pre>
</section>
</div>
@ -63,8 +62,6 @@
// 参数
var triggerCode = '${triggerCode}';
var handleCode = '${handleCode}';
var executorAddress = '${executorAddress!}';
var triggerTime = '${triggerTime?c}';
var logId = '${logId}';
</script>
<script src="${request.contextPath}/static/js/joblog.detail.1.js"></script>

View File

@ -74,7 +74,7 @@
</div>
<div class="col-xs-1">
<button class="btn btn-block btn-nomal" id="clearLog">${I18n.joblog_clean}</button>
<button class="btn btn-block btn-default" id="clearLog">${I18n.joblog_clean}</button>
</div>
</div>
@ -123,7 +123,7 @@
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<div class="form-group">
<label class="col-sm-3 control-label"">${I18n.jobinfo_field_jobgroup}</label>
<label class="col-sm-3 control-label">${I18n.jobinfo_field_jobgroup}</label>
<div class="col-sm-9">
<input type="text" class="form-control jobGroupText" readonly >
<input type="hidden" name="jobGroup" >
@ -131,7 +131,7 @@
</div>
<div class="form-group">
<label class="col-sm-3 control-label"">${I18n.jobinfo_job}</label>
<label class="col-sm-3 control-label">${I18n.jobinfo_job}</label>
<div class="col-sm-9">
<input type="text" class="form-control jobIdText" readonly >
<input type="hidden" name="jobId" >
@ -139,7 +139,7 @@
</div>
<div class="form-group">
<label class="col-sm-3 control-label"">${I18n.joblog_clean_type}</label>
<label class="col-sm-3 control-label">${I18n.joblog_clean_type}</label>
<div class="col-sm-9">
<select class="form-control" name="type" >
<option value="1" >${I18n.joblog_clean_type_1}</option>

View File

@ -38,7 +38,7 @@
<alibaba.nacos.version>2.0.4</alibaba.nacos.version>
<seata.version>1.5.2</seata.version>
<xxl-job-core.version>2.2.0</xxl-job-core.version>
<xxl-job-core.version>2.4.1</xxl-job-core.version>
<fastjson.version>1.2.83</fastjson.version>
<aviator.version>5.2.6</aviator.version>
<pegdown.version>1.6.0</pegdown.version>

View File

@ -1,5 +1,5 @@
# 是否启用mock
VITE_USE_MOCK = true
VITE_USE_MOCK = false
# 发布路径
VITE_PUBLIC_PATH = /