Merge pull request #7058 from EightMonth/master

修复#6903,升级xxl-job 至2.4.1版本,规避CVE-2024-24113
pull/7199/head
JEECG 2024-08-22 13:30:34 +08:00 committed by GitHub
commit 6846e9fdef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 1763 additions and 844 deletions

View File

@ -1,119 +1,283 @@
# /*
# XXL-JOB v2.2.0 Navicat Premium Data Transfer
# Copyright (c) 2015-present, xuxueli.
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci; Source Server : mysql5.7
use `xxl_job`; 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 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, `id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT 'ID', `job_group` int(11) NOT NULL COMMENT 'ID',
`job_cron` varchar(128) NOT NULL COMMENT 'CRON', `job_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`job_desc` varchar(255) NOT NULL, `add_time` datetime NULL DEFAULT NULL,
`add_time` datetime DEFAULT NULL, `update_time` datetime NULL DEFAULT NULL,
`update_time` datetime DEFAULT NULL, `author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`author` varchar(64) DEFAULT NULL COMMENT '', `alarm_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '', `schedule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NONE' COMMENT '',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '', `schedule_conf` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_handler` varchar(255) DEFAULT NULL COMMENT 'handler', `misfire_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DO_NOTHING' COMMENT '',
`executor_param` varchar(512) DEFAULT NULL COMMENT '', `executor_route_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '', `executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'handler',
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '', `executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '', `executor_block_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE', `executor_timeout` int(11) NOT NULL DEFAULT 0 COMMENT '',
`glue_source` mediumtext COMMENT 'GLUE', `executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE', `glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE',
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE', `glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE',
`child_jobid` varchar(255) DEFAULT NULL COMMENT 'ID', `glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE',
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0-1-', `glue_updatetime` datetime NULL DEFAULT NULL COMMENT 'GLUE',
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '', `child_jobid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ID',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '', `trigger_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-1-',
PRIMARY KEY (`id`) `trigger_last_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `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, `id` bigint(20) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT 'ID', `job_group` int(11) NOT NULL COMMENT 'ID',
`job_id` int(11) NOT NULL COMMENT 'ID', `job_id` int(11) NOT NULL COMMENT 'ID',
`executor_address` varchar(255) DEFAULT NULL COMMENT '', `executor_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_handler` varchar(255) DEFAULT NULL COMMENT 'handler', `executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '', `executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT ' 1/2', `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 '', `executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '',
`trigger_time` datetime DEFAULT NULL COMMENT '-', `trigger_time` datetime NULL DEFAULT NULL COMMENT '-',
`trigger_code` int(11) NOT NULL COMMENT '-', `trigger_code` int(11) NOT NULL COMMENT '-',
`trigger_msg` text COMMENT '-', `trigger_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '-',
`handle_time` datetime DEFAULT NULL COMMENT '-', `handle_time` datetime NULL DEFAULT NULL COMMENT '-',
`handle_code` int(11) NOT NULL COMMENT '-', `handle_code` int(11) NOT NULL COMMENT '-',
`handle_msg` text COMMENT '-', `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-', `alarm_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '0-1-2-3-',
PRIMARY KEY (`id`), PRIMARY KEY (`id`) USING BTREE,
KEY `I_trigger_time` (`trigger_time`), INDEX `I_trigger_time`(`trigger_time`) USING BTREE,
KEY `I_handle_code` (`handle_code`) INDEX `I_handle_code`(`handle_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) 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, `id` int(11) NOT NULL AUTO_INCREMENT,
`trigger_day` datetime DEFAULT NULL COMMENT '-', `trigger_day` datetime NULL DEFAULT NULL COMMENT '-',
`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '-', `running_count` int(11) NOT NULL DEFAULT 0 COMMENT '-',
`suc_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 '-', `fail_count` int(11) NOT NULL DEFAULT 0 COMMENT '-',
PRIMARY KEY (`id`), `update_time` datetime NULL DEFAULT NULL,
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE PRIMARY KEY (`id`) USING BTREE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 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, `id` int(11) NOT NULL AUTO_INCREMENT,
`job_id` int(11) NOT NULL COMMENT 'ID', `job_id` int(11) NOT NULL COMMENT 'ID',
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE', `glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE',
`glue_source` mediumtext COMMENT 'GLUE', `glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE',
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE', `glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE',
`add_time` datetime DEFAULT NULL, `add_time` datetime NULL DEFAULT NULL,
`update_time` datetime DEFAULT NULL, `update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) 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, -- Records of xxl_job_logglue
`registry_group` varchar(50) NOT NULL, -- ----------------------------
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_group` ( -- ----------------------------
-- 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, `id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) NOT NULL COMMENT 'AppName', `registry_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`title` varchar(12) NOT NULL COMMENT '', `registry_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0=1=', `registry_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`address_list` varchar(512) DEFAULT NULL COMMENT '', `update_time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`) USING BTREE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 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, `id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '', `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
`password` varchar(50) NOT NULL COMMENT '', `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
`role` tinyint(4) NOT NULL COMMENT '0-1-', `role` tinyint(4) NOT NULL COMMENT '0-1-',
`permission` varchar(255) DEFAULT NULL COMMENT 'ID', `permission` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ID',
PRIMARY KEY (`id`), PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `i_username` (`username`) USING BTREE UNIQUE INDEX `i_username`(`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) 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 '', -- Records of xxl_job_user
PRIMARY KEY (`lock_name`) -- ----------------------------
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `xxl_job_user` VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
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;
SET FOREIGN_KEY_CHECKS = 1;

View File

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

View File

@ -1,16 +1,27 @@
package com.xxl.job.admin; package com.xxl.job.admin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; 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 * @author xuxueli 2018-10-28 00:38:13
*/ */
@SpringBootApplication @SpringBootApplication
@Slf4j
public class XxlJobAdminApplication { public class XxlJobAdminApplication {
public static void main(String[] args) { 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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; 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.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -51,11 +53,12 @@ public class IndexController {
@RequestMapping("/toLogin") @RequestMapping("/toLogin")
@PermissionLimit(limit=false) @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) { 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) @RequestMapping(value="login", method=RequestMethod.POST)

View File

@ -1,5 +1,6 @@
package com.xxl.job.admin.controller; 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.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobRegistry; import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.admin.core.util.I18nUtil; import com.xxl.job.admin.core.util.I18nUtil;
@ -34,12 +35,14 @@ public class JobGroupController {
private XxlJobRegistryDao xxlJobRegistryDao; private XxlJobRegistryDao xxlJobRegistryDao;
@RequestMapping @RequestMapping
@PermissionLimit(adminuser = true)
public String index(Model model) { public String index(Model model) {
return "jobgroup/jobgroup.index"; return "jobgroup/jobgroup.index";
} }
@RequestMapping("/pageList") @RequestMapping("/pageList")
@ResponseBody @ResponseBody
@PermissionLimit(adminuser = true)
public Map<String, Object> pageList(HttpServletRequest request, public Map<String, Object> pageList(HttpServletRequest request,
@RequestParam(required = false, defaultValue = "0") int start, @RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length, @RequestParam(required = false, defaultValue = "10") int length,
@ -59,6 +62,7 @@ public class JobGroupController {
@RequestMapping("/save") @RequestMapping("/save")
@ResponseBody @ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> save(XxlJobGroup xxlJobGroup){ public ReturnT<String> save(XxlJobGroup xxlJobGroup){
// valid // valid
@ -68,13 +72,23 @@ public class JobGroupController {
if (xxlJobGroup.getAppname().length()<4 || xxlJobGroup.getAppname().length()>64) { if (xxlJobGroup.getAppname().length()<4 || xxlJobGroup.getAppname().length()>64) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_appname_length") ); 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) { if (xxlJobGroup.getTitle()==null || xxlJobGroup.getTitle().trim().length()==0) {
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input") + I18nUtil.getString("jobgroup_field_title")) ); 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.getAddressType()!=0) {
if (xxlJobGroup.getAddressList()==null || xxlJobGroup.getAddressList().trim().length()==0) { if (xxlJobGroup.getAddressList()==null || xxlJobGroup.getAddressList().trim().length()==0) {
return new ReturnT<String>(500, I18nUtil.getString("jobgroup_field_addressType_limit") ); 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(","); String[] addresss = xxlJobGroup.getAddressList().split(",");
for (String item: addresss) { for (String item: addresss) {
if (item==null || item.trim().length()==0) { if (item==null || item.trim().length()==0) {
@ -83,12 +97,16 @@ public class JobGroupController {
} }
} }
// process
xxlJobGroup.setUpdateTime(new Date());
int ret = xxlJobGroupDao.save(xxlJobGroup); int ret = xxlJobGroupDao.save(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL; return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
} }
@RequestMapping("/update") @RequestMapping("/update")
@ResponseBody @ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> update(XxlJobGroup xxlJobGroup){ public ReturnT<String> update(XxlJobGroup xxlJobGroup){
// valid // valid
if (xxlJobGroup.getAppname()==null || xxlJobGroup.getAppname().trim().length()==0) { 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); int ret = xxlJobGroupDao.update(xxlJobGroup);
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL; return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
} }
@ -154,6 +175,7 @@ public class JobGroupController {
@RequestMapping("/remove") @RequestMapping("/remove")
@ResponseBody @ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<String> remove(int id){ public ReturnT<String> remove(int id){
// valid // valid
@ -173,6 +195,7 @@ public class JobGroupController {
@RequestMapping("/loadById") @RequestMapping("/loadById")
@ResponseBody @ResponseBody
@PermissionLimit(adminuser = true)
public ReturnT<XxlJobGroup> loadById(int id){ public ReturnT<XxlJobGroup> loadById(int id){
XxlJobGroup jobGroup = xxlJobGroupDao.load(id); XxlJobGroup jobGroup = xxlJobGroupDao.load(id);
return jobGroup!=null?new ReturnT<XxlJobGroup>(jobGroup):new ReturnT<XxlJobGroup>(ReturnT.FAIL_CODE, null); 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; 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.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser; import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum; 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.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao; import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.service.LoginService; 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.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.glue.GlueTypeEnum; import com.xxl.job.core.glue.GlueTypeEnum;
import com.xxl.job.core.util.DateUtil; import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -24,7 +26,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*; import java.util.*;
/** /**
@ -34,6 +35,7 @@ import java.util.*;
@Controller @Controller
@RequestMapping("/jobinfo") @RequestMapping("/jobinfo")
public class JobInfoController { public class JobInfoController {
private static Logger logger = LoggerFactory.getLogger(JobInfoController.class);
@Resource @Resource
private XxlJobGroupDao xxlJobGroupDao; private XxlJobGroupDao xxlJobGroupDao;
@ -47,6 +49,8 @@ public class JobInfoController {
model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典
model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典
model.addAttribute("ScheduleTypeEnum", ScheduleTypeEnum.values()); // 调度类型
model.addAttribute("MisfireStrategyEnum", MisfireStrategyEnum.values()); // 调度过期策略
// 执行器列表 // 执行器列表
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll(); List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
@ -131,36 +135,38 @@ public class JobInfoController {
@RequestMapping("/trigger") @RequestMapping("/trigger")
@ResponseBody @ResponseBody
//@PermissionLimit(limit = false) public ReturnT<String> triggerJob(HttpServletRequest request, int id, String executorParam, String addressList) {
public ReturnT<String> triggerJob(int id, String executorParam, String addressList) { // login user
// force cover job param XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
if (executorParam == null) { // trigger
executorParam = ""; return xxlJobService.trigger(loginUser, id, executorParam, addressList);
}
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
return ReturnT.SUCCESS;
} }
@RequestMapping("/nextTriggerTime") @RequestMapping("/nextTriggerTime")
@ResponseBody @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<>(); List<String> result = new ArrayList<>();
try { try {
CronExpression cronExpression = new CronExpression(cron);
Date lastTime = new Date(); Date lastTime = new Date();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
lastTime = cronExpression.getNextValidTimeAfter(lastTime); lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
if (lastTime != null) { if (lastTime != null) {
result.add(DateUtil.formatDateTime(lastTime)); result.add(DateUtil.formatDateTime(lastTime));
} else { } else {
break; break;
} }
} }
} catch (ParseException e) { } catch (Exception e) {
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid")); 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); return new ReturnT<List<String>>(result);
} }
} }

View File

@ -1,5 +1,6 @@
package com.xxl.job.admin.controller; 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.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
@ -19,9 +20,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -128,27 +131,38 @@ public class JobLogController {
model.addAttribute("triggerCode", jobLog.getTriggerCode()); model.addAttribute("triggerCode", jobLog.getTriggerCode());
model.addAttribute("handleCode", jobLog.getHandleCode()); model.addAttribute("handleCode", jobLog.getHandleCode());
model.addAttribute("executorAddress", jobLog.getExecutorAddress());
model.addAttribute("triggerTime", jobLog.getTriggerTime().getTime());
model.addAttribute("logId", jobLog.getId()); model.addAttribute("logId", jobLog.getId());
return "joblog/joblog.detail"; return "joblog/joblog.detail";
} }
@RequestMapping("/logDetailCat") @RequestMapping("/logDetailCat")
@ResponseBody @ResponseBody
public ReturnT<LogResult> logDetailCat(String executorAddress, long triggerTime, long logId, int fromLineNum){ public ReturnT<LogResult> logDetailCat(long logId, int fromLineNum){
try { try {
ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(executorAddress); // valid
ReturnT<LogResult> logResult = executorBiz.log(new LogParam(triggerTime, logId, fromLineNum)); 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 // is end
if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) { if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
XxlJobLog jobLog = xxlJobLogDao.load(logId);
if (jobLog.getHandleCode() > 0) { if (jobLog.getHandleCode() > 0) {
logResult.getContent().setEnd(true); 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; return logResult;
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
@ -183,7 +197,7 @@ public class JobLogController {
log.setHandleCode(ReturnT.FAIL_CODE); log.setHandleCode(ReturnT.FAIL_CODE);
log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():"")); log.setHandleMsg( I18nUtil.getString("joblog_kill_log_byman")+":" + (runResult.getMsg()!=null?runResult.getMsg():""));
log.setHandleTime(new Date()); log.setHandleTime(new Date());
xxlJobLogDao.updateHandleInfo(log); XxlJobCompleter.updateHandleInfoAndFinish(log);
return new ReturnT<String>(runResult.getMsg()); return new ReturnT<String>(runResult.getMsg());
} else { } else {
return new ReturnT<String>(500, runResult.getMsg()); 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); List<XxlJobUser> list = xxlJobUserDao.pageList(start, length, username, role);
int list_count = xxlJobUserDao.pageListCount(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 // package result
Map<String, Object> maps = new HashMap<String, Object>(); Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数 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.FtlUtil;
import com.xxl.job.admin.core.util.I18nUtil; import com.xxl.job.admin.core.util.I18nUtil;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -17,7 +17,7 @@ import java.util.HashMap;
* @author xuxueli 2015-12-12 18:09:04 * @author xuxueli 2015-12-12 18:09:04
*/ */
@Component @Component
public class CookieInterceptor extends HandlerInterceptorAdapter { public class CookieInterceptor implements AsyncHandlerInterceptor {
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@ -36,8 +36,7 @@ public class CookieInterceptor extends HandlerInterceptorAdapter {
if (modelAndView != null) { if (modelAndView != null) {
modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName())); 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 com.xxl.job.admin.service.LoginService;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod; 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.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -18,7 +18,7 @@ import javax.servlet.http.HttpServletResponse;
* @author xuxueli 2015-12-12 18:09:04 * @author xuxueli 2015-12-12 18:09:04
*/ */
@Component @Component
public class PermissionInterceptor extends HandlerInterceptorAdapter { public class PermissionInterceptor implements AsyncHandlerInterceptor {
@Resource @Resource
private LoginService loginService; private LoginService loginService;
@ -27,7 +27,7 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) { if (!(handler instanceof HandlerMethod)) {
return super.preHandle(request, response, handler); return true; // proceed with the next interceptor
} }
// if need login // if need login
@ -43,8 +43,8 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
if (needLogin) { if (needLogin) {
XxlJobUser loginUser = loginService.ifLogin(request, response); XxlJobUser loginUser = loginService.ifLogin(request, response);
if (loginUser == null) { if (loginUser == null) {
response.sendRedirect(request.getContextPath() + "/toLogin"); response.setStatus(302);
//request.getRequestDispatcher("/toLogin").forward(request, response); response.setHeader("location", request.getContextPath()+"/toLogin");
return false; return false;
} }
if (needAdminuser && loginUser.getRole()!=1) { if (needAdminuser && loginUser.getRole()!=1) {
@ -53,7 +53,7 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); 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 // if json
boolean isJson = false; boolean isJson = false;
HandlerMethod method = (HandlerMethod)handler; if (handler instanceof HandlerMethod) {
ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class); HandlerMethod method = (HandlerMethod)handler;
if (responseBody != null) { ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
isJson = true; if (responseBody != null) {
isJson = true;
}
} }
// error result // error result

View File

@ -66,7 +66,7 @@ public class EmailJobAlarm implements JobAlarm {
MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage(); MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailUserName(), personal); helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailFrom(), personal);
helper.setTo(email); helper.setTo(email);
helper.setSubject(title); helper.setSubject(title);
helper.setText(content, true); 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}") @Value("${xxl.job.accessToken}")
private String accessToken; private String accessToken;
@Value("${spring.mail.username}") @Value("${spring.mail.from}")
private String emailUserName; private String emailFrom;
@Value("${xxl.job.triggerpool.fast.max}") @Value("${xxl.job.triggerpool.fast.max}")
private int triggerPoolFastMax; private int triggerPoolFastMax;
@ -98,8 +98,8 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
return accessToken; return accessToken;
} }
public String getEmailUserName() { public String getEmailFrom() {
return emailUserName; return emailFrom;
} }
public int getTriggerPoolFastMax() { 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 * @param cronExpression String representation of the cron expression the
* new object should represent * new object should represent
* @throws java.text.ParseException * @throws ParseException
* if the string expression cannot be parsed into a valid * if the string expression cannot be parsed into a valid
* <CODE>CronExpression</CODE> * <CODE>CronExpression</CODE>
*/ */
@ -363,9 +363,8 @@ public final class CronExpression implements Serializable, Cloneable {
// the second immediately following it. // the second immediately following it.
while (difference == 1000) { while (difference == 1000) {
newDate = getTimeAfter(lastDate); newDate = getTimeAfter(lastDate);
if(newDate == null) { if(newDate == null)
break; break;
}
difference = newDate.getTime() - lastDate.getTime(); difference = newDate.getTime() - lastDate.getTime();
@ -533,7 +532,7 @@ public final class CronExpression implements Serializable, Cloneable {
return i; return i;
} }
char c = s.charAt(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); String sub = s.substring(i, i + 3);
int sval = -1; int sval = -1;
int eval = -1; int eval = -1;
@ -669,9 +668,8 @@ public final class CronExpression implements Serializable, Cloneable {
if(c == '-') { if(c == '-') {
ValueSet vs = getValue(0, s, i+1); ValueSet vs = getValue(0, s, i+1);
lastdayOffset = vs.value; lastdayOffset = vs.value;
if(lastdayOffset > 30) { if(lastdayOffset > 30)
throw new ParseException("Offset from last day must be <= 30", i+1); throw new ParseException("Offset from last day must be <= 30", i+1);
}
i = vs.pos; i = vs.pos;
} }
if(s.length() > i) { if(s.length() > i) {
@ -734,9 +732,8 @@ public final class CronExpression implements Serializable, Cloneable {
if (c == 'L') { if (c == 'L') {
if (type == DAY_OF_WEEK) { 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); throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
}
lastdayOfWeek = true; lastdayOfWeek = true;
} else { } else {
throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i); throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
@ -753,9 +750,8 @@ public final class CronExpression implements Serializable, Cloneable {
} else { } else {
throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i); throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
} }
if(val > 31) { 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); 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); TreeSet<Integer> set = getSet(type);
set.add(val); set.add(val);
i++; i++;
@ -1284,7 +1280,7 @@ public final class CronExpression implements Serializable, Cloneable {
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR)); day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
day -= lastdayOffset; day -= lastdayOffset;
java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone()); Calendar tcal = Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0); tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0); tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0); tcal.set(Calendar.HOUR_OF_DAY, 0);
@ -1320,7 +1316,7 @@ public final class CronExpression implements Serializable, Cloneable {
t = day; t = day;
day = daysOfMonth.first(); 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.SECOND, 0);
tcal.set(Calendar.MINUTE, 0); tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 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 * @param hour the hour to set
*/ */
protected void setCalendarHour(Calendar cal, int hour) { protected void setCalendarHour(Calendar cal, int hour) {
cal.set(java.util.Calendar.HOUR_OF_DAY, hour); cal.set(Calendar.HOUR_OF_DAY, hour);
if (cal.get(java.util.Calendar.HOUR_OF_DAY) != hour && hour != 24) { if (cal.get(Calendar.HOUR_OF_DAY) != hour && hour != 24) {
cal.set(java.util.Calendar.HOUR_OF_DAY, hour + 1); 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -14,6 +15,7 @@ public class XxlJobGroup {
private String title; private String title;
private int addressType; // 执行器地址类型0=自动注册、1=手动录入 private int addressType; // 执行器地址类型0=自动注册、1=手动录入
private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入) private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
private Date updateTime;
// registry list // registry list
private List<String> registryList; // 执行器地址列表(系统注册) private List<String> registryList; // 执行器地址列表(系统注册)
@ -60,6 +62,14 @@ public class XxlJobGroup {
return addressList; return addressList;
} }
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public void setAddressList(String addressList) { public void setAddressList(String addressList) {
this.addressList = addressList; this.addressList = addressList;
} }

View File

@ -12,7 +12,6 @@ public class XxlJobInfo {
private int id; // 主键ID private int id; // 主键ID
private int jobGroup; // 执行器主键ID private int jobGroup; // 执行器主键ID
private String jobCron; // 任务执行CRON表达式
private String jobDesc; private String jobDesc;
private Date addTime; private Date addTime;
@ -21,6 +20,10 @@ public class XxlJobInfo {
private String author; // 负责人 private String author; // 负责人
private String alarmEmail; // 报警邮件 private String alarmEmail; // 报警邮件
private String scheduleType; // 调度类型
private String scheduleConf; // 调度配置,值含义取决于调度类型
private String misfireStrategy; // 调度过期策略
private String executorRouteStrategy; // 执行器路由策略 private String executorRouteStrategy; // 执行器路由策略
private String executorHandler; // 执行器任务Handler名称 private String executorHandler; // 执行器任务Handler名称
private String executorParam; // 执行器,任务参数 private String executorParam; // 执行器,任务参数
@ -56,14 +59,6 @@ public class XxlJobInfo {
this.jobGroup = jobGroup; this.jobGroup = jobGroup;
} }
public String getJobCron() {
return jobCron;
}
public void setJobCron(String jobCron) {
this.jobCron = jobCron;
}
public String getJobDesc() { public String getJobDesc() {
return jobDesc; return jobDesc;
} }
@ -104,6 +99,30 @@ public class XxlJobInfo {
this.alarmEmail = alarmEmail; 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() { public String getExecutorRouteStrategy() {
return executorRouteStrategy; 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.thread.JobTriggerPoolHelper;
//import com.xxl.job.admin.core.trigger.TriggerTypeEnum; //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.conf.XxlJobAdminConfig;
//import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean; //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.SchedulerConfigException;
//import org.quartz.spi.ThreadPool; //import org.quartz.spi.ThreadPool;

View File

@ -8,14 +8,16 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Created by xuxueli on 17/3/10. * Created by xuxueli on 17/3/10.
*/ */
public class ExecutorRouteRound extends ExecutorRouter { 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 long CACHE_VALID_TIME = 0;
private static int count(int jobId) { private static int count(int jobId) {
// cache clear // cache clear
if (System.currentTimeMillis() > CACHE_VALID_TIME) { if (System.currentTimeMillis() > CACHE_VALID_TIME) {
@ -23,11 +25,16 @@ public class ExecutorRouteRound extends ExecutorRouter {
CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
} }
// count++ AtomicInteger count = routeCountEachJob.get(jobId);
Integer count = routeCountEachJob.get(jobId); if (count == null || count.get() > 1000000) {
count = (count==null || count>1000000)?(new Random().nextInt(100)):++count; // 初始化时主动Random一次缓解首次压力 // 初始化时主动Random一次缓解首次压力
count = new AtomicInteger(new Random().nextInt(100));
} else {
// count++
count.addAndGet(1);
}
routeCountEachJob.put(jobId, count); routeCountEachJob.put(jobId, count);
return count; return count.get();
} }
@Override @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 // init i18n
initI18n(); initI18n();
// admin trigger pool start
JobTriggerPoolHelper.toStart();
// admin registry monitor run // admin registry monitor run
JobRegistryMonitorHelper.getInstance().start(); JobRegistryHelper.getInstance().start();
// admin fail-monitor run // admin fail-monitor run
JobFailMonitorHelper.getInstance().start(); JobFailMonitorHelper.getInstance().start();
// admin lose-monitor run // admin lose-monitor run ( depend on JobTriggerPoolHelper )
JobLosedMonitorHelper.getInstance().start(); JobCompleteHelper.getInstance().start();
// admin trigger pool start
JobTriggerPoolHelper.toStart();
// admin log report start // admin log report start
JobLogReportHelper.getInstance().start(); JobLogReportHelper.getInstance().start();
// start-schedule // start-schedule ( depend on JobTriggerPoolHelper )
JobScheduleHelper.getInstance().start(); JobScheduleHelper.getInstance().start();
logger.info(">>>>>>>>> init xxl-job admin success."); logger.info(">>>>>>>>> init xxl-job admin success.");
@ -54,17 +54,17 @@ public class XxlJobScheduler {
// admin log report stop // admin log report stop
JobLogReportHelper.getInstance().toStop(); JobLogReportHelper.getInstance().toStop();
// admin trigger pool stop
JobTriggerPoolHelper.toStop();
// admin lose-monitor stop // admin lose-monitor stop
JobLosedMonitorHelper.getInstance().toStop(); JobCompleteHelper.getInstance().toStop();
// admin fail-monitor stop // admin fail-monitor stop
JobFailMonitorHelper.getInstance().toStop(); JobFailMonitorHelper.getInstance().toStop();
// admin registry stop // 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 // 2、fail alarm monitor
int newAlarmStatus = 0; // 告警状态0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败 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); boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult?2:3; newAlarmStatus = alarmResult?2:3;
} else { } 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.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.cron.CronExpression; import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobInfo; 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 com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -10,7 +12,6 @@ import org.slf4j.LoggerFactory;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.ParseException;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -86,7 +87,15 @@ public class JobScheduleHelper {
// 2.1、trigger-expire > 5spass && make next-trigger-time // 2.1、trigger-expire > 5spass && make next-trigger-time
logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId()); 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()); refreshNextValidTime(jobInfo, new Date());
} else if (nowTime > jobInfo.getTriggerNextTime()) { } else if (nowTime > jobInfo.getTriggerNextTime()) {
@ -213,17 +222,17 @@ public class JobScheduleHelper {
@Override @Override
public void run() { 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) { while (!ringThreadToStop) {
// align second
try {
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
} catch (InterruptedException e) {
if (!ringThreadToStop) {
logger.error(e.getMessage(), e);
}
}
try { try {
// second data // second data
List<Integer> ringItemData = new ArrayList<>(); List<Integer> ringItemData = new ArrayList<>();
@ -251,15 +260,6 @@ public class JobScheduleHelper {
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e); 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"); logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
} }
@ -269,8 +269,8 @@ public class JobScheduleHelper {
ringThread.start(); ringThread.start();
} }
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws ParseException { private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(fromTime); Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
if (nextValidTime != null) { if (nextValidTime != null) {
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime()); jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
jobInfo.setTriggerNextTime(nextValidTime.getTime()); jobInfo.setTriggerNextTime(nextValidTime.getTime());
@ -278,6 +278,8 @@ public class JobScheduleHelper {
jobInfo.setTriggerStatus(0); jobInfo.setTriggerStatus(0);
jobInfo.setTriggerLastTime(0); jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(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"); 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")), CRON(I18nUtil.getString("jobconf_trigger_type_cron")),
RETRY(I18nUtil.getString("jobconf_trigger_type_retry")), RETRY(I18nUtil.getString("jobconf_trigger_type_retry")),
PARENT(I18nUtil.getString("jobconf_trigger_type_parent")), 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){ private TriggerTypeEnum(String title){
this.title = 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.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.biz.model.ReturnT;
import java.util.Date; import java.util.Date;
@ -67,6 +68,17 @@ public interface XxlJobService {
*/ */
public ReturnT<String> stop(int id); 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 * dashboard info
* *

View File

@ -1,27 +1,13 @@
package com.xxl.job.admin.service.impl; package com.xxl.job.admin.service.impl;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.thread.JobCompleteHelper;
import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.thread.JobRegistryHelper;
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.core.biz.AdminBiz; import com.xxl.job.core.biz.AdminBiz;
import com.xxl.job.core.biz.model.HandleCallbackParam; import com.xxl.job.core.biz.model.HandleCallbackParam;
import com.xxl.job.core.biz.model.RegistryParam; import com.xxl.job.core.biz.model.RegistryParam;
import com.xxl.job.core.biz.model.ReturnT; 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.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -29,147 +15,21 @@ import java.util.List;
*/ */
@Service @Service
public class AdminBizImpl implements AdminBiz { 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 @Override
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) { public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
for (HandleCallbackParam handleCallbackParam: callbackParamList) { return JobCompleteHelper.getInstance().callback(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;
}
} }
@Override @Override
public ReturnT<String> registry(RegistryParam registryParam) { public ReturnT<String> registry(RegistryParam registryParam) {
return JobRegistryHelper.getInstance().registry(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;
} }
@Override @Override
public ReturnT<String> registryRemove(RegistryParam registryParam) { public ReturnT<String> registryRemove(RegistryParam registryParam) {
return JobRegistryHelper.getInstance().registryRemove(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
} }
} }

View File

@ -1,11 +1,16 @@
package com.xxl.job.admin.service.impl; 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.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo; 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.XxlJobLogReport;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; 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.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.core.util.I18nUtil;
import com.xxl.job.admin.dao.*; import com.xxl.job.admin.dao.*;
import com.xxl.job.admin.service.XxlJobService; import com.xxl.job.admin.service.XxlJobService;
@ -19,7 +24,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.ParseException;
import java.util.*; import java.util.*;
/** /**
@ -58,40 +62,67 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override @Override
public ReturnT<String> add(XxlJobInfo jobInfo) { public ReturnT<String> add(XxlJobInfo jobInfo) {
// valid
// valid base
XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
if (group == null) { if (group == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) ); 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) { 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")) ); 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) { 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")) ); 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) { if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); 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) { if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) ); 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) ) { 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") ); 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) { if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) {
jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", ""));
} }
// ChildJobId valid // valid advanced
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) { 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(","); String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) { if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
@ -140,25 +171,50 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override @Override
public ReturnT<String> update(XxlJobInfo jobInfo) { public ReturnT<String> update(XxlJobInfo jobInfo) {
// valid // valid base
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) { 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")) ); 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) { 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")) ); 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) { if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); 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) { if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) );
} }
// ChildJobId valid // ChildJobId valid
if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) { if (jobInfo.getChildJobId()!=null && jobInfo.getChildJobId().trim().length()>0) {
String[] childJobIds = jobInfo.getChildJobId().split(","); String[] childJobIds = jobInfo.getChildJobId().split(",");
for (String childJobIdItem: childJobIds) { for (String childJobIdItem: childJobIds) {
if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) { if (childJobIdItem!=null && childJobIdItem.trim().length()>0 && isNumeric(childJobIdItem)) {
@ -197,24 +253,27 @@ public class XxlJobServiceImpl implements XxlJobService {
// next trigger time (5s后生效避开预读周期) // next trigger time (5s后生效避开预读周期)
long nextTriggerTime = exists_jobInfo.getTriggerNextTime(); 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 { 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) { 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(); nextTriggerTime = nextValidTime.getTime();
} catch (ParseException e) { } catch (Exception e) {
logger.error(e.getMessage(), 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.setJobGroup(jobInfo.getJobGroup());
exists_jobInfo.setJobCron(jobInfo.getJobCron());
exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
exists_jobInfo.setAuthor(jobInfo.getAuthor()); exists_jobInfo.setAuthor(jobInfo.getAuthor());
exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); 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.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler()); exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam()); exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
@ -248,17 +307,23 @@ public class XxlJobServiceImpl implements XxlJobService {
public ReturnT<String> start(int id) { public ReturnT<String> start(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(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后生效避开预读周期) // next trigger time (5s后生效避开预读周期)
long nextTriggerTime = 0; long nextTriggerTime = 0;
try { 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) { 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(); nextTriggerTime = nextValidTime.getTime();
} catch (ParseException e) { } catch (Exception e) {
logger.error(e.getMessage(), 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); xxlJobInfo.setTriggerStatus(1);
@ -283,6 +348,42 @@ public class XxlJobServiceImpl implements XxlJobService {
return ReturnT.SUCCESS; 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 @Override
public Map<String, Object> dashboardInfo() { public Map<String, Object> dashboardInfo() {

View File

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

View File

@ -1,6 +1,6 @@
admin_name=Scheduling Center admin_name=Scheduling Center
admin_name_full=Distributed Task Scheduling Platform XXL-JOB admin_name_full=Distributed Task Scheduling Platform XXL-JOB
admin_version=2.2.0 admin_version=2.4.2-SNAPSHOT
admin_i18n=en admin_i18n=en
## system ## system
@ -117,8 +117,6 @@ jobinfo_field_jobdesc=Job description
jobinfo_field_timeout=Job timeout period jobinfo_field_timeout=Job timeout period
jobinfo_field_gluetype=GLUE Type jobinfo_field_gluetype=GLUE Type
jobinfo_field_executorparam=Param 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_author=Author
jobinfo_field_alarmemail=Alarm email jobinfo_field_alarmemail=Alarm email
jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated 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_jobid_unvalid=Job ID is illegal
jobinfo_glue_gluetype_unvalid=The job is not GLUE Type jobinfo_glue_gluetype_unvalid=The job is not GLUE Type
jobinfo_field_executorTimeout_placeholder=Job Timeout periodin seconds. effect if greater than zero 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 ## job log
joblog_name=Trigger 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_parent=Parent job trigger
jobconf_trigger_type_api=Api trigger jobconf_trigger_type_api=Api trigger
jobconf_trigger_type_retry=Fail retry trigger jobconf_trigger_type_retry=Fail retry trigger
jobconf_trigger_type_misfire=Misfire compensation trigger
## user ## user
user_manage=User Manage user_manage=User Manage

View File

@ -1,6 +1,6 @@
admin_name=任务调度中心 admin_name=任务调度中心
admin_name_full=分布式任务调度平台XXL-JOB admin_name_full=分布式任务调度平台XXL-JOB
admin_version=2.2.0 admin_version=2.4.2-SNAPSHOT
admin_i18n= admin_i18n=
## system ## system
@ -116,8 +116,6 @@ jobinfo_field_jobgroup=执行器
jobinfo_field_jobdesc=任务描述 jobinfo_field_jobdesc=任务描述
jobinfo_field_gluetype=运行模式 jobinfo_field_gluetype=运行模式
jobinfo_field_executorparam=任务参数 jobinfo_field_executorparam=任务参数
jobinfo_field_cron_unvalid=Cron格式非法
jobinfo_field_cron_never_fire=Cron非法永远不会触发
jobinfo_field_author=负责人 jobinfo_field_author=负责人
jobinfo_field_timeout=任务超时时间 jobinfo_field_timeout=任务超时时间
jobinfo_field_alarmemail=报警邮件 jobinfo_field_alarmemail=报警邮件
@ -144,6 +142,19 @@ jobinfo_glue_rollback=版本回溯
jobinfo_glue_jobid_unvalid=任务ID非法 jobinfo_glue_jobid_unvalid=任务ID非法
jobinfo_glue_gluetype_unvalid=该任务非GLUE模式 jobinfo_glue_gluetype_unvalid=该任务非GLUE模式
jobinfo_field_executorTimeout_placeholder=任务超时时间,单位秒,大于零时生效 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 ## job log
joblog_name=调度日志 joblog_name=调度日志
@ -243,6 +254,7 @@ jobconf_trigger_type_manual=手动触发
jobconf_trigger_type_parent=父任务触发 jobconf_trigger_type_parent=父任务触发
jobconf_trigger_type_api=API触发 jobconf_trigger_type_api=API触发
jobconf_trigger_type_retry=失败重试触发 jobconf_trigger_type_retry=失败重试触发
jobconf_trigger_type_misfire=调度过期补偿
## user ## user
user_manage=用户管理 user_manage=用户管理

View File

@ -1,6 +1,6 @@
admin_name=任務調度中心 admin_name=任務調度中心
admin_name_full=分布式任務調度平臺XXL-JOB admin_name_full=分布式任務調度平臺XXL-JOB
admin_version=2.2.0 admin_version=2.4.2-SNAPSHOT
admin_i18n= admin_i18n=
## system ## system
@ -116,8 +116,6 @@ jobinfo_field_jobgroup=執行器
jobinfo_field_jobdesc=任務描述 jobinfo_field_jobdesc=任務描述
jobinfo_field_gluetype=運行模式 jobinfo_field_gluetype=運行模式
jobinfo_field_executorparam=任務參數 jobinfo_field_executorparam=任務參數
jobinfo_field_cron_unvalid=Cron 格式非法
jobinfo_field_cron_never_fire=Cron 格式非法,永遠不會觸發
jobinfo_field_author=負責人 jobinfo_field_author=負責人
jobinfo_field_timeout=任務超時秒數 jobinfo_field_timeout=任務超時秒數
jobinfo_field_alarmemail=告警郵件 jobinfo_field_alarmemail=告警郵件
@ -144,6 +142,19 @@ jobinfo_glue_rollback=版本回復
jobinfo_glue_jobid_unvalid=任務ID非法 jobinfo_glue_jobid_unvalid=任務ID非法
jobinfo_glue_gluetype_unvalid=該任務非GLUE模式 jobinfo_glue_gluetype_unvalid=該任務非GLUE模式
jobinfo_field_executorTimeout_placeholder=任務超時時間,單位秒,大於零時生效 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 ## job log
joblog_name=調度日誌 joblog_name=調度日誌
@ -243,6 +254,7 @@ jobconf_trigger_type_manual=手動觸發
jobconf_trigger_type_parent=父任務觸發 jobconf_trigger_type_parent=父任務觸發
jobconf_trigger_type_api=API觸發 jobconf_trigger_type_api=API觸發
jobconf_trigger_type_retry=失敗重試觸發 jobconf_trigger_type_retry=失敗重試觸發
jobconf_trigger_type_misfire=調度過期補償
## user ## user
user_manage=用户管理 user_manage=用户管理

View File

@ -2,7 +2,7 @@
<configuration debug="false" scan="true" scanPeriod="1 seconds"> <configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName> <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"> <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>

View File

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

View File

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

View File

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

View File

@ -123,7 +123,7 @@ $(function() {
var id = $(this).attr("_id"); var id = $(this).attr("_id");
var row = tableData['key'+id]; var row = tableData['key'+id];
var html = '<div>'; /*var html = '<div>';
if (row.registryList) { if (row.registryList) {
for (var index in row.registryList) { for (var index in row.registryList) {
html += (parseInt(index)+1) + '. <span class="badge bg-green" >' + row.registryList[index] + '</span><br>'; html += (parseInt(index)+1) + '. <span class="badge bg-green" >' + row.registryList[index] + '</span><br>';
@ -135,8 +135,19 @@ $(function() {
title: I18n.jobinfo_opt_registryinfo , title: I18n.jobinfo_opt_registryinfo ,
btn: [ I18n.system_ok ], btn: [ I18n.system_ok ],
content: html 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, "visible" : true,
"width":'25%' "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', "data": 'glueType',
"width":'25%', "width":'25%',
@ -62,11 +74,6 @@ $(function() {
} }
}, },
{ "data": 'executorParam', "visible" : false}, { "data": 'executorParam', "visible" : false},
{
"data": 'jobCron',
"visible" : true,
"width":'13%'
},
{ {
"data": 'addTime', "data": 'addTime',
"visible" : false, "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'; 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 // log url
var logHref = base_url +'/joblog?jobId='+ row.id; var logHref = base_url +'/joblog?jobId='+ row.id;
// log url // code url
var codeBtn = ""; var codeBtn = "";
if ('BEAN' != row.glueType) { if ('BEAN' != row.glueType) {
var codeUrl = base_url +'/jobcode?jobId='+ row.id; 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="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="'+ 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_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' + ' <li class="divider"></li>\n' +
codeBtn + codeBtn +
start_stop_div + start_stop_div +
@ -322,17 +335,16 @@ $(function() {
var id = $(this).parents('ul').attr("_id"); var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id]; var row = tableData['key'+id];
var jobCron = row.jobCron;
$.ajax({ $.ajax({
type : 'POST', type : 'POST',
url : base_url + "/jobinfo/nextTriggerTime", url : base_url + "/jobinfo/nextTriggerTime",
data : { data : {
"cron" : jobCron "scheduleType" : row.scheduleType,
"scheduleConf" : row.scheduleConf
}, },
dataType : "json", dataType : "json",
success : function(data){ success : function(data){
if (data.code != 200) { if (data.code != 200) {
layer.open({ layer.open({
title: I18n.jobinfo_opt_next_time , title: I18n.jobinfo_opt_next_time ,
@ -364,8 +376,14 @@ $(function() {
$(".add").click(function(){ $(".add").click(function(){
// init-cronGen // init-cronGen
$("#addModal .form input[name='jobCron']").show().siblings().remove(); $("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
$("#addModal .form input[name='jobCron']").cronGen({}); $("#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'); $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
@ -378,35 +396,29 @@ $(function() {
required : true, required : true,
maxlength: 50 maxlength: 50
}, },
jobCron : {
required : true
},
author : { author : {
required : true required : true
}, }/*,
executorTimeout : { executorTimeout : {
digits:true digits:true
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits:true digits:true
} }*/
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
}, },
jobCron : {
required : I18n.system_please_input + "Cron"
},
author : { author : {
required : I18n.system_please_input + I18n.jobinfo_field_author required : I18n.system_please_input + I18n.jobinfo_field_author
}, }/*,
executorTimeout : { executorTimeout : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
}, },
executorFailRetryCount : { executorFailRetryCount : {
digits: I18n.system_please_input + I18n.system_digits digits: I18n.system_please_input + I18n.system_digits
} }*/
}, },
highlight : function(element) { highlight : function(element) {
$(element).closest('.form-group').addClass('has-error'); $(element).closest('.form-group').addClass('has-error');
@ -420,7 +432,7 @@ $(function() {
}, },
submitHandler : function(form) { submitHandler : function(form) {
// process // process executorTimeout+executorFailRetryCount
var executorTimeout = $("#addModal .form input[name='executorTimeout']").val(); var executorTimeout = $("#addModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) { if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0; executorTimeout = 0;
@ -432,8 +444,17 @@ $(function() {
} }
$("#addModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount); $("#addModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
// process-cronGen // process schedule_conf
$("#addModal .form input[name='jobCron']").val( $("#addModal .form input[name='cronGen_display']").val() ); 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) { $.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) {
if (data.code == "200") { if (data.code == "200") {
@ -468,6 +489,13 @@ $(function() {
$("#addModal .form input[name='executorHandler']").removeAttr("readonly"); $("#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
$(".glueType").change(function(){ $(".glueType").change(function(){
@ -508,27 +536,46 @@ $(function() {
var id = $(this).parents('ul').attr("_id"); var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id]; var row = tableData['key'+id];
// base data // fill base
$("#updateModal .form input[name='id']").val( row.id ); $("#updateModal .form input[name='id']").val( row.id );
$('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true); $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
$("#updateModal .form input[name='jobDesc']").val( row.jobDesc ); $("#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='author']").val( row.author );
$("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount ); // fill trigger
$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); $('#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 input[name='executorHandler']").val( row.executorHandler );
$("#updateModal .form textarea[name='executorParam']").val( row.executorParam ); $("#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=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
$('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true); $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
$("#updateModal .form select[name=glueType]").change();
// init-cronGen
$("#updateModal .form input[name='jobCron']").show().siblings().remove();
$("#updateModal .form input[name='jobCron']").cronGen({});
// show // show
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
@ -543,35 +590,17 @@ $(function() {
required : true, required : true,
maxlength: 50 maxlength: 50
}, },
jobCron : {
required : true
},
author : { author : {
required : true required : true
}, }
executorTimeout : {
digits:true
},
executorFailRetryCount : {
digits:true
}
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
}, },
jobCron : {
required : I18n.system_please_input + "Cron"
},
author : { author : {
required : I18n.system_please_input + I18n.jobinfo_field_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) { highlight : function(element) {
$(element).closest('.form-group').addClass('has-error'); $(element).closest('.form-group').addClass('has-error');
@ -585,7 +614,7 @@ $(function() {
}, },
submitHandler : function(form) { submitHandler : function(form) {
// process // process executorTimeout + executorFailRetryCount
var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val(); var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val();
if(!/^\d+$/.test(executorTimeout)) { if(!/^\d+$/.test(executorTimeout)) {
executorTimeout = 0; executorTimeout = 0;
@ -597,8 +626,18 @@ $(function() {
} }
$("#updateModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount); $("#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
$.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) { $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) {
@ -653,27 +692,45 @@ $(function() {
var id = $(this).parents('ul').attr("_id"); var id = $(this).parents('ul').attr("_id");
var row = tableData['key'+id]; var row = tableData['key'+id];
// base data // fill base
//$("#addModal .form input[name='id']").val( row.id );
$('#addModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true); $('#addModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
$("#addModal .form input[name='jobDesc']").val( row.jobDesc ); $("#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='author']").val( row.author );
$("#addModal .form input[name='alarmEmail']").val( row.alarmEmail ); $("#addModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#addModal .form input[name='executorTimeout']").val( row.executorTimeout );
$("#addModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount ); // fill trigger
$('#addModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); $('#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 input[name='executorHandler']").val( row.executorHandler );
$("#addModal .form textarea[name='executorParam']").val( row.executorParam ); $("#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(); $("#addModal .form select[name=glueType]").change();
// init-cronGen // 》init-cronGen
$("#addModal .form input[name='jobCron']").show().siblings().remove(); $("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
$("#addModal .form input[name='jobCron']").cronGen({}); $("#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 // show
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');

View File

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

View File

@ -116,7 +116,7 @@ $(function() {
"data": 'triggerTime', "data": 'triggerTime',
"width":'20%', "width":'20%',
"render": function ( data, type, row ) { "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', "data": 'handleTime',
"width":'20%', "width":'20%',
"render": function ( data, type, row ) { "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; //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' + 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">'+ I18n.system_opt +'</button>\n' +
' <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown">\n' + ' <button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown">\n' +
@ -195,8 +201,7 @@ $(function() {
' </button>\n' + ' </button>\n' +
' <ul class="dropdown-menu" role="menu" _id="'+ row.id +'" >\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><a href="javascript:void(0);" class="logDetail" _id="'+ row.id +'" >'+ I18n.joblog_rolling_log +'</a></li>\n' +
' <li class="divider"></li>\n' + logKillDiv +
' <li><a href="javascript:void(0);" class="logKill" _id="'+ row.id +'" >'+ I18n.joblog_kill_log +'</a></li>\n' +
' </ul>\n' + ' </ul>\n' +
' </div>'; ' </div>';

View File

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

View File

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

View File

@ -10,7 +10,7 @@
options = $.extend({}, $.fn.cronGen.defaultOptions, options); options = $.extend({}, $.fn.cronGen.defaultOptions, options);
//create top menu //create top menu
var cronContainer = $("<div/>", { id: "CronContainer", style: "display:none;width:300px;height:300px;" }); 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" }); var topMenu = $("<ul/>", { "class": "nav nav-tabs", id: "CronGenTabs" });
$('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu); $('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu);
$('<li/>').html($('<a id="MinutesTab" href="#Minutes"></a>')).appendTo(topMenu); $('<li/>').html($('<a id="MinutesTab" href="#Minutes"></a>')).appendTo(topMenu);
@ -318,9 +318,12 @@
// resultsName = $(this).prop("id"); // resultsName = $(this).prop("id");
// $(this).prop("name", resultsName); // $(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); $(span12).appendTo(row);
$(row).appendTo(container); $(row).appendTo(container);
$(container).appendTo(mainDiv); $(container).appendTo(mainDiv);
$(runTime).appendTo(mainDiv);
$(cronContainer).append(mainDiv); $(cronContainer).append(mainDiv);
var that = $(this); var that = $(this);
@ -351,9 +354,13 @@
return $(cronContainer).html(); 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>', 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 placement: options.direction
}).on('click', function (e) { }).on('click', function (e) {
if (inputElement.val().trim() !== '') {
refreshRunTime();
}
e.preventDefault(); e.preventDefault();
//fillDataOfMinutesAndHoursSelectOptions(); //fillDataOfMinutesAndHoursSelectOptions();
@ -374,6 +381,7 @@
}); });
$("#CronGenMainDiv select,input").change(function (e) { $("#CronGenMainDiv select,input").change(function (e) {
generate(); generate();
refreshRunTime();
}); });
$("#CronGenMainDiv input").focus(function (e) { $("#CronGenMainDiv input").focus(function (e) {
generate(); generate();
@ -628,6 +636,25 @@
displayElement.val(results); 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); })(jQuery);
(function($) { (function($) {
@ -1011,12 +1038,12 @@
//获取参数中表达式的值 //获取参数中表达式的值
if (cronExpress) { if (cronExpress) {
var regs = cronExpress.split(' '); var regs = cronExpress.split(' ');
$("input[name=secondHidden]").val(regs[0]); $("#secondHidden").val(regs[0]);
$("input[name=minHidden]").val(regs[1]); $("#minHidden").val(regs[1]);
$("input[name=hourHidden]").val(regs[2]); $("#hourHidden").val(regs[2]);
$("input[name=dayHidden]").val(regs[3]); $("#dayHidden").val(regs[3]);
$("input[name=monthHidden]").val(regs[4]); $("#monthHidden").val(regs[4]);
$("input[name=weekHidden]").val(regs[5]); $("#weekHidden").val(regs[5]);
$.fn.cronGen.tools.initObj(regs[0], "second"); $.fn.cronGen.tools.initObj(regs[0], "second");
$.fn.cronGen.tools.initObj(regs[1], "min"); $.fn.cronGen.tools.initObj(regs[1], "min");

View File

@ -10,7 +10,7 @@
options = $.extend({}, $.fn.cronGen.defaultOptions, options); options = $.extend({}, $.fn.cronGen.defaultOptions, options);
//create top menu //create top menu
var cronContainer = $("<div/>", { id: "CronContainer", style: "display:none;width:300px;height:300px;" }); 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" }); var topMenu = $("<ul/>", { "class": "nav nav-tabs", id: "CronGenTabs" });
$('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu); $('<li/>', { 'class': 'active' }).html($('<a id="SecondlyTab" href="#Secondly"></a>')).appendTo(topMenu);
$('<li/>').html($('<a id="MinutesTab" href="#Minutes">Minute</a>')).appendTo(topMenu); $('<li/>').html($('<a id="MinutesTab" href="#Minutes">Minute</a>')).appendTo(topMenu);
@ -318,9 +318,12 @@
// resultsName = $(this).prop("id"); // resultsName = $(this).prop("id");
// $(this).prop("name", resultsName); // $(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); $(span12).appendTo(row);
$(row).appendTo(container); $(row).appendTo(container);
$(container).appendTo(mainDiv); $(container).appendTo(mainDiv);
$(runTime).appendTo(mainDiv);
$(cronContainer).append(mainDiv); $(cronContainer).append(mainDiv);
var that = $(this); var that = $(this);
@ -351,9 +354,13 @@
return $(cronContainer).html(); 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>', 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 placement: options.direction
}).on('click', function (e) { }).on('click', function (e) {
if (inputElement.val().trim() !== '') {
refreshRunTime();
}
e.preventDefault(); e.preventDefault();
//fillDataOfMinutesAndHoursSelectOptions(); //fillDataOfMinutesAndHoursSelectOptions();
@ -374,6 +381,7 @@
}); });
$("#CronGenMainDiv select,input").change(function (e) { $("#CronGenMainDiv select,input").change(function (e) {
generate(); generate();
refreshRunTime();
}); });
$("#CronGenMainDiv input").focus(function (e) { $("#CronGenMainDiv input").focus(function (e) {
generate(); generate();
@ -628,6 +636,25 @@
displayElement.val(results); 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); })(jQuery);
(function($) { (function($) {
@ -1011,12 +1038,12 @@
//获取参数中表达式的值 //获取参数中表达式的值
if (cronExpress) { if (cronExpress) {
var regs = cronExpress.split(' '); var regs = cronExpress.split(' ');
$("input[name=secondHidden]").val(regs[0]); $("#secondHidden").val(regs[0]);
$("input[name=minHidden]").val(regs[1]); $("#minHidden").val(regs[1]);
$("input[name=hourHidden]").val(regs[2]); $("#hourHidden").val(regs[2]);
$("input[name=dayHidden]").val(regs[3]); $("#dayHidden").val(regs[3]);
$("input[name=monthHidden]").val(regs[4]); $("#monthHidden").val(regs[4]);
$("input[name=weekHidden]").val(regs[5]); $("#weekHidden").val(regs[5]);
$.fn.cronGen.tools.initObj(regs[0], "second"); $.fn.cronGen.tools.initObj(regs[0], "second");
$.fn.cronGen.tools.initObj(regs[1], "min"); $.fn.cronGen.tools.initObj(regs[1], "min");

View File

@ -34,9 +34,9 @@
</#macro> </#macro>
<#macro commonScript> <#macro commonScript>
<!-- jQuery 2.1.4 --> <!-- jQuery -->
<script src="${request.contextPath}/static/adminlte/bower_components/jquery/jquery.min.js"></script> <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> <script src="${request.contextPath}/static/adminlte/bower_components/bootstrap/js/bootstrap.min.js"></script>
<!-- FastClick --> <!-- FastClick -->
<script src="${request.contextPath}/static/adminlte/bower_components/fastclick/fastclick.js"></script> <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="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">AppName</span> <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> </div>
<div class="col-xs-3"> <div class="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">${I18n.jobgroup_field_title}</span> <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> </div>
<div class="col-xs-2"> <div class="col-xs-2">
@ -70,6 +70,25 @@
</section> </section>
</div> </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 fade" id="addModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog "> <div class="modal-dialog ">
@ -98,7 +117,7 @@
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label>
<div class="col-sm-10"> <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>
</div> </div>
<hr> <hr>
@ -142,7 +161,7 @@
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">${I18n.jobgroup_field_registryList}<font color="red">*</font></label>
<div class="col-sm-10"> <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>
</div> </div>
<hr> <hr>

View File

@ -46,17 +46,17 @@
</div> </div>
<div class="col-xs-2"> <div class="col-xs-2">
<div class="input-group"> <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> </div>
<div class="col-xs-2"> <div class="col-xs-2">
<div class="input-group"> <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> </div>
<div class="col-xs-2"> <div class="col-xs-2">
<div class="input-group"> <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> </div>
<div class="col-xs-1"> <div class="col-xs-1">
@ -80,9 +80,9 @@
<th name="id" >${I18n.jobinfo_field_id}</th> <th name="id" >${I18n.jobinfo_field_id}</th>
<th name="jobGroup" >${I18n.jobinfo_field_jobgroup}</th> <th name="jobGroup" >${I18n.jobinfo_field_jobgroup}</th>
<th name="jobDesc" >${I18n.jobinfo_field_jobdesc}</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="glueType" >${I18n.jobinfo_field_gluetype}</th>
<th name="executorParam" >${I18n.jobinfo_field_executorparam}</th> <th name="executorParam" >${I18n.jobinfo_field_executorparam}</th>
<th name="jobCron" >Cron</th>
<th name="addTime" >addTime</th> <th name="addTime" >addTime</th>
<th name="updateTime" >updateTime</th> <th name="updateTime" >updateTime</th>
<th name="author" >${I18n.jobinfo_field_author}</th> <th name="author" >${I18n.jobinfo_field_author}</th>
@ -114,6 +114,8 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <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"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
@ -123,11 +125,74 @@
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label> <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 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>
<div class="form-group"> <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"> <div class="col-sm-4">
<select class="form-control" name="executorRouteStrategy" > <select class="form-control" name="executorRouteStrategy" >
<#list ExecutorRouteStrategyEnum as item> <#list ExecutorRouteStrategyEnum as item>
@ -135,23 +200,22 @@
</#list> </#list>
</select> </select>
</div> </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>
<div class="form-group"> <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"> <div class="col-sm-4">
<select class="form-control glueType" name="glueType" > <select class="form-control" name="misfireStrategy" >
<#list GlueTypeEnum as item> <#list MisfireStrategyEnum as item>
<option value="${item}" >${item.desc}</option> <option value="${item}" <#if 'DO_NOTHING' == item >selected</#if> >${item.title}</option>
</#list> </#list>
</select> </select>
</div> </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> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorBlockStrategy}<font color="black">*</font></label>
</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"> <div class="col-sm-4">
<select class="form-control" name="executorBlockStrategy" > <select class="form-control" name="executorBlockStrategy" >
<#list ExecutorBlockStrategyEnum as item> <#list ExecutorBlockStrategyEnum as item>
@ -159,26 +223,13 @@
</#list> </#list>
</select> </select>
</div> </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>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="black">*</font></label> <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> <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 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>
<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> </div>
<hr> <hr>
@ -194,16 +245,14 @@
<textarea class="glueSource_java" style="display:none;" > <textarea class="glueSource_java" style="display:none;" >
package com.xxl.job.service.handler; package com.xxl.job.service.handler;
import com.xxl.job.core.log.XxlJobLogger; import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.IJobHandler;
public class DemoGlueJobHandler extends IJobHandler { public class DemoGlueJobHandler extends IJobHandler {
@Override @Override
public ReturnT<String> execute(String param) throws Exception { public void execute() throws Exception {
XxlJobLogger.log("XXL-JOB, Hello World."); XxlJobHelper.log("XXL-JOB, Hello World.");
return ReturnT.SUCCESS;
} }
} }
@ -310,71 +359,122 @@ exit 0
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <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> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobgroup}<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="jobGroup" > <select class="form-control" name="jobGroup" >
<#list JobGroupList as group> <#list JobGroupList as group>
<option value="${group.id}" >${group.title}</option> <option value="${group.id}" >${group.title}</option>
</#list> </#list>
</select> </select>
</div> </div>
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_jobdesc}<font color="red">*</font></label> <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 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>
<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"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_author}<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> <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> <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 class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</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"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label> <label for="firstname" class="col-sm-2 control-label">${I18n.jobinfo_field_executorparam}<font color="black">*</font></label>
<div class="col-sm-10"> <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> <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> </div>
<hr> <hr>

View File

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

View File

@ -74,7 +74,7 @@
</div> </div>
<div class="col-xs-1"> <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>
</div> </div>
@ -123,7 +123,7 @@
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
<div class="form-group"> <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"> <div class="col-sm-9">
<input type="text" class="form-control jobGroupText" readonly > <input type="text" class="form-control jobGroupText" readonly >
<input type="hidden" name="jobGroup" > <input type="hidden" name="jobGroup" >
@ -131,7 +131,7 @@
</div> </div>
<div class="form-group"> <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"> <div class="col-sm-9">
<input type="text" class="form-control jobIdText" readonly > <input type="text" class="form-control jobIdText" readonly >
<input type="hidden" name="jobId" > <input type="hidden" name="jobId" >
@ -139,7 +139,7 @@
</div> </div>
<div class="form-group"> <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"> <div class="col-sm-9">
<select class="form-control" name="type" > <select class="form-control" name="type" >
<option value="1" >${I18n.joblog_clean_type_1}</option> <option value="1" >${I18n.joblog_clean_type_1}</option>

View File

@ -38,7 +38,7 @@
<alibaba.nacos.version>2.0.4</alibaba.nacos.version> <alibaba.nacos.version>2.0.4</alibaba.nacos.version>
<seata.version>1.5.2</seata.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> <fastjson.version>1.2.83</fastjson.version>
<aviator.version>5.2.6</aviator.version> <aviator.version>5.2.6</aviator.version>
<pegdown.version>1.6.0</pegdown.version> <pegdown.version>1.6.0</pegdown.version>