系列文章目录
前言
一、安装cron和timezone
二、创建相关db
1.定时任务开关表
2.定时任务表和运行记录表
三、相关代码实现
四、时区数据下载
五、time cron
前言
使用cron 插件实现动态任务调度,配置不同时区的定时任务
一、安装cron和timezone
npm ininstall cron
npm install moment-timezone
二、创建相关db
1.定时任务开关表
CREATE TABLE `scheduled_task_switch` (
`id` int(10) NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '1',
`runningState` tinyint(1) DEFAULT '0' COMMENT '0: 初始状态 1:正在停止 2:已停止',
`createBy` varchar(50) NOT NULL,
`createDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updateBy` varchar(50) DEFAULT NULL,
`updateDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.定时任务表和运行记录表
CREATE TABLE `scheduled_tasks` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`code` varchar(100) DEFAULT NULL,
`name` varchar(100) NOT NULL,
`cronTime` varchar(100) DEFAULT NULL,
`timeZone` varchar(200) DEFAULT NULL,
`isActive` tinyint(1) NOT NULL DEFAULT '1',
`limitCount` int(10) DEFAULT NULL,
`errMaxCount` int(5) DEFAULT '5',
`saveLog` tinyint(1) DEFAULT '0'45,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `scheduled_task_logs` (
`id` bigint(30) NOT NULL AUTO_INCREMENT,
`taskId` int(10) NOT NULL,
`name` varchar(100) DEFAULT NULL,
`code` varchar(100) DEFAULT NULL,
`cronTime` varchar(100) DEFAULT NULL,
`timeZone` varchar(200) DEFAULT NULL,
`locationDate` datetime DEFAULT NULL,
`locationWeekDay` tinyint(1) DEFAULT NULL,
`execCount` int(10) DEFAULT '0',
`remarks` varchar(2000) DEFAULT NULL,
`status` tinyint(1) DEFAULT '1',
`execStatus` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
三、相关代码实现
interface TaskContent {
taskId: number
taskCode: string
taskData: cron.CronJob
taskInfo: taskDb.ScheduledTasks
}
// 保存已加载的任务
let taskContents: TaskContent[] = []
export const initScheduledTask = (): void => {
const job = new CronJob('0 */1 * * * *', async function () {
// 获取任务调度总开关
if (switchStatus === 1) {
const scheduleTasks: taskDb.ScheduledTasks[] = await taskDb.getScheduledTask()
for (const task of scheduleTasks) {
const isActive = task.isActive
const saveLog = task.saveLog
const contentIndex = taskContents.findIndex(t => t.taskId === task.id)
if (contentIndex === -1) { // 不存在
const taskData = new CronJob(task.cronTime, async function () {
const timeZoneDate = timeZone.tz(task.timeZone)
const locationDate = timeZoneDate.format('YYYY-MM-DD HH:mm:ss')
//根据task code 处理不同的业务逻辑
},null, true, task.timeZone ?? '')
if (isActive === 1) {
taskData.start()
}
taskContents.push({
taskId: task.id,
taskCode: task.code,
taskData,
taskInfo: task
})
} else {
// 根据task.isActive启动或者暂停相关任务
taskContents[contentIndex].taskInfo = task
}
}
} else {
if (taskContents.length > 0) {
for (let i = taskContents.length - 1; i >= 0; i--) {
const taskData = taskContents[i].taskData
const taskInfo = taskContents[i].taskInfo
if (taskData.running) {
taskData.stop()
taskContents[i].taskInfo.isActive = 0
} else {
// 移除数组中的数据
taskContents.splice(i, 1)
// 保存任务记录
saveLog(taskInfo)
}
}
}else {
// 修改任务调度状态为已停止
}
}
})
job.start()
}
四、时区数据下载
Download Time Zone Database - TimeZoneDB
五、time cron
0 */2 * * * * 每2分钟执行一次