[egg.js] 扩展定时任务与阿里云消息服务MNS长轮询
发布于 7 年前 作者 jerryhu 4835 次预览 最后一次回复是 7 年前 来自 问答
目前的项目是一个App应用,后端API采用egg.js框架。 现在有这样一个需求
业务场景:
- API服务发送消息到阿里云消息服务 (MNS)
- 需要一个服务,获取阿里云消息服务(MNS)队列的消息,然后进行相关的业务处理
- 需要多个服务处理不同的业务 (比如发送短信,帖子新回复的提醒)
考虑用egg.js框架的扩展定时任务+阿里云消息服务(MNS)长轮询
代码示例: https://github.com/jerryhu/egg-mns-long-polling-experiment
task部分的代码如下:
'use strict';
module.exports = {
schedule: {
type: 'mns',
},
async task(ctx, message) {
console.log(`task1: ${message}`);
const condition = true;
while (condition) {
try {
// 获取消息
const resp = await ctx.app.alicloudMns.receiveMessage('test-post-reminder-queue', 25);
const data = Buffer.from(resp.body.MessageBody, 'base64').toString('utf8');
console.log(`data: ${data}`);
// TODO: 新评论提醒
// 删除消息
await ctx.app.alicloudMns.deleteMessage('test-post-reminder-queue', resp.body.ReceiptHandle);
} catch (err) {
if (err.name === 'MNSMessageNotExistError') {
console.log(`没有消息: ${new Date()}`);
continue;
}
console.error(`获取消息出错 ${err.stack}`);
break;
}
}
},
};
问题:
- 扩展定时任务中长时间执行任务是否可行?
- 有没有更优的解决方案(nodejs后端服务应用+阿里云MNS长轮询)?
11 回复
这代码有问题吧,一会cpu就飙满了,node不太适合这么用,阿里云MNS没提供subscribe机制吗?感觉还是换个思路 这种也比while(true)好吧
我没有用 while true 用的是递归,目前跑了一年多 是没有问题的 一次执行完成了 才执行下一次的拉取
@jerryhu js是单线程运行的,while(true)会把cpu占满,回调不能执行
@carlisliu 我看了一些文章, while(true)有时候确实会导致事件堵塞 例如以下代码
但是我如果修改下代码,就没有了堵塞这个问题
参考了cheerego的做法,我把while(true)改为了递归调用
是不是阿里云的MQ比MNS更合适
egg 的定时任务可以指定间隔时间吧。用框架提供的功能来控制频度是否更好?
这样如何:
@464085647 理论上MQ比MNS更合适。 但是在项目中,考虑到以下两点,我选择了MNS
@waitingsong
@jerryhu timeout(3000) 这个只是个例子,自己根据实际情况修改超时值甚至不用 timeout() 控制就行了