用戶添加定時任務后如
每月30 號發(fā)工資
訂單到期未付款恢復
這種是如何做的?
直接在Linux 操作crontab 可以,
但是用戶添加一個任務就加到 crontab 怎么實現(xiàn)?
Keywords: shell_exec, php safe mode
shell_exec solves your problem of adding scheduled tasks. The shell_exec function cannot be used when PHP safe mode is turned on.
Scheduled tasks can be stored in MySQL or files, and then use crontab to run mysql or files
Use independent scheduled task middleware to manage, user scheduled tasks are not suitable to be placed in crontab
I'll quote Naist
First of all, you need to be able to use crontab. Yes, if you don't know how to use it, just use Baidu. I won't answer it here. You can write a blog.
Then in the command line
crontab -e
After
0 0 30 * * php 需要定期執(zhí)行的php腳本位置
It may not be crontab. I used node.js
to write a WebSocket that users can schedule by themselves before and hang in the background. When the user sends a request to this WebSocket, the scheduled time is recorded in a cache file (JSON), and then node.js
sets its own timer.
If the WebSocket service hangs up, just restart the background script, and the script will reset the scheduled task based on the time recorded in the cached JSON. I can put some code here, the core code is omitted, and some comments are added for reference
'use strict';
// 一些NodeJS包
const WebSocket = require('ws');
const path = require('path');
const crontab = require('node-crontab');
const spawn = require('cross-spawn');
const fsExtra = require('fs-extra');
const objectValues = require('object-values');
// 省略了一些配置
const wss = new WebSocket.Server({port: 8080}); // 創(chuàng)建WebSocket服務
let ScheduleList = {}; // 這個為存儲時間的JS對象
let JobList = {}; // 這個為存儲定時任務ID的JS對象,如果要取消任務,就通過這個來查找定時任務ID
// 省略了日志方法
// 故障后重啟載入任務時間的方法
const loadJobs = () => {
let jobsCache = path.resolve(__dirname, './config/scheduler.jobs');
if(fsExtra.pathExistsSync(jobsCache)) {
ScheduleList = fsExtra.readJsonSync(jobsCache, {throw: false}) || {};
}
};
// 用戶傳入時間時將任務時間對象ScheduleList重寫到文件的方法
const saveJobs = () => {
let jobsCache = path.resolve(__dirname, './config/scheduler.jobs');
fsExtra.outputJsonSync(jobsCache, ScheduleList);
};
// 根據(jù)ScheduleList重新創(chuàng)建計劃任務的方法
const rerunJobs = () => {
for(let jobScheduleId in ScheduleList) {
let hour = ScheduleList[jobScheduleId].hour || 0;
let minute = ScheduleList[jobScheduleId].minute || 0;
let jobId = crontab.scheduleJob(`${minute} ${hour} * * *`, () => {
// 此處省略了任務創(chuàng)建的具體操作,用的cross-spawn包
});
JobList[id] = jobId;
}
};
loadJobs(); // 啟動時載入時間
rerunJobs(); // 根據(jù)時間重新創(chuàng)建計劃任務
wss.on('connection', ws => {
ws.on('message', message => {
// 省略了傳入數(shù)據(jù)的解析
// 如果任務存在,先刪除任務
if(JobList[id]) {
crontab.cancelJob(JobList[id]);
delete ScheduleList[id];
delete JobList[id];
}
// 重新添加任務
let jobId = crontab.scheduleJob(`${minute} ${hour} * * *`, () => {
// 同rerunJobs()里的創(chuàng)建操作,省略細節(jié)
});
ScheduleList[id] = {id: id, hour: hour, minute: minute};
JobList[id] = jobId;
saveJobs(); // 保存任務計劃時間
ws.send(JSON.stringify(response(null, {message: '應用成功'}))); // 給請求者反饋
});
});
For PHP, you can only use crontab to select scheduled tasks, so the shortest training rotation time is 1 second
If you want it within 1 second, you have to find another way.