✨ 添加新特性。 支持quartz 定时任务

This commit is contained in:
冷冷 committed 2019-03-14 17:47:02 +08:00
1 parent 7083019d6b
commit f74e338e07
70 files changed
+2919 -22

No files matched your search

+4 -1
View File
@@ -5,4 +5,7 @@ create database `pigxx` default character set utf8mb4 collate utf8mb4_general_ci
create database `pigxx_ac` default character set utf8mb4 collate utf8mb4_general_ci;
-- pigx zipkin相关库
create database `pigxx_zipkin` default character set utf8mb4 collate utf8mb4_general_ci;
create database `pigxx_zipkin` default character set utf8mb4 collate utf8mb4_general_ci;
-- pigx 任务相关库
create database `pigxx_job` default character set utf8mb4 collate utf8mb4_general_ci;
+313
View File
@@ -0,0 +1,313 @@
/*
Navicat MySQL Data Transfer
Source Server : 233
Source Server Version : 50725
Source Host : 47.92.69.233:3306
Source Database : frwcloud
Target Server Type : MYSQL
Target Server Version : 50725
File Encoding : 65001
Date: 2019-03-14 12:42:21
*/
USE pigxx_job;
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_blob_triggers`;
CREATE TABLE `qrtz_blob_triggers` (
`sched_name` varchar(120) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`blob_data` blob,
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_blob_triggers
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_calendars
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_calendars`;
CREATE TABLE `qrtz_calendars` (
`sched_name` varchar(120) NOT NULL,
`calendar_name` varchar(200) NOT NULL,
`calendar` blob NOT NULL,
PRIMARY KEY (`sched_name`,`calendar_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_calendars
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_cron_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_cron_triggers`;
CREATE TABLE `qrtz_cron_triggers` (
`sched_name` varchar(120) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`cron_expression` varchar(200) NOT NULL,
`time_zone_id` varchar(80) DEFAULT NULL,
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_cron_triggers
-- ----------------------------
INSERT INTO `qrtz_cron_triggers` VALUES ('clusteredScheduler', 'demo', 'demo', '0 0/30 * * * ?', 'Asia/Shanghai');
INSERT INTO `qrtz_cron_triggers` VALUES ('clusteredScheduler', 'demo1', 'demo', '0 0/5 * * * ?', 'Asia/Shanghai');
INSERT INTO `qrtz_cron_triggers` VALUES ('clusteredScheduler', 'demo3', 'demo', '0 0/20 * * * ?', 'Asia/Shanghai');
-- ----------------------------
-- Table structure for qrtz_fired_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_fired_triggers`;
CREATE TABLE `qrtz_fired_triggers` (
`sched_name` varchar(120) NOT NULL,
`entry_id` varchar(95) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`instance_name` varchar(200) NOT NULL,
`fired_time` bigint(13) NOT NULL,
`sched_time` bigint(13) NOT NULL,
`priority` int(11) NOT NULL,
`state` varchar(16) NOT NULL,
`job_name` varchar(200) DEFAULT NULL,
`job_group` varchar(200) DEFAULT NULL,
`is_nonconcurrent` varchar(1) DEFAULT NULL,
`requests_recovery` varchar(1) DEFAULT NULL,
PRIMARY KEY (`sched_name`,`entry_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_fired_triggers
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_job_details
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_job_details`;
CREATE TABLE `qrtz_job_details` (
`sched_name` varchar(120) NOT NULL,
`job_name` varchar(200) NOT NULL,
`job_group` varchar(200) NOT NULL,
`description` varchar(250) DEFAULT NULL,
`job_class_name` varchar(250) NOT NULL,
`is_durable` varchar(1) NOT NULL,
`is_nonconcurrent` varchar(1) NOT NULL,
`is_update_data` varchar(1) NOT NULL,
`requests_recovery` varchar(1) NOT NULL,
`job_data` blob,
PRIMARY KEY (`sched_name`,`job_name`,`job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_job_details
-- ----------------------------
INSERT INTO `qrtz_job_details` VALUES ('clusteredScheduler', 'demo', 'demo', null, 'com.company.platform.frwcloud.job.config.FrwcloudQuartzFactory', '0', '1', '0', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000B7363686564756C654A6F627372002F636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E656E746974792E5379734A6F6200000000000000010200174C0009636C6173734E616D657400124C6A6176612F6C616E672F537472696E673B4C0008637265617465427971007E00094C000A63726561746554696D657400194C6A6176612F74696D652F4C6F63616C4461746554696D653B4C000E63726F6E45787072657373696F6E71007E00094C000B657865637574655061746871007E00094C00106A6F624578656375746553746174757371007E00094C00086A6F6247726F757071007E00094C00056A6F6249647400134C6A6176612F6C616E672F496E74656765723B4C00076A6F624E616D6571007E00094C00086A6F624F7264657271007E00094C00096A6F6253746174757371007E00094C000D6A6F6254656E616E745479706571007E00094C00076A6F625479706571007E00094C000A6D6574686F644E616D6571007E00094C00116D6574686F64506172616D7356616C756571007E00094C000D6D697366697265506F6C69637971007E00094C00086E65787474696D6571007E000A4C000C70726576696F757374696D6571007E000A4C000672656D61726B71007E00094C0009737461727474696D6571007E000A4C000874656E616E74496471007E000B4C0008757064617465427971007E00094C000A75706461746554696D6571007E000A78720035636F6D2E62616F6D69646F752E6D796261746973706C75732E657874656E73696F6E2E6163746976657265636F72642E4D6F64656C0000000000000001020000787074000464656D6F707372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770A05000007E3011B0E3BDB7874000D3020302F31202A202A202A203F707400013074000464656D6F737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000174000464656D6F7400013174000132740001317400013274000A64656D6F4D6574686F647400077A68656E676A6E740001337371007E000F770905000007E3030E08F5787371007E000F770905000007E3030E08F6787400007371007E000F770A05000007E302021225FC7871007E001674000561646D696E7371007E000F770A05000007E3011B0E3BDB787800);
INSERT INTO `qrtz_job_details` VALUES ('clusteredScheduler', 'demo1', 'demo', null, 'com.company.platform.frwcloud.job.config.FrwcloudQuartzFactory', '0', '1', '0', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000B7363686564756C654A6F627372002F636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E656E746974792E5379734A6F6200000000000000010200174C0009636C6173734E616D657400124C6A6176612F6C616E672F537472696E673B4C0008637265617465427971007E00094C000A63726561746554696D657400194C6A6176612F74696D652F4C6F63616C4461746554696D653B4C000E63726F6E45787072657373696F6E71007E00094C000B657865637574655061746871007E00094C00106A6F624578656375746553746174757371007E00094C00086A6F6247726F757071007E00094C00056A6F6249647400134C6A6176612F6C616E672F496E74656765723B4C00076A6F624E616D6571007E00094C00086A6F624F7264657271007E00094C00096A6F6253746174757371007E00094C000D6A6F6254656E616E745479706571007E00094C00076A6F625479706571007E00094C000A6D6574686F644E616D6571007E00094C00116D6574686F64506172616D7356616C756571007E00094C000D6D697366697265506F6C69637971007E00094C00086E65787474696D6571007E000A4C000C70726576696F757374696D6571007E000A4C000672656D61726B71007E00094C0009737461727474696D6571007E000A4C000874656E616E74496471007E000B4C0008757064617465427971007E00094C000A75706461746554696D6571007E000A78720035636F6D2E62616F6D69646F752E6D796261746973706C75732E657874656E73696F6E2E6163746976657265636F72642E4D6F64656C0000000000000001020000787074002C636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E7461736B2E44656D6F31707372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770A05000007E3011B132AC87874000D3020302F35202A202A202A203F707400013074000464656D6F737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000274000564656D6F317400013274000132740001317400013174000A64656D6F4D6574686F647400046A69616E740001337371007E000F770905000007E3030C0AE1787371007E000F770905000007E3030C0AE6787400007371007E000F770A05000007E302021225FC7871007E001674000561646D696E7371007E000F770A05000007E3011B132AC8787800);
INSERT INTO `qrtz_job_details` VALUES ('clusteredScheduler', 'demo3', 'demo', null, 'com.company.platform.frwcloud.job.config.FrwcloudQuartzFactory', '0', '1', '0', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000B7363686564756C654A6F627372002F636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E656E746974792E5379734A6F6200000000000000010200174C0009636C6173734E616D657400124C6A6176612F6C616E672F537472696E673B4C0008637265617465427971007E00094C000A63726561746554696D657400194C6A6176612F74696D652F4C6F63616C4461746554696D653B4C000E63726F6E45787072657373696F6E71007E00094C000B657865637574655061746871007E00094C00106A6F624578656375746553746174757371007E00094C00086A6F6247726F757071007E00094C00056A6F6249647400134C6A6176612F6C616E672F496E74656765723B4C00076A6F624E616D6571007E00094C00086A6F624F7264657271007E00094C00096A6F6253746174757371007E00094C000D6A6F6254656E616E745479706571007E00094C00076A6F625479706571007E00094C000A6D6574686F644E616D6571007E00094C00116D6574686F64506172616D7356616C756571007E00094C000D6D697366697265506F6C69637971007E00094C00086E65787474696D6571007E000A4C000C70726576696F757374696D6571007E000A4C000672656D61726B71007E00094C0009737461727474696D6571007E000A4C000874656E616E74496471007E000B4C0008757064617465427971007E00094C000A75706461746554696D6571007E000A78720035636F6D2E62616F6D69646F752E6D796261746973706C75732E657874656E73696F6E2E6163746976657265636F72642E4D6F64656C0000000000000001020000787070707372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770A05000007E3011C0B02FE7874000D3020302F31202A202A202A203F740026687474703A2F2F465257434C4F55442D474154455741592F6A6F622F696E6E65726A6F622F317400013074000464656D6F737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000374000564656D6F33740001337400013274000131740001337070740001337371007E000E770905000007E3030E08F5787371007E000E770905000007E3030E08F67874000A72657374E8B083E794A87371007E000E770905000007E3021013F5787371007E00140000000174000561646D696E7371007E000E770A05000007E3011C0B02FE787800);
-- ----------------------------
-- Table structure for qrtz_locks
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_locks`;
CREATE TABLE `qrtz_locks` (
`sched_name` varchar(120) NOT NULL,
`lock_name` varchar(40) NOT NULL,
PRIMARY KEY (`sched_name`,`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_locks
-- ----------------------------
INSERT INTO `qrtz_locks` VALUES ('clusteredScheduler', 'STATE_ACCESS');
INSERT INTO `qrtz_locks` VALUES ('clusteredScheduler', 'TRIGGER_ACCESS');
-- ----------------------------
-- Table structure for qrtz_paused_trigger_grps
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
CREATE TABLE `qrtz_paused_trigger_grps` (
`sched_name` varchar(120) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
PRIMARY KEY (`sched_name`,`trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_paused_trigger_grps
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_scheduler_state
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_scheduler_state`;
CREATE TABLE `qrtz_scheduler_state` (
`sched_name` varchar(120) NOT NULL,
`instance_name` varchar(200) NOT NULL,
`last_checkin_time` bigint(13) NOT NULL,
`checkin_interval` bigint(13) NOT NULL,
PRIMARY KEY (`sched_name`,`instance_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_scheduler_state
-- ----------------------------
INSERT INTO `qrtz_scheduler_state` VALUES ('clusteredScheduler', 'iZ8vb0pfoq9og1yav6fslxZ1552524268412', '1552538541845', '10000');
-- ----------------------------
-- Table structure for qrtz_simple_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simple_triggers`;
CREATE TABLE `qrtz_simple_triggers` (
`sched_name` varchar(120) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`repeat_count` bigint(7) NOT NULL,
`repeat_interval` bigint(12) NOT NULL,
`times_triggered` bigint(10) NOT NULL,
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_simple_triggers
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_simprop_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
CREATE TABLE `qrtz_simprop_triggers` (
`sched_name` varchar(120) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`str_prop_1` varchar(512) DEFAULT NULL,
`str_prop_2` varchar(512) DEFAULT NULL,
`str_prop_3` varchar(512) DEFAULT NULL,
`int_prop_1` int(11) DEFAULT NULL,
`int_prop_2` int(11) DEFAULT NULL,
`long_prop_1` bigint(20) DEFAULT NULL,
`long_prop_2` bigint(20) DEFAULT NULL,
`dec_prop_1` decimal(13,4) DEFAULT NULL,
`dec_prop_2` decimal(13,4) DEFAULT NULL,
`bool_prop_1` varchar(1) DEFAULT NULL,
`bool_prop_2` varchar(1) DEFAULT NULL,
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_simprop_triggers
-- ----------------------------
-- ----------------------------
-- Table structure for qrtz_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_triggers`;
CREATE TABLE `qrtz_triggers` (
`sched_name` varchar(120) NOT NULL,
`trigger_name` varchar(200) NOT NULL,
`trigger_group` varchar(200) NOT NULL,
`job_name` varchar(200) NOT NULL,
`job_group` varchar(200) NOT NULL,
`description` varchar(250) DEFAULT NULL,
`next_fire_time` bigint(13) DEFAULT NULL,
`prev_fire_time` bigint(13) DEFAULT NULL,
`priority` int(11) DEFAULT NULL,
`trigger_state` varchar(16) NOT NULL,
`trigger_type` varchar(8) NOT NULL,
`start_time` bigint(13) NOT NULL,
`end_time` bigint(13) DEFAULT NULL,
`calendar_name` varchar(200) DEFAULT NULL,
`misfire_instr` smallint(2) DEFAULT NULL,
`job_data` blob,
PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
KEY `sched_name` (`sched_name`,`job_name`,`job_group`),
CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `qrtz_job_details` (`sched_name`, `job_name`, `job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of qrtz_triggers
-- ----------------------------
INSERT INTO `qrtz_triggers` VALUES ('clusteredScheduler', 'demo', 'demo', 'demo', 'demo', null, '1552539600000', '1552537800000', '5', 'WAITING', 'CRON', '1552523640000', '0', null, '2', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000B7363686564756C654A6F627372002F636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E656E746974792E5379734A6F6200000000000000010200174C0009636C6173734E616D657400124C6A6176612F6C616E672F537472696E673B4C0008637265617465427971007E00094C000A63726561746554696D657400194C6A6176612F74696D652F4C6F63616C4461746554696D653B4C000E63726F6E45787072657373696F6E71007E00094C000B657865637574655061746871007E00094C00106A6F624578656375746553746174757371007E00094C00086A6F6247726F757071007E00094C00056A6F6249647400134C6A6176612F6C616E672F496E74656765723B4C00076A6F624E616D6571007E00094C00086A6F624F7264657271007E00094C00096A6F6253746174757371007E00094C000D6A6F6254656E616E745479706571007E00094C00076A6F625479706571007E00094C000A6D6574686F644E616D6571007E00094C00116D6574686F64506172616D7356616C756571007E00094C000D6D697366697265506F6C69637971007E00094C00086E65787474696D6571007E000A4C000C70726576696F757374696D6571007E000A4C000672656D61726B71007E00094C0009737461727474696D6571007E000A4C000874656E616E74496471007E000B4C0008757064617465427971007E00094C000A75706461746554696D6571007E000A78720035636F6D2E62616F6D69646F752E6D796261746973706C75732E657874656E73696F6E2E6163746976657265636F72642E4D6F64656C0000000000000001020000787074000464656D6F707372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770A05000007E3011B0E3BDB7874000E3020302F3330202A202A202A203F707400013074000464656D6F737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000174000464656D6F7400013174000133740001317400013274000A64656D6F4D6574686F647400077A68656E676A6E740001337371007E000F770905000007E3030E08D3787371007E000F770905000007E3030E08D4787400007371007E000F770905000007E3030E08DD7871007E001674000561646D696E7371007E000F770A05000007E3011B0E3BDB787800);
INSERT INTO `qrtz_triggers` VALUES ('clusteredScheduler', 'demo1', 'demo', 'demo1', 'demo', null, '1552538700000', '1552538400000', '5', 'WAITING', 'CRON', '1552523640000', '0', null, '2', '');
INSERT INTO `qrtz_triggers` VALUES ('clusteredScheduler', 'demo3', 'demo', 'demo3', 'demo', null, '1552539600000', '1552538400000', '5', 'WAITING', 'CRON', '1552523641000', '0', null, '2', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000B7363686564756C654A6F627372002F636F6D2E636F6D70616E792E706C6174666F726D2E667277636C6F75642E6A6F622E656E746974792E5379734A6F6200000000000000010200174C0009636C6173734E616D657400124C6A6176612F6C616E672F537472696E673B4C0008637265617465427971007E00094C000A63726561746554696D657400194C6A6176612F74696D652F4C6F63616C4461746554696D653B4C000E63726F6E45787072657373696F6E71007E00094C000B657865637574655061746871007E00094C00106A6F624578656375746553746174757371007E00094C00086A6F6247726F757071007E00094C00056A6F6249647400134C6A6176612F6C616E672F496E74656765723B4C00076A6F624E616D6571007E00094C00086A6F624F7264657271007E00094C00096A6F6253746174757371007E00094C000D6A6F6254656E616E745479706571007E00094C00076A6F625479706571007E00094C000A6D6574686F644E616D6571007E00094C00116D6574686F64506172616D7356616C756571007E00094C000D6D697366697265506F6C69637971007E00094C00086E65787474696D6571007E000A4C000C70726576696F757374696D6571007E000A4C000672656D61726B71007E00094C0009737461727474696D6571007E000A4C000874656E616E74496471007E000B4C0008757064617465427971007E00094C000A75706461746554696D6571007E000A78720035636F6D2E62616F6D69646F752E6D796261746973706C75732E657874656E73696F6E2E6163746976657265636F72642E4D6F64656C0000000000000001020000787070707372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770A05000007E3011C0B02FE7874000E3020302F3230202A202A202A203F740026687474703A2F2F465257434C4F55442D474154455741592F6A6F622F696E6E65726A6F622F317400013074000464656D6F737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700000000374000564656D6F33740001337400013374000131740001337070740001337371007E000E770905000007E3030E08D3787371007E000E770905000007E3030E08D47874000A72657374E8B083E794A87371007E000E770A05000007E3030E0822FE787371007E00140000000174000561646D696E7371007E000E770A05000007E3011C0B02FE787800);
-- ----------------------------
-- Table structure for sys_job
-- ----------------------------
DROP TABLE IF EXISTS `sys_job`;
CREATE TABLE `sys_job` (
`job_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务id',
`job_name` varchar(64) NOT NULL COMMENT '任务名称',
`job_group` varchar(64) NOT NULL COMMENT '任务组名',
`job_order` char(1) DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
`job_type` char(1) NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
`execute_path` varchar(500) DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持rest get协议,需要增加String返回值,0成功,1失败;job_type=4时,jar路径;其它值为空',
`class_name` varchar(500) DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
`method_name` varchar(500) DEFAULT NULL COMMENT '任务方法',
`method_params_value` varchar(2000) DEFAULT NULL COMMENT '参数值',
`cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron执行表达式',
`misfire_policy` varchar(20) DEFAULT '3' COMMENT '错失执行策略(1错失周期立即执行 2错失周期执行一次 3下周期执行)',
`job_tenant_type` char(1) DEFAULT '1' COMMENT '1、多租户任务;2、非多租户任务',
`job_status` char(1) DEFAULT '0' COMMENT '状态(1、未发布;2、运行中;3、暂停;4、删除;)',
`job_execute_status` char(1) DEFAULT '0' COMMENT '状态(0正常 1异常)',
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`startTime` timestamp NULL DEFAULT NULL COMMENT '初次执行时间',
`previousTime` timestamp NULL DEFAULT NULL COMMENT '上次执行时间',
`nextTime` timestamp NULL DEFAULT NULL COMMENT '下次执行时间',
`tenant_id` int(11) DEFAULT '1' COMMENT '租户',
`remark` varchar(500) DEFAULT '' COMMENT '备注信息',
PRIMARY KEY (`job_id`,`job_name`,`job_group`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COMMENT='定时任务调度表';
-- ----------------------------
-- Records of sys_job
-- ----------------------------
INSERT INTO `sys_job` VALUES ('1', 'demo', 'demo', '1', '2', null, 'demo', 'demoMethod', 'zhengjn', '0 0/30 * * * ?', '3', '1', '2', '0', null, '2019-01-27 14:59:36', 'admin', '2019-01-27 14:59:36', '2019-03-14 08:34:00', '2019-03-14 12:30:00', '2019-03-14 13:00:00', '1', '');
INSERT INTO `sys_job` VALUES ('2', 'demo1', 'demo', '2', '1', null, 'com.company.platform.frwcloud.job.task.Demo1', 'demoMethod', 'jian', '0 0/5 * * * ?', '3', '1', '2', '0', null, '2019-01-27 19:42:55', 'admin', '2019-01-27 19:42:55', '2019-03-14 08:34:00', '2019-03-14 12:40:00', '2019-03-14 12:45:00', '2', '');
INSERT INTO `sys_job` VALUES ('3', 'demo3', 'demo', '3', '3', 'http://FRWCLOUD-GATEWAY/job/innerjob/1', null, null, null, '0 0/20 * * * ?', '3', '1', '2', '0', null, '2019-01-28 11:02:01', 'admin', '2019-01-28 11:02:01', '2019-03-14 08:34:01', '2019-03-14 12:40:00', '2019-03-14 13:00:00', '1', 'rest调用');
-- ----------------------------
-- Table structure for sys_job_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_job_log`;
CREATE TABLE `sys_job_log` (
`job_log_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务日志ID',
`job_id` int(11) NOT NULL COMMENT '任务id',
`job_name` varchar(64) DEFAULT NULL COMMENT '任务名称',
`job_group` varchar(64) DEFAULT NULL COMMENT '任务组名',
`job_order` char(1) DEFAULT NULL COMMENT '组内执行顺利,值越大执行优先级越高,最大值9,最小值1',
`job_type` char(1) NOT NULL DEFAULT '1' COMMENT '1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他',
`execute_path` varchar(500) DEFAULT NULL COMMENT 'job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空',
`class_name` varchar(500) DEFAULT NULL COMMENT 'job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空',
`method_name` varchar(500) DEFAULT NULL COMMENT '任务方法',
`method_params_value` varchar(2000) DEFAULT NULL COMMENT '参数值',
`cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron执行表达式',
`job_message` varchar(500) DEFAULT NULL COMMENT '日志信息',
`job_log_status` char(1) DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
`execute_time` varchar(30) DEFAULT NULL COMMENT '执行时间',
`exception_info` varchar(2000) DEFAULT '' COMMENT '异常信息',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`tenant_id` int(11) NOT NULL DEFAULT '1' COMMENT '租户id',
PRIMARY KEY (`job_log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=201028 DEFAULT CHARSET=utf8 COMMENT='定时任务执行日志表';
-- ----------------------------
-- Records of sys_job_log
-- ----------------------------
+3 -1
View File
@@ -10,4 +10,6 @@ COPY ./db/2pigxx.sql /docker-entrypoint-initdb.d
COPY ./db/3pigxx_ac.sql /docker-entrypoint-initdb.d
COPY ./db/4pigxx_zipkin.sql /docker-entrypoint-initdb.d
COPY ./db/4pigxx_zipkin.sql /docker-entrypoint-initdb.d
COPY ./db/5pigxx_job.sql /docker-entrypoint-initdb.d
@@ -79,8 +79,10 @@ mybatis-plus:
configuration:
map-underscore-to-camel-case: true
#swagger公共信息
swagger:
host: pigx-gateway:9999
title: PigX Swagger API
description: 全宇宙最牛逼的Spring Cloud微服务开发脚手架
version: @project.version@
@@ -13,7 +13,7 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://pigx-mysql:3306/pigxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
url: jdbc:mysql://pigx-mysql:3306/pigxx_job?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
elasticjob:
# 分布式任务协调依赖zookeeper
zookeeper:
@@ -0,0 +1,50 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
scope: server
# 默认放行url,子模块重写时application-dev.yml中的公共配置会被覆盖,所以要把公共配置中的放行url再写一次
ignore-urls:
- /actuator/**
- /v2/api-docs
- /innerjob/**
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://pigx-mysql:3306/pigxx_job?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
resources:
static-locations: classpath:/static/,classpath:/views/
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
#初始化表结构
#jdbc:
#initialize-schema: never
@@ -39,7 +39,7 @@ import java.util.stream.Collectors;
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
private static final String API_URI = "/v2/api-docs";
public static final String API_URI = "/v2/api-docs";
private final RouteDefinitionRepository routeDefinitionRepository;
private final FilterIgnorePropertiesConfig filterIgnorePropertiesConfig;
@@ -50,14 +50,14 @@ public class SwaggerProvider implements SwaggerResourcesProvider {
List<RouteDefinition> routes = new ArrayList<>();
routeDefinitionRepository.getRouteDefinitions().subscribe(route -> routes.add(route));
routes.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
.filter(predicateDefinition -> !filterIgnorePropertiesConfig.getSwaggerProviders().contains(routeDefinition.getId()))
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))));
.filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
.filter(predicateDefinition -> !filterIgnorePropertiesConfig.getSwaggerProviders().contains(routeDefinition.getId()))
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))));
return resources.stream().sorted(Comparator.comparing(SwaggerResource::getName))
.collect(Collectors.toList());
.collect(Collectors.toList());
}
private SwaggerResource swaggerResource(String name, String location) {
@@ -18,6 +18,7 @@
package com.pig4cloud.pigx.gateway.filter;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.gateway.config.SwaggerProvider;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
@@ -73,9 +74,16 @@ public class PigxRequestGlobalFilter implements GlobalFilter, Ordered {
.build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
// 3. 支持swagger添加X-Forwarded-Prefix header
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
return chain.filter(exchange.mutate().request(newRequest).build());
}
String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
return chain.filter(exchange.mutate()
.request(newRequest.mutate()
.build()).build());
.request(newRequest.mutate()
.header(HEADER_NAME, basePath)
.build()).build());
}
@Override
@@ -65,7 +65,7 @@ public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try {
ImageIO.write(image, "jpeg", os);
ImageIO.write(image, MediaType.IMAGE_JPEG.getType(), os);
} catch (IOException e) {
log.error("ImageIO write err", e);
return Mono.error(e);
@@ -0,0 +1,15 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER wangiegie@gmail.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /pigx-daemon-elastic
WORKDIR /pigx-daemon-elastic
EXPOSE 5002
ADD ./pigx-visual/pigx-daemon-elastic/target/pigx-daemon-elastic.jar ./
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-daemon-elastic.jar
@@ -26,10 +26,10 @@
<version>2.6.0</version>
</parent>
<artifactId>pigx-daemon</artifactId>
<artifactId>pigx-daemon-elastic</artifactId>
<packaging>jar</packaging>
<description>后台跑批定时任务模块</description>
<description>基于elastic-job后台跑批定时任务模块</description>
<dependencies>
<!--配置中心客户端-->
@@ -34,10 +34,10 @@ import org.springframework.cloud.client.SpringCloudApplication;
@EnablePigxFeignClients
@SpringCloudApplication
@EnablePigxResourceServer
public class PigxDaemonApplication {
public class PigxDaemonElasticApplication {
public static void main(String[] args) {
SpringApplication.run(PigxDaemonApplication.class, args);
SpringApplication.run(PigxDaemonElasticApplication.class, args);
}
}
@@ -4,12 +4,12 @@ MAINTAINER wangiegie@gmail.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /pigx-daemon
RUN mkdir -p /pigx-daemon-quartz
WORKDIR /pigx-daemon
WORKDIR /pigx-daemon-quartz
EXPOSE 5002
ADD ./pigx-visual/pigx-daemon/target/pigx-daemon.jar ./
ADD ./pigx-daemon-quartz/target/pigx-daemon-quartz.jar ./
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-daemon.jar
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-daemon-quartz.jar
+91
View File
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>pigx</artifactId>
<groupId>com.pig4cloud</groupId>
<version>2.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>pigx-daemon-quartz</artifactId>
<packaging>jar</packaging>
<description>基于quartz后台跑批定时任务模块</description>
<dependencies>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--日志处理-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-log</artifactId>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-data</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-swagger</artifactId>
</dependency>
<!--spring security 、oauth、jwt依赖-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-security</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- quartz 模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.company.platform.frwcloud.job.FrwcloudJobApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,23 @@
package com.pig4cloud.pigx.daemon;
import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients;
import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer;
import com.pig4cloud.pigx.common.swagger.annotation.EnablePigxSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
/**
* @author frwcloud
* @date 2019/01/23
* 定时任务模块
*/
@EnablePigxSwagger2
@SpringCloudApplication
@EnablePigxFeignClients
@EnablePigxResourceServer
public class PigxDaemonQuartzApplication {
public static void main(String[] args) {
SpringApplication.run(PigxDaemonQuartzApplication.class, args);
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.util.Assert;
/**
* @author 郑健楠
*/
class AutowireCapableBeanJobFactory extends SpringBeanJobFactory {
private final AutowireCapableBeanFactory beanFactory;
AutowireCapableBeanJobFactory(AutowireCapableBeanFactory beanFactory) {
Assert.notNull(beanFactory, "Bean factory must not be null");
this.beanFactory = beanFactory;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
this.beanFactory.autowireBean(jobInstance);
this.beanFactory.initializeBean(jobInstance, (String) null);
return jobInstance;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import com.pig4cloud.pigx.daemon.service.SysJobService;
import com.pig4cloud.pigx.daemon.util.TaskUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 郑健楠
* <p>
* 初始化加载定时任务
*/
@Slf4j
@Configuration
@AllArgsConstructor
public class PigxInitQuartzJob {
private final SysJobService sysJobService;
private final TaskUtil taskUtil;
private final Scheduler scheduler;
@Bean
public void customize() {
sysJobService.list().forEach(sysjob -> {
if (PigxQuartzEnum.JOBSTATUSRELEASE.getType().equals(sysjob.getJobStatus())) {
taskUtil.removeJob(sysjob, scheduler);
} else if (PigxQuartzEnum.JOBSTATUSRUNNING.getType().equals(sysjob.getJobStatus())) {
taskUtil.resumeJob(sysjob, scheduler);
} else if (PigxQuartzEnum.JOBSTATUSNOTRUNNING.getType().equals(sysjob.getJobStatus())) {
taskUtil.pauseJob(sysjob, scheduler);
} else {
taskUtil.removeJob(sysjob, scheduler);
}
});
}
}
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import org.quartz.Calendar;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author 郑健楠
*/
@Configuration
@ConditionalOnClass({Scheduler.class, SchedulerFactoryBean.class})
@EnableConfigurationProperties({QuartzProperties.class})
public class PigxQuartzConfig {
private final QuartzProperties properties;
private final List<SchedulerFactoryBeanCustomizer> customizers;
private final JobDetail[] jobDetails;
private final Map<String, Calendar> calendars;
private final Trigger[] triggers;
private final ApplicationContext applicationContext;
public PigxQuartzConfig(QuartzProperties properties,
ObjectProvider<List<SchedulerFactoryBeanCustomizer>> customizers,
ObjectProvider<JobDetail[]> jobDetails, ObjectProvider<Map<String, Calendar>> calendars
, ObjectProvider<Trigger[]> triggers, ApplicationContext applicationContext) {
this.properties = properties;
this.customizers = customizers.getIfAvailable();
this.jobDetails = jobDetails.getIfAvailable();
this.calendars = calendars.getIfAvailable();
this.triggers = triggers.getIfAvailable();
this.applicationContext = applicationContext;
}
@Bean
@ConditionalOnMissingBean
public SchedulerFactoryBean quartzScheduler() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(
this.applicationContext.getAutowireCapableBeanFactory()));
if (!this.properties.getProperties().isEmpty()) {
schedulerFactoryBean.setQuartzProperties(this.asProperties(this.properties.getProperties()));
}
if (this.jobDetails != null && this.jobDetails.length > 0) {
schedulerFactoryBean.setJobDetails(this.jobDetails);
}
if (this.calendars != null && !this.calendars.isEmpty()) {
schedulerFactoryBean.setCalendars(this.calendars);
}
if (this.triggers != null && this.triggers.length > 0) {
schedulerFactoryBean.setTriggers(this.triggers);
}
this.customize(schedulerFactoryBean);
return schedulerFactoryBean;
}
private Properties asProperties(Map<String, String> source) {
Properties properties = new Properties();
properties.putAll(source);
return properties;
}
private void customize(SchedulerFactoryBean schedulerFactoryBean) {
if (this.customizers != null) {
Iterator var2 = this.customizers.iterator();
while (var2.hasNext()) {
SchedulerFactoryBeanCustomizer customizer = (SchedulerFactoryBeanCustomizer) var2.next();
customizer.customize(schedulerFactoryBean);
}
}
}
/**
* 初始化监听器
*
* @return
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/**
* 通过SchedulerFactoryBean获取Scheduler的实例
*
* @return
*/
@Bean
public Scheduler scheduler() {
return quartzScheduler().getScheduler();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* @author 郑健楠
*/
@Configuration
public class PigxQuartzCustomizerConfig implements SchedulerFactoryBeanCustomizer {
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true);
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author 郑健楠
*
* <p>
* 动态任务工厂
*/
@Slf4j
@DisallowConcurrentExecution
public class PigxQuartzFactory implements Job {
@Autowired
private PigxQuartzInvokeFactory pigxQuartzInvokeFactory;
@Override
@SneakyThrows
public void execute(JobExecutionContext jobExecutionContext) {
SysJob sysJob = (SysJob) jobExecutionContext.getMergedJobDataMap().get(PigxQuartzEnum.SCHEDULEJOBKEY.getType());
pigxQuartzInvokeFactory.init(sysJob, jobExecutionContext.getTrigger());
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.config;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.event.SysJobEvent;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.quartz.Trigger;
import org.springframework.context.ApplicationEventPublisher;
/**
* @author 郑健楠
*/
@Aspect
@Slf4j
@AllArgsConstructor
public class PigxQuartzInvokeFactory {
private final ApplicationEventPublisher publisher;
@SneakyThrows
void init(SysJob sysJob, Trigger trigger) {
publisher.publishEvent(new SysJobEvent(sysJob, trigger));
}
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.constant.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author lengleng
* @date 2019-03-14
* <p>
* 任务类型枚举
*/
@Getter
@AllArgsConstructor
public enum JobTypeQuartzEnum {
/**
* 反射java类
*/
JAVA("1", "反射java类"),
/**
* spring bean 的方式
*/
SPRING_BEAN("2", "spring bean容器实例"),
/**
* rest 调用
*/
REST("3", "rest调用"),
/**
* jar
*/
JAR("4", "jar调用");
/**
* 类型
*/
private final String type;
/**
* 描述
*/
private final String description;
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.constant.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 郑健楠
*
* <p>
* 定时任务枚举
*/
@Getter
@AllArgsConstructor
public enum PigxQuartzEnum {
/**
* 错失执行策略默认
*/
MISFIRE_DEFAULT("0", "默认"),
/**
* 错失执行策略-立即执行错失任务
*/
MISFIRE_IGNORE_MISFIRES("1", "立即执行错失任务"),
/**
* 错失执行策略-触发一次执行周期执行
*/
MISFIRE_FIRE_AND_PROCEED("2", "触发一次执行周期执行"),
/**
* 错失执行策略-不触发执行周期执行
*/
MISFIRE_DO_NOTHING("3", "不触发周期执行"),
/**
* 任务详细信息的key
*/
SCHEDULEJOBKEY("scheduleJob", "获取任务详细信息的key"),
/**
* JOB执行状态:0执行成功
*/
JOBLOGSTATUSSUCCESS("0", "执行成功"),
/**
* JOB执行状态:1执行失败
*/
JOBLOGSTATUFAIL("1", "执行失败"),
/**
* JOB状态:1已发布
*/
JOBSTATUSRELEASE("1", "未发布"),
/**
* JOB状态:2运行中
*/
JOBSTATUSRUNNING("2", "运行中"),
/**
* JOB状态:3暂停
*/
JOBSTATUSNOTRUNNING("3", "暂停"),
/**
* JOB状态:4删除
*/
JOBSTATUSDEL("4", "删除");
/**
* 类型
*/
private final String type;
/**
* 描述
*/
private final String description;
}
@@ -0,0 +1,290 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import com.pig4cloud.pigx.daemon.service.SysJobLogService;
import com.pig4cloud.pigx.daemon.service.SysJobService;
import com.pig4cloud.pigx.daemon.util.TaskUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.quartz.Scheduler;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import static com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum.*;
/**
* @author frwcloud
* @date 2019-01-27 10:04:42
* <p>
* 定时任务管理
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sysjob")
@Api(value = "sysjob", description = "定时任务")
public class SysJobController {
private final SysJobService sysJobService;
private final SysJobLogService sysJobLogService;
private final TaskUtil taskUtil;
private final Scheduler scheduler;
/**
* 定时任务分页查询
*
* @param page 分页对象
* @param sysJob 定时任务调度表
* @return
*/
@GetMapping("/page")
@ApiOperation(value = "分页定时业务查询")
public R getSysJobPage(Page page, SysJob sysJob) {
sysJob.setTenantId(TenantContextHolder.getTenantId());
return R.builder().data(sysJobService.page(page, Wrappers.query(sysJob))).build();
}
/**
* 通过id查询定时任务
*
* @param jobId id
* @return R
*/
@GetMapping("/{jobId}")
@ApiOperation(value = "唯一标识查询定时任务")
public R getById(@PathVariable("jobId") Integer jobId) {
return R.builder().data(sysJobService.getById(jobId)).build();
}
/**
* 新增定时任务
*
* @param sysJob 定时任务调度表
* @return R
*/
@SysLog("新增定时任务")
@PostMapping
@PreAuthorize("@pms.hasPermission('job_sysjob_add')")
@ApiOperation(value = "新增定时任务")
public R save(@RequestBody SysJob sysJob) {
sysJob.setJobStatus(JOBSTATUSRELEASE.getType());
sysJob.setCreateBy(SecurityUtils.getUser().getUsername());
sysJob.setTenantId(TenantContextHolder.getTenantId());
return R.builder().data(sysJobService.save(sysJob)).build();
}
/**
* 修改定时任务
*
* @param sysJob 定时任务调度表
* @return R
*/
@SysLog("修改定时任务")
@PutMapping
@PreAuthorize("@pms.hasPermission('job_sysjob_edit')")
@ApiOperation(value = "修改定时任务")
public R updateById(@RequestBody SysJob sysJob) {
sysJob.setUpdateBy(SecurityUtils.getUser().getUsername());
SysJob querySysJob = this.sysJobService.getById(sysJob.getJobId());
if (JOBSTATUSNOTRUNNING.getType().equals(querySysJob.getJobStatus())) {
this.taskUtil.addOrUpateJob(sysJob, scheduler);
sysJobService.updateById(sysJob);
} else if (JOBSTATUSRELEASE.getType().equals(querySysJob.getJobStatus())) {
sysJobService.updateById(sysJob);
}
return R.builder().build();
}
/**
* 通过id删除定时任务
*
* @param jobId id
* @return R
*/
@SysLog("删除定时任务")
@DeleteMapping("/{jobId}")
@PreAuthorize("@pms.hasPermission('job_sysjob_del')")
@ApiOperation(value = "唯一标识查询定时任务,暂停任务才能删除")
public R removeById(@PathVariable Integer jobId) {
SysJob querySysJob = this.sysJobService.getById(jobId);
if (JOBSTATUSNOTRUNNING.getType().equals(querySysJob.getJobStatus())) {
this.taskUtil.removeJob(querySysJob, scheduler);
this.sysJobService.removeById(jobId);
} else if (JOBSTATUSRELEASE.getType().equals(querySysJob.getJobStatus())) {
this.sysJobService.removeById(jobId);
}
return R.builder().build();
}
/**
* 暂停全部定时任务
*
* @return
*/
@SysLog("暂停全部定时任务")
@PostMapping("/shutdownJobs")
@PreAuthorize("@pms.hasPermission('job_sysjob_shutdownJobs')")
@ApiOperation(value = "暂停全部定时任务")
public R shutdownJobs() {
taskUtil.pauseJobs(scheduler);
int count = this.sysJobService.count(new LambdaQueryWrapper<SysJob>()
.eq(SysJob::getJobStatus, JOBSTATUSRUNNING.getType()));
if (count <= 0) {
return R.builder().msg("无正在运行定时任务").build();
} else {
//更新定时任务状态条件,运行状态2更新为暂停状态2
this.sysJobService.update(SysJob.builder()
.jobStatus(JOBSTATUSNOTRUNNING.getType()).build(), new UpdateWrapper<SysJob>()
.lambda().eq(SysJob::getJobStatus, JOBSTATUSRUNNING.getType()));
return R.builder().msg("暂停成功").build();
}
}
/**
* 启动全部定时任务
*
* @return
*/
@SysLog("启动全部定时任务")
@PostMapping("/startJobs")
@PreAuthorize("@pms.hasPermission('job_sysjob_startJob')")
@ApiOperation(value = "启动全部定时任务")
public R startJobs() {
//更新定时任务状态条件,暂停状态3更新为运行状态2
this.sysJobService.update(SysJob.builder().jobStatus(JOBSTATUSRUNNING
.getType()).build(), new UpdateWrapper<SysJob>().lambda()
.eq(SysJob::getJobStatus, JOBSTATUSNOTRUNNING.getType()));
taskUtil.startJobs(scheduler);
return R.builder().build();
}
/**
* 刷新全部定时任务
*
* @return
*/
@SysLog("刷新全部定时任务")
@PostMapping("/refreshJobs")
@PreAuthorize("@pms.hasPermission('job_sysjob_refreshJobs')")
@ApiOperation(value = "刷新全部定时任务")
public R refreshJobs() {
sysJobService.list().forEach((sysjob) -> {
if (JOBSTATUSRELEASE.getType().equals(sysjob.getJobStatus())
|| JOBSTATUSDEL.getType().equals(sysjob.getJobStatus())) {
taskUtil.removeJob(sysjob, scheduler);
} else if (JOBSTATUSRUNNING.getType().equals(sysjob.getJobStatus())
|| JOBSTATUSNOTRUNNING.getType().equals(sysjob.getJobStatus())) {
taskUtil.addOrUpateJob(sysjob, scheduler);
} else {
taskUtil.removeJob(sysjob, scheduler);
}
});
return R.builder().build();
}
/**
* 启动定时任务
*
* @param jobId
* @return
*/
@SysLog("启动定时任务")
@GetMapping("/startJob/{jobId}")
@PreAuthorize("@pms.hasPermission('job_sysjob_startJob')")
@ApiOperation(value = "启动定时任务")
public R startJob(@PathVariable("jobId") Integer jobId) {
SysJob querySysJob = this.sysJobService.getById(jobId);
if (querySysJob != null && JOBLOGSTATUFAIL.getType()
.equals(querySysJob.getJobStatus())) {
taskUtil.addOrUpateJob(querySysJob, scheduler);
} else {
taskUtil.resumeJob(querySysJob, scheduler);
}
//更新定时任务状态条件,暂停状态3更新为运行状态2
this.sysJobService.updateById(SysJob.builder().jobId(jobId)
.jobStatus(JOBSTATUSRUNNING.getType()).build());
return R.builder().build();
}
/**
* 暂停定时任务
*
* @return
*/
@SysLog("暂停定时任务")
@GetMapping("/shutdownJob/{jobId}")
@PreAuthorize("@pms.hasPermission('job_sysjob_shutdownJob')")
@ApiOperation(value = "暂停定时任务")
public R shutdownJob(@PathVariable("jobId") Integer jobId) {
SysJob querySysJob = this.sysJobService.getById(jobId);
//更新定时任务状态条件,运行状态2更新为暂停状态3
this.sysJobService.updateById(SysJob.builder().jobId(querySysJob.getJobId())
.jobStatus(JOBSTATUSNOTRUNNING.getType()).build());
taskUtil.pauseJob(querySysJob, scheduler);
return R.builder().build();
}
/**
* 唯一标识查询定时执行日志
*
* @return
*/
@GetMapping("/getJobLog")
@ApiOperation(value = "唯一标识查询定时执行日志")
public R getJobLog(Page page, SysJobLog sysJobLog) {
return R.builder().data(sysJobLogService.page(page, Wrappers.query(sysJobLog))).build();
}
/**
* 判断cron表达式是否正确
*
* @return
*/
@PostMapping("/isValidCron")
@ApiOperation(value = "判断cron是否正确")
public R isValidCron(@RequestParam String cronExpression) {
return R.builder().data(this.taskUtil.isValidCron(cronExpression)
? CommonConstants.SUCCESS : CommonConstants.FAIL).build();
}
/**
* 检验任务名称和任务组联合是否唯一
*
* @return
*/
@PostMapping("/isValidTaskName")
@ApiOperation(value = "检验任务名称和任务组联合是否唯一")
public R isValidTaskName(@RequestParam String jobName, @RequestParam String jobGroup) {
return R.builder().data(this.sysJobService
.count(Wrappers.query(SysJob.builder().jobName(jobName).jobGroup(jobGroup).build())) > 0
? CommonConstants.FAIL : CommonConstants.SUCCESS).build();
}
}
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import com.pig4cloud.pigx.daemon.service.SysJobLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author frwcloud
* <p>
* 定时任务执行日志表
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sysjoblog")
@Api(value = "sysjoblog", description = "定时任务日志")
public class SysJobLogController {
private final SysJobLogService sysJobLogService;
/**
* 分页查询
*
* @param page 分页对象
* @param sysJobLog 定时任务执行日志表
* @return
*/
@GetMapping("/page")
@ApiOperation(value = "分页定时任务日志查询")
public R getSysJobLogPage(Page page, SysJobLog sysJobLog) {
sysJobLog.setTenantId(TenantContextHolder.getTenantId());
return R.builder().data(sysJobLogService.page(page, Wrappers.query(sysJobLog))).build();
}
}
@@ -0,0 +1,138 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 定时任务调度表
*
* @author frwcloud
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "定时任务")
public class SysJob extends Model<SysJob> {
private static final long serialVersionUID = 1L;
/**
* 任务id
*/
@TableId(value = "job_id", type = IdType.AUTO)
private Integer jobId;
/**
* 任务名称
*/
private String jobName;
/**
* 任务组名
*/
private String jobGroup;
/**
* 组内执行顺利,值越大执行优先级越高,最大值9,最小值1
*/
private String jobOrder;
/**
* 1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他
*/
private String jobType;
/**
* job_type=3时,rest调用地址,仅支持rest get协议,需要增加String返回值,0成功,1失败;job_type=4时,jar路径;其它值为空
*/
private String executePath;
/**
* job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空
*/
private String className;
/**
* 任务方法
*/
private String methodName;
/**
* 参数值
*/
private String methodParamsValue;
/**
* cron执行表达式
*/
private String cronExpression;
/**
* 错失执行策略(1错失周期立即执行 2错失周期执行一次 3下周期执行)
*/
private String misfirePolicy;
/**
* 1、多租户任务;2、非多租户任务
*/
private String jobTenantType;
/**
* 状态(0、未发布;1、已发布;2、运行中;3、暂停;4、删除;)
*/
private String jobStatus;
/**
* 状态(0正常 1异常)
*/
private String jobExecuteStatus;
/**
* 创建者
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 首次执行时间
*/
private LocalDateTime starttime;
/**
* 上次执行时间
*/
private LocalDateTime previoustime;
/**
* 下次执行时间
*/
private LocalDateTime nexttime;
/**
* 租户id
*/
private Integer tenantId;
/**
* 备注信息
*/
private String remark;
}
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 定时任务执行日志表
*
* @author frwcloud
* @date 2019-01-27 13:40:20
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "定时任务日志")
public class SysJobLog extends Model<SysJobLog> {
private static final long serialVersionUID = 1L;
/**
* 任务日志ID
*/
@TableId(value = "job_log_id", type = IdType.AUTO)
private Integer jobLogId;
/**
* 任务id
*/
private Integer jobId;
/**
* 任务名称
*/
private String jobName;
/**
* 任务组名
*/
private String jobGroup;
/**
* 组内执行顺利,值越大执行优先级越高,最大值9,最小值1
*/
private String jobOrder;
/**
* 1、java类;2、spring bean名称;3、rest调用;4、jar调用;9其他
*/
private String jobType;
/**
* job_type=3时,rest调用地址,仅支持post协议;job_type=4时,jar路径;其它值为空
*/
private String executePath;
/**
* job_type=1时,类完整路径;job_type=2时,spring bean名称;其它值为空
*/
private String className;
/**
* 任务方法
*/
private String methodName;
/**
* 参数值
*/
private String methodParamsValue;
/**
* cron执行表达式
*/
private String cronExpression;
/**
* 日志信息
*/
private String jobMessage;
/**
* 执行状态(0正常 1失败)
*/
private String jobLogStatus;
/**
* 执行时间
*/
private String executeTime;
/**
* 异常信息
*/
private String exceptionInfo;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 租户id
*/
private Integer tenantId;
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.event;
import com.pig4cloud.pigx.daemon.config.PigxQuartzInvokeFactory;
import com.pig4cloud.pigx.daemon.service.SysJobLogService;
import com.pig4cloud.pigx.daemon.util.TaskInvokUtil;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author frwcloud
* @date 2018/6/28
* <p>
* 多线程自动配置
*/
@EnableAsync
@Configuration
@AllArgsConstructor
@ConditionalOnWebApplication
public class EventAutoConfiguration {
private TaskInvokUtil taskInvokUtil;
private SysJobLogService sysJobLogService;
@Bean
public SysJobListener sysJobListener() {
return new SysJobListener(taskInvokUtil);
}
@Bean
public PigxQuartzInvokeFactory frwcloudQuartzInvokeFactory(ApplicationEventPublisher publisher) {
return new PigxQuartzInvokeFactory(publisher);
}
@Bean
public SysJobLogListener sysJobLogListener() {
return new SysJobLogListener(sysJobLogService);
}
@Bean
public TaskInvokUtil taskInvokUtil(ApplicationEventPublisher publisher) {
return new TaskInvokUtil(publisher);
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.event;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.quartz.Trigger;
/**
* @author frwcloud
* 定时任务多线程事件
*/
@Getter
@AllArgsConstructor
public class SysJobEvent {
private final SysJob sysJob;
private final Trigger trigger;
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.event;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.util.TaskInvokUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Trigger;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
/**
* @author frwcloud
* 异步监听定时任务事件
*/
@Slf4j
@AllArgsConstructor
public class SysJobListener {
private TaskInvokUtil taskInvokUtil;
@Async
@Order
@EventListener(SysJobEvent.class)
public void comSysJob(SysJobEvent event) {
SysJob sysJob = event.getSysJob();
Trigger trigger = event.getTrigger();
taskInvokUtil.invokMethod(sysJob, trigger);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.event;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author frwcloud
* 定时任务日志多线程事件
*/
@Getter
@AllArgsConstructor
public class SysJobLogEvent {
private final SysJobLog sysJobLog;
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.event;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import com.pig4cloud.pigx.daemon.service.SysJobLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
/**
* @author frwcloud
* 异步监听定时任务日志事件
*/
@Slf4j
@AllArgsConstructor
public class SysJobLogListener {
private SysJobLogService sysJobLogService;
@Async
@Order
@EventListener(SysJobLogEvent.class)
public void saveSysJobLog(SysJobLogEvent event) {
SysJobLog sysJobLog = (SysJobLog) event.getSysJobLog();
sysJobLogService.save(sysJobLog);
log.info("执行定时任务日志");
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.exception;
/**
* 定时任务异常
*
* @author 郑健楠
*/
public class TaskException extends Exception {
public TaskException() {
super();
}
public TaskException(String msg) {
super(msg);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
/**
* 定时任务执行日志表
*
* @author frwcloud
* @date 2019-01-27 13:40:20
*/
public interface SysJobLogMapper extends BaseMapper<SysJobLog> {
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pig4cloud.pigx.daemon.entity.SysJob;
/**
* 定时任务调度表
*
* @author frwcloud
* @date 2019-01-27 10:04:42
*/
public interface SysJobMapper extends BaseMapper<SysJob> {
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
/**
* 定时任务执行日志表
*
* @author frwcloud
* @date 2019-01-27 13:40:20
*/
public interface SysJobLogService extends IService<SysJobLog> {
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.daemon.entity.SysJob;
/**
* 定时任务调度表
*
* @author frwcloud
* @date 2019-01-27 10:04:42
*/
public interface SysJobService extends IService<SysJob> {
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import com.pig4cloud.pigx.daemon.mapper.SysJobLogMapper;
import com.pig4cloud.pigx.daemon.service.SysJobLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 定时任务执行日志表
*
* @author frwcloud
* @date 2019-01-27 13:40:20
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysJobLogServiceImpl extends ServiceImpl<SysJobLogMapper, SysJobLog> implements SysJobLogService {
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.mapper.SysJobMapper;
import com.pig4cloud.pigx.daemon.service.SysJobService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 定时任务调度表
*
* @author frwcloud
* @date 2019-01-27 10:04:42
*/
@Slf4j
@Service
@AllArgsConstructor
public class SysJobServiceImpl extends ServiceImpl<SysJobMapper, SysJob> implements SysJobService {
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.task;
import cn.hutool.core.date.DateUtil;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author 郑健楠
*/
@Slf4j
@Component("demo")
public class Demo {
/**
*
*/
@SneakyThrows
public String demoMethod(String para) {
log.info("郑健楠测试于:{},输入参数L{}", DateUtil.now(), para);
return PigxQuartzEnum.JOBLOGSTATUSSUCCESS.getType();
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.task;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author 郑健楠
*/
@Slf4j
@Component("demo1")
public class Demo1 {
@SneakyThrows
public String demoMethod(String para) {
log.info("demo1测试于:{},输入参数L{}", new Date(), para);
return PigxQuartzEnum.JOBLOGSTATUSSUCCESS.getType();
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.exception.TaskException;
/**
* 定时任务反射实现接口类
*
* @author 郑健楠
*/
public interface ITaskInvok {
/**
* 执行反射方法
*
* @param sysJob 配置类
* @throws TaskException
*/
void invokMethod(SysJob sysJob) throws TaskException;
}
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.exception.TaskException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 定时任务可执行jar反射实现
*
* @author 郑健楠
*/
@Slf4j
@Component("jarTaskInvok")
public class JarTaskInvok implements ITaskInvok {
@Override
public void invokMethod(SysJob sysJob) throws TaskException {
ProcessBuilder processBuilder = new ProcessBuilder();
File jar = new File(sysJob.getExecutePath());
processBuilder.directory(jar.getParentFile());
List<String> commands = new ArrayList<>();
commands.add("java");
commands.add("-jar");
commands.add(sysJob.getExecutePath());
if (StrUtil.isNotEmpty(sysJob.getMethodParamsValue())) {
commands.add(sysJob.getMethodParamsValue());
}
processBuilder.command(commands);
try {
Process process = processBuilder.start();
} catch (IOException e) {
log.error("定时任务jar反射执行异常,执行任务:{}", sysJob.getExecutePath());
throw new TaskException("定时任务jar反射执行异常,执行任务:" + sysJob.getExecutePath());
}
}
}
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.exception.TaskException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 定时任务java class反射实现
*
* @author 郑健楠
*/
@Component("javaClassTaskInvok")
@Slf4j
public class JavaClassTaskInvok implements ITaskInvok {
@Override
public void invokMethod(SysJob sysJob) throws TaskException {
Object obj = null;
Class clazz = null;
Method method = null;
Object returnValue = null;
try {
if (StrUtil.isNotEmpty(sysJob.getMethodParamsValue())) {
clazz = Class.forName(sysJob.getClassName());
obj = clazz.newInstance();
method = clazz.getDeclaredMethod(sysJob.getMethodName(), String.class);
returnValue = method.invoke(obj, sysJob.getMethodParamsValue());
} else {
clazz = Class.forName(sysJob.getClassName());
obj = clazz.newInstance();
method = clazz.getDeclaredMethod(sysJob.getMethodName());
returnValue = method.invoke(obj);
}
if (StrUtil.isEmpty(returnValue.toString()) || PigxQuartzEnum.JOBLOGSTATUFAIL.getType().equals(returnValue.toString())) {
log.error("定时任务javaClassTaskInvok异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务javaClassTaskInvok业务执行失败,任务:" + sysJob.getClassName());
}
} catch (ClassNotFoundException e) {
log.error("定时任务java反射类没有找到,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射类没有找到,执行任务:" + sysJob.getClassName());
} catch (IllegalAccessException e) {
log.error("定时任务java反射类异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射类异常,执行任务:" + sysJob.getClassName());
} catch (InstantiationException e) {
log.error("定时任务java反射类异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射类异常,执行任务:" + sysJob.getClassName());
} catch (NoSuchMethodException e) {
log.error("定时任务java反射执行方法名异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射执行方法名异常,执行任务:" + sysJob.getClassName());
} catch (InvocationTargetException e) {
log.error("定时任务java反射执行异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射执行异常,执行任务:" + sysJob.getClassName());
}
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.exception.TaskException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* 定时任务rest反射实现
*
* @author 郑健楠
*/
@Slf4j
@Component("restTaskInvok")
@AllArgsConstructor
public class RestTaskInvok implements ITaskInvok {
private RestTemplate restTemplate;
@Override
public void invokMethod(SysJob sysJob) throws TaskException {
R r = restTemplate.getForObject(sysJob.getExecutePath(), R.class);
if (CommonConstants.FAIL == r.getCode()) {
log.error("定时任务restTaskInvok异常,执行任务:{}", sysJob.getExecutePath());
throw new TaskException("定时任务restTaskInvok业务执行失败,任务:" + sysJob.getExecutePath());
}
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.exception.TaskException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 定时任务spring bean反射实现
*
* @author 郑健楠
*/
@Component("springBeanTaskInvok")
@Slf4j
public class SpringBeanTaskInvok implements ITaskInvok {
@Override
public void invokMethod(SysJob sysJob) throws TaskException {
Object target = null;
Method method = null;
Object returnValue = null;
//通过Spring上下文去找 也有可能找不到
target = SpringContextHolder.getBean(sysJob.getClassName());
try {
if (StrUtil.isNotEmpty(sysJob.getMethodParamsValue())) {
method = target.getClass().getDeclaredMethod(sysJob.getMethodName(), String.class);
ReflectionUtils.makeAccessible(method);
returnValue = method.invoke(target, sysJob.getMethodParamsValue());
} else {
method = target.getClass().getDeclaredMethod(sysJob.getMethodName());
ReflectionUtils.makeAccessible(method);
returnValue = method.invoke(target);
}
if (StrUtil.isEmpty(returnValue.toString()) || PigxQuartzEnum.JOBLOGSTATUFAIL.getType()
.equals(returnValue.toString())) {
log.error("定时任务springBeanTaskInvok异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务springBeanTaskInvok业务执行失败,任务:" + sysJob.getClassName());
}
} catch (NoSuchMethodException e) {
log.error("定时任务spring bean反射异常方法未找到,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务spring bean反射异常方法未找到,执行任务:" + sysJob.getClassName());
} catch (IllegalAccessException e) {
log.error("定时任务spring bean反射异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务spring bean反射异常,执行任务:" + sysJob.getClassName());
} catch (InvocationTargetException e) {
log.error("定时任务spring bean反射执行异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务spring bean反射执行异常,执行任务:" + sysJob.getClassName());
}
}
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.daemon.constant.enums.JobTypeQuartzEnum;
import com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import com.pig4cloud.pigx.daemon.entity.SysJobLog;
import com.pig4cloud.pigx.daemon.event.SysJobLogEvent;
import com.pig4cloud.pigx.daemon.exception.TaskException;
import com.pig4cloud.pigx.daemon.service.SysJobService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import java.time.ZoneId;
import java.util.Date;
/**
* 定时任务反射工具类
*
* @author 郑健楠
*/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class TaskInvokUtil {
private final ApplicationEventPublisher publisher;
@Autowired
private SysJobService sysJobService;
@SneakyThrows
public void invokMethod(SysJob sysJob, Trigger trigger) {
ITaskInvok iTaskInvok;
//执行开始时间
long startTime;
//执行结束时间
long endTime;
//获取执行开始时间
startTime = System.currentTimeMillis();
//更新定时任务表内的状态、执行时间、上次执行时间、下次执行时间等信息
SysJob updateSysjob = new SysJob();
updateSysjob.setJobId(sysJob.getJobId());
//日志
SysJobLog sysJobLog = new SysJobLog();
sysJobLog.setJobId(sysJob.getJobId());
sysJobLog.setJobName(sysJob.getJobName());
sysJobLog.setJobGroup(sysJob.getJobGroup());
sysJobLog.setJobOrder(sysJob.getJobOrder());
sysJobLog.setJobType(sysJob.getJobType());
sysJobLog.setExecutePath(sysJob.getExecutePath());
sysJobLog.setClassName(sysJob.getClassName());
sysJobLog.setMethodName(sysJob.getMethodName());
sysJobLog.setMethodParamsValue(sysJob.getMethodParamsValue());
sysJobLog.setCronExpression(sysJob.getCronExpression());
sysJobLog.setTenantId(sysJob.getTenantId());
try {
if (StrUtil.isEmpty(sysJob.getJobType())) {
log.info("定时任务类型无对应反射方式,反射类型为空");
throw new TaskException("定时任务类型无对应反射方式,反射类型为空");
}
if (StrUtil.isNotEmpty(sysJob.getJobType()) && JobTypeQuartzEnum.JAVA.getType()
.equals(sysJob.getJobType())) {
iTaskInvok = SpringContextHolder.getBean("javaClassTaskInvok");
iTaskInvok.invokMethod(sysJob);
} else if (StrUtil.isNotEmpty(sysJob.getJobType()) && JobTypeQuartzEnum.SPRING_BEAN.getType()
.equals(sysJob.getJobType())) {
iTaskInvok = SpringContextHolder.getBean("springBeanTaskInvok");
iTaskInvok.invokMethod(sysJob);
} else if (StrUtil.isNotEmpty(sysJob.getJobType()) && JobTypeQuartzEnum.REST.getType()
.equals(sysJob.getJobType())) {
iTaskInvok = SpringContextHolder.getBean("restTaskInvok");
iTaskInvok.invokMethod(sysJob);
} else if (StrUtil.isNotEmpty(sysJob.getJobType()) && JobTypeQuartzEnum.JAR.getType()
.equals(sysJob.getJobType())) {
iTaskInvok = SpringContextHolder.getBean("jarTaskInvok");
iTaskInvok.invokMethod(sysJob);
} else {
log.info("定时任务类型无对应反射方式,反射类型:{}", sysJob.getJobType());
throw new TaskException("");
}
//获取执行结束时间
endTime = System.currentTimeMillis();
sysJobLog.setJobMessage(PigxQuartzEnum.JOBLOGSTATUSSUCCESS.getDescription());
sysJobLog.setJobLogStatus(PigxQuartzEnum.JOBLOGSTATUSSUCCESS.getType());
sysJobLog.setExecuteTime(String.valueOf(endTime - startTime));
//任务表信息更新
updateSysjob.setJobExecuteStatus(PigxQuartzEnum.JOBLOGSTATUSSUCCESS.getType());
updateSysjob.setStarttime(trigger.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
updateSysjob.setPrevioustime(trigger.getPreviousFireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
updateSysjob.setNexttime(trigger.getNextFireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
} catch (Throwable e) {
//获取执行结束时间
endTime = System.currentTimeMillis();
log.error("定时任务执行失败,任务名称:{};任务组名:{},cron执行表达式:{},执行时间:{}", sysJob.getJobName(), sysJob.getJobGroup(), sysJob.getCronExpression(), new Date());
sysJobLog.setJobMessage(PigxQuartzEnum.JOBLOGSTATUFAIL.getDescription());
sysJobLog.setJobLogStatus(PigxQuartzEnum.JOBLOGSTATUFAIL.getType());
sysJobLog.setExecuteTime(String.valueOf(endTime - startTime));
sysJobLog.setExceptionInfo(StrUtil.sub(e.getMessage(), 0, 2000));
//任务表信息更新
updateSysjob.setJobExecuteStatus(PigxQuartzEnum.JOBLOGSTATUFAIL.getType());
updateSysjob.setStarttime(trigger.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
updateSysjob.setPrevioustime(trigger.getPreviousFireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
updateSysjob.setNexttime(trigger.getNextFireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
} finally {
publisher.publishEvent(new SysJobLogEvent(sysJobLog));
sysJobService.updateById(updateSysjob);
}
}
}
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.daemon.util;
import com.pig4cloud.pigx.daemon.config.PigxQuartzFactory;
import com.pig4cloud.pigx.daemon.entity.SysJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Component;
import static com.pig4cloud.pigx.daemon.constant.enums.PigxQuartzEnum.*;
/**
* 定时任务的工具类
*
* @author 郑健楠
*/
@Slf4j
@Component
public class TaskUtil {
/**
* 获取定时任务的唯一key
*
* @param sysjob
* @return
*/
public JobKey getJobKey(SysJob sysjob) {
return JobKey.jobKey(sysjob.getJobName(), sysjob.getJobGroup());
}
/**
* 获取定时任务触发器cron的唯一key
*
* @param sysjob
* @return
*/
public TriggerKey getTriggerKey(SysJob sysjob) {
return TriggerKey.triggerKey(sysjob.getJobName(), sysjob.getJobGroup());
}
/**
* 添加或更新定时任务
*
* @param sysjob
* @param scheduler
*/
public void addOrUpateJob(SysJob sysjob, Scheduler scheduler) {
CronTrigger trigger = null;
try {
JobKey jobKey = this.getJobKey(sysjob);
//获得触发器
TriggerKey triggerKey = this.getTriggerKey(sysjob);
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//判断触发器是否存在(如果存在说明之前运行过但是在当前被禁用了,如果不存在说明一次都没运行过)
if (trigger == null) {
//新建一个工作任务 指定任务类型为串接进行的
JobDetail jobDetail = JobBuilder.newJob(PigxQuartzFactory.class).withIdentity(jobKey).build();
//将任务信息添加到任务信息中
jobDetail.getJobDataMap().put(SCHEDULEJOBKEY.getType(), sysjob);
//将cron表达式进行转换
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysjob.getCronExpression());
cronScheduleBuilder = this.handleCronScheduleMisfirePolicy(sysjob, cronScheduleBuilder);
//创建触发器并将cron表达式对象给塞入
trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
//在调度器中将触发器和任务进行组合
scheduler.scheduleJob(jobDetail, trigger);
} else {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysjob.getCronExpression());
cronScheduleBuilder = this.handleCronScheduleMisfirePolicy(sysjob, cronScheduleBuilder);
//按照新的规则进行
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
//将任务信息更新到任务信息中
trigger.getJobDataMap().put(SCHEDULEJOBKEY.getType(), sysjob);
//重启
scheduler.rescheduleJob(triggerKey, trigger);
}
// 如任务状态为暂停
if (sysjob.getJobStatus().equals(JOBSTATUSNOTRUNNING.getType())) {
this.pauseJob(sysjob, scheduler);
}
} catch (SchedulerException e) {
log.error("添加或更新定时任务,失败信息:{}", e.getMessage());
}
}
/**
* 暂停定时任务
*
* @param sysjob
* @param scheduler
*/
public void pauseJob(SysJob sysjob, Scheduler scheduler) {
try {
if (scheduler != null) {
scheduler.pauseJob(getJobKey(sysjob));
}
} catch (SchedulerException e) {
log.error("暂停任务失败,失败信息:{}", e.getMessage());
}
}
/**
* 恢复定时任务
*
* @param sysjob
* @param scheduler
*/
public void resumeJob(SysJob sysjob, Scheduler scheduler) {
try {
if (scheduler != null) {
scheduler.resumeJob(getJobKey(sysjob));
}
} catch (SchedulerException e) {
log.error("恢复任务失败,失败信息:{}", e.getMessage());
}
}
/**
* 移除定时任务
*
* @param sysjob
* @param scheduler
*/
public void removeJob(SysJob sysjob, Scheduler scheduler) {
try {
if (scheduler != null) {
// 停止触发器
scheduler.pauseTrigger(getTriggerKey(sysjob));
//移除触发器
scheduler.unscheduleJob(getTriggerKey(sysjob));
//删除任务
scheduler.deleteJob(getJobKey(sysjob));
}
} catch (Exception e) {
log.error("移除定时任务失败,失败信息:{}", e.getMessage());
}
}
/**
* 启动所有运行定时任务
*
* @param scheduler
*/
public void startJobs(Scheduler scheduler) {
try {
if (scheduler != null) {
scheduler.resumeAll();
}
} catch (SchedulerException e) {
log.error("启动所有运行定时任务失败,失败信息:{}", e.getMessage());
}
}
/**
* 停止所有运行定时任务
*
* @param scheduler
*/
public void pauseJobs(Scheduler scheduler) {
try {
if (scheduler != null) {
scheduler.pauseAll();
}
} catch (Exception e) {
log.error("暂停所有运行定时任务失败,失败信息:{}", e.getMessage());
}
}
/**
* 获取错失执行策略方法
*
* @param sysJob
* @param cronScheduleBuilder
* @return
*/
private CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob sysJob, CronScheduleBuilder cronScheduleBuilder) {
if (MISFIRE_DEFAULT.getType().equals(sysJob.getMisfirePolicy())) {
return cronScheduleBuilder;
} else if (MISFIRE_IGNORE_MISFIRES.getType().equals(sysJob.getMisfirePolicy())) {
return cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
} else if (MISFIRE_FIRE_AND_PROCEED.getType().equals(sysJob.getMisfirePolicy())) {
return cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();
} else if (MISFIRE_DO_NOTHING.getType().equals(sysJob.getMisfirePolicy())) {
return cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
} else {
return cronScheduleBuilder;
}
}
/**
* 判断cron表达式是否正确
*
* @param cronExpression
* @return
*/
public boolean isValidCron(String cronExpression) {
return CronExpression.isValidExpression(cronExpression);
}
}
@@ -0,0 +1,30 @@
server:
port: 5007
quartz:
enabled: true
spring:
application:
name: @artifactId@
#配置中心
cloud:
config:
fail-fast: true
name: ${spring.application.name}
profile: ${spring.profiles.active}
discovery:
enabled: true
service-id: pigx-config
main:
allow-bean-definition-overriding: true
profiles:
active: dev
# 注册中心配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://pig:pig@pigx-eureka:8761/eureka/
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.daemon.mapper.SysJobLogMapper">
<resultMap id="sysJobLogMap" type="com.pig4cloud.pigx.daemon.entity.SysJobLog">
<id property="jobLogId" column="job_log_id"/>
<result property="jobId" column="job_id"/>
<result property="jobName" column="job_name"/>
<result property="jobGroup" column="job_group"/>
<result property="jobOrder" column="job_order"/>
<result property="jobType" column="job_type"/>
<result property="executePath" column="execute_path"/>
<result property="className" column="class_name"/>
<result property="methodName" column="method_name"/>
<result property="methodParamsValue" column="method_params_value"/>
<result property="cronExpression" column="cron_expression"/>
<result property="jobMessage" column="job_message"/>
<result property="jobLogStatus" column="job_log_status"/>
<result property="executeTime" column="execute_time"/>
<result property="exceptionInfo" column="exception_info"/>
<result property="createTime" column="create_time"/>
<result property="tenantId" column="tenant_id"/>
</resultMap>
</mapper>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.daemon.mapper.SysJobMapper">
<resultMap id="sysJobMap" type="com.pig4cloud.pigx.daemon.entity.SysJob">
<id property="jobId" column="job_id"/>
<result property="jobName" column="job_name"/>
<result property="jobGroup" column="job_group"/>
<result property="jobOrder" column="job_order"/>
<result property="jobType" column="job_type"/>
<result property="executePath" column="execute_path"/>
<result property="className" column="class_name"/>
<result property="methodName" column="method_name"/>
<result property="methodParamsValue" column="method_params_value"/>
<result property="cronExpression" column="cron_expression"/>
<result property="misfirePolicy" column="misfire_policy"/>
<result property="jobTenantType" column="job_tenant_type"/>
<result property="jobStatus" column="job_status"/>
<result property="jobExecuteStatus" column="job_execute_status"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="starttime" column="startTime"/>
<result property="previoustime" column="previousTime"/>
<result property="nexttime" column="nextTime"/>
<result property="tenantId" column="tenant_id"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>
+2 -1
View File
@@ -34,7 +34,8 @@
<modules>
<module>pigx-activiti</module>
<module>pigx-codegen</module>
<module>pigx-daemon</module>
<module>pigx-daemon-elastic</module>
<module>pigx-daemon-quartz</module>
<module>pigx-monitor</module>
<module>pigx-sso-client-demo</module>
<module>pigx-tx-manager</module>