定时任务
- https://eggjs.org/zh-cn/basics/schedule.html
- 可以让我们定时的去执行一些操作,比如:定时检测网站是否被篡改,定时的更新缓存、定时的爬取数据等
- 所有的定时任务都统一存放在 app/schedule 目录下
- 每一个文件都是一个独立的定时任务,可以配置定时任务的属性和要执行的方法。
1 ) 定时任务的复杂写法
app/schedule/watchfile.js
// 比较复杂的写法
'use strict';
const Subscription = require('egg').Subscription;
let i = 0;
class WatchFile extends Subscription {
// 通过 schedule 属性来设置定时任务的执行间隔等配置
static get schedule() {
return {
interval: '2s', // 1 分钟间隔
type: 'all', // 指定所有的 worker 都需要执行 所有进程
};
}
/* 官方示例
// subscribe 是真正定时任务执行时被运行的函数
async subscribe() {
const res = await this.ctx.curl('http://www.api.com/cache', {
dataType: 'json',
});
this.ctx.app.cache = res.data;
}
*/
// 简单的示例
async subscribe() {
i++;
var res = this.ctx.service.news.getList(); // 这里配置调用服务
console.log(res);
console.log(i);
}
}
module.exports = WatchFile;
2 ) 简单写法
app/schedule/simple.js
// 比较简单的的写法
'use strict';
let i = 0;
module.exports = {
schedule: {
interval: '1m', // 1 分钟间隔
type: 'all', // 指定所有的 worker 都需要执行
},
async task(ctx) {
i++;
console.log("I'm growing: " + i);
},
};
3 ) 第三种写法
app/schedule/spider.js
// 高级写法
'use strict';
let i = 0;
module.exports = app => {
return {
schedule: {
interval: '3s', // 3s间隔
type: 'all', // 指定所有的 worker 都需要执行
},
async task(ctx) {
i++;
const res = await ctx.service.news.getList(); // 这里配置调用服务
console.log(res);
console.log("I'm testing: " + i);
},
};
};
- 重启服务,多个任务都会被重新触发
4 ) 按固定时间去执行
* * * * * *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ |
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ └─────────────── hour (0 - 23)
│ └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, optional)
module.exports = {
schedule: {
// 每三小时准点执行一次
cron: '0 0 */3 * * *',
},
};
配置
- 框架提供的定时任务默认支持两种类型,worker 和 all
- worker 类型:每台机器上只有一个 worker 会执行这个定时任务,每次执行定时任务的 worker 的选择是随机的
- all 类型:每台机器上的每个 worker 都会执行这个定时任务
其他参数
- cronOptions: 配置 cron 的时区等,参见 cron-parser 文档
- immediate:配置了该参数为 true 时,这个定时任务会在应用启动并 ready 后立刻执行一次这个定时任务
- disable:配置该参数为 true 时,这个定时任务不会被启动
- env:数组,仅在指定的环境下才启动该定时任务
实例定时任务
每隔5s检测一次网站,看是否被挂掉,并解析数据
在 app/service/spider.js中编写服务
'use strict';
const Service = require('egg').Service;
class SpiderService extends Service {
async requestUrl(url) {
const res = await this.ctx.curl(url);
return res;
}
}
module.exports = SpiderService;
在app/schedule/watchdomain.js中编写
// 比较简单的的写法
'use strict';
const cheerio = require('cheerio');
module.exports = {
schedule: {
interval: '5s', // 间隔时间
type: 'all', // 指定所有的 worker 都需要执行
},
async task(ctx) {
const url = 'https://news.baidu.com/';
const res = await ctx.service.spider.requestUrl(url);
// console.log(res.data); // 输出了 能输出,说明网站没有挂掉
const htmlStr = res.data.toString();
// console.log(htmlStr); // 输出了 这个是内容
// 检测网站是否被篡改 比如:一些标志性的内容,如title
// <title>百度新闻——海量中文资讯平台</title>
// 使用cheerio模块或者正则, 输出内容对比
// 加载要解析的内容
const $ = cheerio.load(htmlStr, { decodeEntities: false }); // 避免乱码
const title = $('title').text();
console.log(title);
if (title !== '百度新闻——海量中文资讯平台') {
// 网站被挂掉了,发邮件
} else {
// 一切正常
// 获取hotnews下面的所有a标签内容
$('.hotnews a').each(function() {
console.log($(this).html());
});
}
},
};