我们为什么要使用RabbitMQ?
一、前言
这篇文章就是讲RocketMQMQ的好处,你可能要说RocketMQ很好呀,我们主要看上的就是RabbitMQ支持多语言的客户端,很符合我们公司的现状,不要我们花费功夫去搞一个客户端,所以下面请大家不要吐槽,我们就来静心听听RabbitMQ的好;
二、RabbitMQ
在消息队列的一发一收中,我们来看下RabbitMQ怎么让我们放心使用的?首先我们来看下RabbitMQ发收的过程:
发消息的过程(生产者):
1.连接到RabbitMQ Borker,建立一个连接(Connection),开启一个信道(Channel);
2.声明交换机(Exchange);
3.声明队列(Queue);
4.通过路由键(Binding Key)将交换机与路由器绑定;
5.发送消息(消息包含路由键(Routing Key)和交换机等内容)到RabbitMQ Borker;
6.交换机根据接收到路由键去匹配到相应的队列中,如果找到则放入到对应的队列中,找不到则退回(这里是根据配置信息来的);
7.关闭;
收消息的过程(消费者):
1.连接到RabbitMQ Borker,建立一个连接,开启一个信道;
2.请求接收RabbitMQ Borker中队列的消息;
3.等待RabbitMQ Borker回应返回队列中相应的消息;
4.消费者接收到消息,返回确认(ack);
5.RabbitMQ移除队列中对应的消息;
6.关闭;
针对上面的过程我们首先来谈下生产者RabbitMQ是如何确保一条消息被投递到RabbitMQ Borker中的,没有使用过消息队列可能听到这里有点懵,这里简单说一下,当生产者发送一条消息的时候,可能因为网络的原因或者RabbitMQ服务器宕机了,这个时候我们就无法知道一条消息是否被成功的投递到RabbitMQ中,针对这些情况RabbitMQ给我们提供两种机制来处理这个问题,一种是事务机制,另外一种是消息确认机制。事务机制我想大家都很明白了,RabbitMQ客户端提供与事务机制相关的方法有三个:channel.txSelect、channel.txCommit以及channel.txRollback。channel.txSelect用于将当前信道设置成事务模式,channel.txCommit用于提交事务,channel.txRollback用于事务回滚。当事务开启以后,发送消息给RabbitMQ,如果消息提交成功,那么说明RabbitMQ一定收到了消息,否则我们可以通过异常来捕获,然后通过txRollback回滚,当然这种方式性能不好,事务机制将消息串行化,导致发送一条消息必须等待结果。这种方式不太好,那么我们接下来探讨一下消息确认机制,涉及到消息确认机制的相关方法有两个channel.confirmSelect以及channel.waitForConfirms,首先使用confirmSelect将信道设置成为消息确认模式,当使用消息确认模式的时候,该信道上每发布一条消息都会生成唯一的ID,当消息匹配到相应的队列以后,就会返回一个确认的ack,这个时候生产者就知道投递消息成功了,如果RabbitMQ发生宕机或者错误以后,会返回nack,则表示投递失败,当使用waitForConfirms其实是将异步的模式串行化,我们还可以通过addConfirmLister通过ConfirmListener这个回调接口来处理返回值。RabbitMQ通过这两种机制保证消息能被正确投递,生产环境中都是使用批量提交,当然实际生产的时候单纯这样还是不能够保证消息被正确投递,比如说生产者发送消息时候网络断了一下,就不能保证消息被投递过,所以下一篇我会使用延时队列和消息打标的方式来保证消息会被100%投递到RabbitMQ中,当然也不能说是100%只能说是99.好多个9;
接下来我们来探讨下消费者消费的问题,如果消费者在接受到消息以后,比如出现宕机,那么这条消息也就丢失掉了。RabbitMQ针对这种情况,也提供了消息确认机制。当消费订阅队列设置autoAck设置为fals的时候,RabbitMQ通过打标的方式,等收到消息确认的时候将队列中的消息移除出去,如果设置为true,当发送成功以后就将消息移除。当autoAck为fals的时候,RabbitMQ内部会有两种消息,一种是等待投递消息,另外一种是等待确认的消息,如果RabbitMQ一直没有收到消费者确认的消息,并且消费此消息的消费者断开,那么RabbitMQ会重新发送该条消息,RabbitMQ重新投递消息的依据就是消费者的该消息连接断开。消费端可以通过重试机制保证消息能被正常消费,如果重试还消费不掉,那么还可以利用下死信队列,通过死信队列中的内容分析程序中可能存在的异常;提到了死信队列,我们这里也介绍一下,消息成为死信有3种情况:消费端消息被拒绝,并设置requeue参数为false、消息过期以及队列达到最大长度,绑定死信队列的交换机就是死信交换机(DLX),当队列中有死信的时候,RabbitMQ会自动将消息重新发布到设置DLX上,从而被路由死信队列中;
RabbitMQ本身是可以将交换机、队列以及消息都持久化的,当然是不建议将消息持久化的,成本太高。RabbitMQ支持集群模式,是通过多副本的方式实现集群模式,在RabbitMQ中叫做镜像队列,当Master宕机以后会按照下面步骤进行:
1.与Master相关联的客户端会全部断开;
2.选举最老的Savle节点作为Master,如果这个时候所有Salve都没处于同步状态,则未同步的消息会被丢失掉;
3.出于对消息可靠性的考虑,新的Master会重新入队所有客户端未确认的消息;
4.如果客户端连着slave,并且Basic.Consume消费时指定了x-cancel-on-ha-failover参数,那么客户端会接收到一个Consumer Cancellation Notification通知。如果未指定x-cancal-on-ha-failover参数,那么消费者就无法感知master宕机,会一直等待下去。
另外RabbitMQ还支持优先级队列、多协议、多租户等等,性能方面的话能满足我们公司业务,记得好像我们这边高峰期达到4W-5W/s,最主要的RabbitMQ社区很活跃;
三、结束
下一篇我会使用Java和C#分别去实现上面生产者和消费者的模式,本文主要参考厮大的书和工作中使用RabbitMQ的经验, 另外在推荐下厮大的书《RabbitMQ实战指南》和《深入理解Kafka:核心设计与实践原理》,讲的真的好,欢迎大家加群438836709,欢迎大家关注我!
- Arxiv网络科学论文摘要14篇
- 工信部:网络强国建设2018年重点工作任务
- 刚刚!张小龙再出重磅!微信小程序掀起新零售红利狂潮!
- 无人驾驶系列——深度学习笔记:Tensorflow的安装-windows系统
- 2018年12大顶级云安全威胁
- 缤果盒子为域名意识打call 六位数秒下bingobox.com
- 用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)
- 用Qt写软件系列一:QCacheViewer(浏览器缓存查看器)
- 用Qt写软件系列三:一个简单的系统工具(上)
- ChartDirector应用笔记(三)
- 汇编语言 手记9
- 程序员一年写百万行代码是什么体验?这肯定是个Bug
- ChartDirector应用笔记(二)
- ChartDirector应用笔记(一)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 玩转StyleGAN2模型:教你生成动漫人物
- R语言时间序列数据指数平滑法分析交互式动态可视化
- 再见Excel!最强国产开源在线表格Luckysheet走红GitHub
- R语言广义线性模型索赔频率预测:过度分散、风险暴露数和树状图可视化
- R语言多分类logistic逻辑回归模型在混合分布模拟单个风险损失值评估的应用
- sas神经网络:构建人工神经网络模型来识别垃圾邮件
- 图像倾斜校正算法的MATLAB实现:图像倾斜角检测及校正
- 手写dubbo框架9-SPI实现
- R语言非参数模型厘定保险费率:局部回归、广义相加模型GAM、样条回归
- VsCode插件之Live Serve探秘.(上)
- R语言小数定律的保险业应用:泊松分布模拟索赔次数
- R语言中自编基尼系数的CART回归决策树的实现
- Docker hello world
- 前端环境配置
- R数据读取(数据文件解析)