RabbitMQ的几个常见问题
1. 如何保证消息尽量发送成功?
问题描述: 如果没有启动消费者,重启了RabbitMQ服务,队列和消息都会丢失。
解决方案: 针对这个问题,有以下几个机制可以解决:
- 生产者确认;
- 持久化;
- 手动ACK。
生产者确认
首先,我们要确保生产者能成功地将消息发送到RabbitMQ服务器。
默认情况下生产者发送消息并不会返回任何状态信息,也就是它并不知道消息有没有正确地到达服务器。
针对这个问题,RabbitMQ提供了两种解决方案:
- 事务机制;
- 通过发送方确认机制(publisher confirm);
事务机制相关的方法主要有三个:
- channel.txSelect:用于将当前的channel设置成事务模式;
- channel.txCommit:用于提交事务;
- channel.txRollback:用于回滚事务.
用过数据库的人对事务一词肯定不陌生,在RabbitMQ中也是类似的,只有消息被RabbitMQ服务端成功接收,事务才能提交成功,否则就会触发异常,可以对异常进行捕获处理。
事务机制是阻塞形式的,一条消息发送之后会使消息端阻塞,以等待RabbitMQ的回应,才能发送下一个消息。
使用事务机制会影响RabbitMQ的性能,因此还是推荐使用发送方确认机制。
发送方确认机制是指生产者将channel设置成confirm模式,所有在该信道上发布的消息都会被指派一个唯一ID(从1开始),一旦消息被投递到RabbitMQ服务器之后,RabbitMQ就会发送一个包含了消息唯一ID的确认(Basic.Ack)给生产者,使生产者知道消息已经正确到达了目的地。
如果RabbitMQ因为内部错误导致消息丢失,就会发送一条nack(Basic.Nack)命令,生产者可以在回调方法中处理该nack命令。
发送方确认机制是异步的,一旦发布一条消息,生产者可以在等待信道返回的同时发送下一条消息,当消息确认时,可以在回调方法中处理该确认消息。因此,总体效率会更好。
相关的方法:
- channel.confirmSelect();
- channel.waitForConfirms;
- channel.addConfirmListener;
当然confirm机制也可以分为:普通confirm,批量confirm,异步confirm。
普通confirm可事务机制差不多,就是发送一条,就调用waitForConfirms确认一次;批量confirm就是发送多条后,再调用waitForConfirms确认一次;异步confirm就是注册两个回调分别处理Ack和NAck确认。
事务机制和生产者确认机制是互斥的,不能共存!
发送成功的含义是消息能到达RabbitMQ交换机,并且能有匹配的队列接收。
总体效率上,异步confirm会更好。
2. 如何进行消息持久化?
所谓持久化,就是RabbitMQ将内存中的数据(比如交换机、队列、消息等)固化到磁盘,以防止异常情况的发生时造成数据丢失。
RabbitMQ持久化分为:
- 交换机持久化;
- 队列持久化;
- 消息持久化
交换机的持久化
在创建Exchange时设置durable参数参数。
channel.exchangeDeclare(EXCHANGE_NAME, "direct", true);
队列的持久化
同样也是设置设置durable参数。
持久化的队列会存盘,在服务器重启的时候可以保证不丢失相关信息。
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
消息的持久化
即使交换机、队列持久化不会因为重启丢失,但是存储在队列中的消息仍然会丢失。
解决的办法就是设置消息的投递模式为2,即代表持久化(JAVA)。
理论上,可以将所有的消息都设置为持久化,但是这会严重影响RabbitMQ性能,因为写入到磁盘的速度可比写入到内存的速度慢非常多。因此,在选择是否要持久化消息时,需要在可靠性和吞吐量之间做一个权衡。
然而,将交换机、队列、消息都设置持久化之后仍然不能够保证百分百不会丢失数据。因为有些消息可能还没来得及落盘,就发生了宕机、重启等异常情况。
如何保证消息被正确消费
这部分要处理的场景是: 当消费者接收到消息后,还没处理完业务逻辑,消费者挂掉了,此时消息等同于丢失了。
为了确保消息被消费者成功消费,RabbitMQ提供了消息确认机制,主要通过显示Ack模式来实现。
默认情况下,RabbitMQ会自动把发送出去的消息置为确认,然后从内存(或磁盘)删除,但是我们在使用时可以手动设置autoAck为False的,当然具体做法各个语言都不一样。
需要注意的时,如果设置autoAck为false,也就意味者每条消息需要我们自己发送ack确认,RabbitMQ才能正确标识消息的状态。
消息队列的优缺点
优点:
- 解耦和复用,易扩展;
- 异步;
- 削峰;
缺点:
- 系统可用性降低,复杂度提高,mq要是挂了,影响太大;
- 存在数据一致性问题
选用RabbitMQ的理由
目前还是有很多种消息队列的,各有特点。
对于选用RabbitMQ的理由,大概因为:延时低是它最大的特点,同时单机吞吐量也很不错;也能进行分布式集群扩展;社区非常活跃。
RabbitMQ的几个常见问题的更多相关文章
- RabbitMQ 离线安装(带视频)
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 疯狂创客圈 高并 ...
- 【攻克RabbitMQ】常见问题
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/zlt995768025/article/ ...
- [Open Source] RabbitMQ 安装与使用
前言 吃多了拉就是队列,吃饱了吐就是栈 使用场景 对操作的实时性要求不高,而需要执行的任务极为耗时:(发送短信,邮件提醒,更新文章阅读计数,记录用户操作日志) 存在异构系统间的整合: 安装 下载 Er ...
- RabbitMQ可靠性投递及高可用集群
可靠性投递: 首先需要明确,效率与可靠性是无法兼得的,如果要保证每一个环节都成功,势必会对消息的收发效率造成影响.如果是一些业务实时一致性要求不是特别高的场合,可以牺牲一些可靠性来换取效率. 要保证消 ...
- centos 7 rabbitmq 3.7.12 erlang 20.3源码安装
1.下载erlang 官网地址 http://www.erlang.org/download 挑选合适的版本 然后 建议20.3运行命令 wget http://erlang.org/download ...
- Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)
应用场景 之前我们已经通过<Spring Cloud Stream消费失败后的处理策略(一):自动重试>一文介绍了Spring Cloud Stream默认的消息重试功能.本文将介绍Rab ...
- RabbitMQ 安装与使用
RabbitMQ 安装与使用 前言 吃多了拉就是队列,吃饱了吐就是栈 使用场景 对操作的实时性要求不高,而需要执行的任务极为耗时:(发送短信,邮件提醒,更新文章阅读计数,记录用户操作日志) 存在异 ...
- rabbitmq集群部署及配置
消息中间件rabbitmq,一般以集群方式部署,主要提供消息的接受和发送,实现各微服务之间的消息异步.本篇将以rabbitmq+HA方式进行部署. 一.原理介绍 rabbitmq是依据erlang的分 ...
- 关于 RabbitMQ 的 Dead-Letters-Queue “死信队列”
来自一个队列的消息可以被当做‘死信’,即被重新发布到另外一个“exchange”去,这样的情况有: 消息被拒绝 (basic.reject or basic.nack) 且带 requeue=fa ...
随机推荐
- Vue工程化入口文件main.js中Vue.config.productionTip = false含义
阻止启动生产消息,常用作指令.通俗理解为消息提示的环境配置. 阻止启动生产消息 這又是什麽意思? 看下效果 (1)Vue.config.productionTip = false (2)Vue.con ...
- Jmeter(二)响应内容乱码解决办法
Jmeter请求编码设置为UTF-8,响应内容依然乱码,可在Jmeter安装路径bin\jmeter.properties中设置默认编码为UTF-8,于是问题得以解决:
- 求GCD(最大公约数)的两种方式
求GCD(最大公约数)的两种方式 这篇随笔讲解C++语言程序设计与应用中求GCD(最大公约数,下文使用GCD代替)的两种常用方式:更相减损法和辗转相除法,前提要求是具有小学数学的基本素养,知道GCD是 ...
- git使用遇到问题1
1.上传代码过程中遇到 git help gc错误解决方法,有两种方式,推荐第一种方式. $ git fsck $ git gc --prune=now 如果执行完上面的命令还是不行的话,可以尝试删掉 ...
- The Python Debugger Pdb
Python Debugger pdb The Python Debugger Pdb 可以直接在命令行中启动,调试程序 也可以写在代码中 命令行使用 可以直接在命令行指定要进行调试的程序 pytho ...
- 开源规则引擎 drools
java语言开发的开源业务规则引擎 DROOLS(JBOSS RULES )具有一个易于访问企业策略.易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快.效率高.业务分析师或审核人员可以利用 ...
- LinkCutTree学习笔记
LinkCutTree 学习笔记 参考来源 https://www.zybuluo.com/xzyxzy/note/1027479 https://www.cnblogs.com/zhoushuyu/ ...
- 怎样用cmd脚本添加Qt的环境变量
在网上遍历了很久,终于找到了一个简单且令人满意的答案: 定位到PyQt5发布文件所需的plugins的位置: 新建一个名为“设置环境变量”的cmd脚本,在里面写上: wmic ENVIRONMENT ...
- 【VS开发】COM组件技术概述
这篇文章对COM做出来比较完整的解释,非常好. COM是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术.在COM构架下,人们可以开发出各种各样功能专一的组件,然后将它 ...
- LeetCode 21:合并两个有序链表 Merge Two Sorted Lists
将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. Merge two sorted linked lists and return it as a new ...