RabbitMQ 实践之在处理异步任务中的流程
一、背景:
我司的系统,用户可以创建任务,启动任务,但任务的运行需要很长的时间,所以采用消息队列的方式,后台异步处理。
这里所用到的是 RabbitMQ ,对应的 Node.js 库为 amqplib ( 这里采用的是回调形式:require("amqplib/callback_api") )。
二、MQ 处理任务的流程

① ② ③ ④ ⑤ :从前端发来 HTTP 请求,被 Producer(express) 处理,经过 Route -> Controller -> Function ,使用 amqplib 的 sendToQueue(),发送需要处理的任务的 uuid 入 MQ 队列。这时候,还要修改数据库,把该任务的状态从 "new" -> "queue"。
⑥ ⑦ ⑧ ⑨ ⑩ ⑪ : Consumer 消化 MQ 队列吐出来的 message,即任务的 uuid。先修改数据库该任务的状态为"runnning", 然后调用"处理"模块去执行复杂运算,执行完成后,修改数据库该任务的状态是 "success" 还是 ”fail”,然后返回 ack 信号给 MQ 。
注:这次的需求比较简单,所以没有用到 MQ 的交换机功能。
三、问与答
Q:如何做好 MQ 的错误处理?
MQ 的 connection 和 channel 对象都有 "error" 和 "close" 事件,需做好相关的日志记录。尤其是 "error",要加上 reconnect 机制,防止因为某个任务导致的错误或者 MQ 自身的原因,影响到后续任务的处理。
connection.on("error", function(err) {
// reconnect
});
channel.on("error", function(err) {
// reconnect
});
最后可以根据实际需要,在全局加上 try……catch。
Q:如何保证 MQ 自身消息的数据安全?
为了防止 MQ server 的崩溃导致的消息损失,需要对数据做持久化。大致分两块:
队列持久化 + 消息持久化
channel.assertQueue(queue_name, {
durable: true
// 队列持久化
});
channel.sendToQueue(
queue_name,
Buffer.from(uuid),
{
persistent: true
// 消息持久化
},
function(err, ok) {
}
);
Q:如何保证 DB 跟 MQ 数据的一致性?
1、发送 message 时
④ 中的 sendToQueue() ,需要在 createConfirmChannel() 的基础下使用,这样 sendToQueue() 的第三个参数才有 MQ 收到 message 成功与否的回调,根据这个,去结合 ② 的 DB 操作, 绑定为事务,来保证数据的一致性。
2、接受 message 时
channel.consume() 需开启 ack 模式,等 Consumer 端一切确认完成后,再通知 MQ 。
channel.consume(
queue_name,
function(msg) {
const uuid = msg.content.toString();
// use uuid todo……
},
{
noAck: false
}
);
Q:如何避免 MQ 多发、少发的问题
从上面的 如何保证 DB 跟 MQ 数据的一致性? 其实就避免了该问题的发生。
但是额外要做的是:
1、重试机制,例如 发送 message 失败,规定重试的次数。
2、善用 MQ 的 Web 控制台,地址形如 http://localhost:15672。除了关注基本的服务器负载状态,还要关注任务队列是否正常吞吐,是否有卡壳。
3、构建运维一体的后台管控系统,比上面的 2 自定义程度更高。
4、提供用户类似"提交工单"/"问题反馈"/"错误上传"的功能,查缺补漏。
RabbitMQ 实践之在处理异步任务中的流程的更多相关文章
- C#异步编程中的最佳实践(做法)
原文地址Stephen Cleary 写得很详细,尤其讲到了 GUI 上下文调用,在APS.NET中它会阻塞 GUI 线程,从而导致死锁.而控制台中却不存在这个问题. 比如开发过程中本地写控制台程序测 ...
- NET下RabbitMQ实践[实战篇]
之前的文章中,介绍了如何将RabbitMQ以WCF方式进行发布.今天就介绍一下我们产品中如何使用RabbitMQ的! 在Discuz!NT企业版中,提供了对HTTP错误日志的记录功能 ...
- 探究SynchronizationContext在.Net异步编程中的地位
原文:探究SynchronizationContext在.Net异步编程中的地位 引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要去学习,贴心的.NET提供Task线程包装类和await/a ...
- 你不知道的this—JS异步编程中的this
Javascript小学生都知道了javascript中的函数调用时会 隐性的接收两个附加的参数:this和arguments.参数this在javascript编程中占据中非常重要的地位,它的值取决 ...
- 实践基于Task的异步模式
Await 返回该系列目录<基于Task的异步模式--全面介绍> 在API级别,实现没有阻塞的等待的方法是提供callback(回调函数).对于Tasks来说,这是通过像ContinueW ...
- Android异步回调中的UI同步性问题
Android程序编码过程中,回调无处不在.从最常见的Activity生命周期回调开始,到BroadcastReceiver.Service以及Sqlite等.Activity.BroadcastRe ...
- [Effective JavaScript 笔记]第62条:在异步序列中使用嵌套或命名的回调函数
异步程序的操作顺序 61条讲述了异步API如何执行潜在的代价高昂的I/O操作,而不阻塞应用程序继续处理其他输入.理解异步程序的操作顺序刚开始有点混乱.例如,下面的代码会在打印"finishe ...
- [置顶] Ajax程序:处理异步调用中的异常(使用Asp.Net Ajax内建的异常处理方法)
无论在Window应用程序,还是Web应用程序以对用户友好的方式显示运行时的异常都是很有必要,尤其对于可能有很多不确定因素导致异常的Web应用程序;在传统的Web开发中,处理异常的方式——设计专门一个 ...
- 使用domain模块捕获异步回调中的异常
和其他服务器端语言相比,貌似node.js 对于异常捕捉确实非常困难. 首先你会想到try/catch ,但是在使用过程中我们会发现并没有真正将错误控制在try/catch 语句中. 为什么? 答案是 ...
随机推荐
- libevent for qt的讨论
一直对Qt官方的QtNetwork模块抱有遗憾,Qt自带的网络模块用的是select模型,无法支持高并发的服务器开发.最近在网上看到有个libevent for qt的东西,它直接替换了Qt的sele ...
- ASP.NET 5 (vNext) 牛刀小試:自帶 DI 容器
小引 在 ASP.NET 5(vNext)之前,亦即 MVC 4/5.Web API 2 的时代,MVC 与 Web API 框架彼此有非常相似的设计,却是以不同的代码来实现.现在,ASP.NET 5 ...
- delphi中pos和Ansipos函数的区别
POS和ANSIPOS的主要区别在于,POS参数多用于是一个字符,而ANSIPOS多用于是多个字符: 例如:i:=pos('a','sssssas'); i:=ansipos('abc','sdabc ...
- Oracle数据库密码重置、导入导出库命令
重置办法如下:打开CMD命令提示符,然后输入下面命令进行重置: 输入sqlplus /nolog,回车 SQL> conn /as sysdba 已连接: SQL>alter user s ...
- 30+ 强大的Buddypress主题–开始您的社区站点吧
BuddyPress起源于2008年,当时设计者设想添加社交网络功能到WordPress多用户版本中.第一个正式稳定版本的发布是在2009年的5月.自从那时起.BuddyPress开始快速的成长和演变 ...
- 自己动手写jQuery插件---Tip(提示框)
对jQuery相信很多同学和我一样平时都是拿来主义,没办法,要怪只能怪jQuery太火了,各种插件基本能满足平时的要求.但是这毕竟不是长久之道,古人云:“授之以鱼,不如授之以渔”. 为了方便之前没有接 ...
- Verilog写一个对数计算模块Log2(x)
网上一个能用的也没有,自己写一个把. 1.计算原理: 整数部分 网上找到了一个c语言的计算方法如下: int flog2(float x) { return ((unsigned&)x> ...
- vuex分模块4
Vuex下Store的模块化拆分实践 https://segmentfault.com/a/1190000007667542 vue.js vuex 猫切 2016年12月02日发布 赞 | 1 ...
- RT-thread线程创建:动态线程与静态线程
本文介绍了如何创建一个动态线程和一个静态线程 RT-thread版本:RT-thread system 3.1.0 开发环境:MDK5 为了编程方便,创建了sample1.c文件,然后添加到工程中 话 ...
- client-go中的golang技巧
client-go中有很多比较有意思的实现,如定时器,同步机制等,可以作为移植使用.下面就遇到的一些技术讲解,首先看第一个: sets.String(k8s.io/apimachinery/pkg/u ...