rabbitmq怎样确认是否已经消费了消息_阿里Java研发二面:了解RabbitMQ?说说RabbitMQ可靠性投递...

上期写到高并发下RabbitMq消息中间件你应该介么玩今天给小伙伴说说!有自己看法的也可以在评论区留言探讨,也可以转发关注下我以后会长期分享!

目录:

  1. 确保消息发送到RabbitMQ服务器
  2. 确保消息被正确的路由
  3. 确保消息在队列正确地存储
  4. 确保消息从队列正确地投递到消费者
  5. 消费者回调
  6. 补偿机制
  7. 消息幂等性
  8. 消息的顺序性

可靠性投递

首先需要明确,效率和可靠性是无法兼得的,如果要保证每一个环节都成功,势必会对消息的收发效率造成影响,如过是一些业务实时性要求不是特别高的场合,可以牺牲可靠性来换取效率。

d96dcdd365711a37629ffd7574147183.png
  1. ①代表消息从生产者发送到Exchange
  2. ②代表消息从Exchange路由到Queue
  3. ③ 代表消息在Queue中存储;
  4. ④ 代表消费者订阅Queue并消费消息。

1.确保消息发送到RabbitMQ服务器

可能因为网络或者Broker的问题导致①失败,而生产者是无法得知消息是否正确发送到Broker的。

有两种解决方案:

第一种是Transaction事务模式

第二种是Confirm确认模式

1.在通过channel.txSelect方法开启事务之后,我们便可以发布消息给RabbitMQ了,如果事务提交成功,则消息一定 到达了RabbitMQ中,如果在事务提交执行之前由于RabbitMQ异常崩溃或者其他原因抛出异常,这个时候我们便可以将其捕获,进而通过执行channel.txRollback方法来实现事务回滚。使用事务机制的话会“吸干”RabbitMQ的性 能,一般不建议使用。
2.生产者通过调用channel.confirmSelect方法(即Confirm.Select命令)将信道设置为confirm模式。一旦消息被投递到所有匹配的队列之后,RabbitMQ就会发送一个确认(Basic.Ack)给生产者(包含消息的唯一ID),这就使得生产者知晓消息已经正确到达了目的地了。

2.确保消息被正确的路由

可能因为路由关键字错误,或者队列不存在,或者队列名称错误导致②失败。

  1. 使用mandatory参数和ReturnListener,可以实现消息无法路由的时候返回给生产者。
  2. 另一种方式就是使用备份交换机(alternate-exchange),无法路由的消息会发送到这个交换机上。
Map<String,Object> arguments = new HashMap<String,Object>();
// 指定交换机的备份交换机
arguments.put("alternate-exchange","ALTERNATE_EXCHANGE"); 
channel.exchangeDeclare("TEST_EXCHANGE","topic", false, false, false, arguments);

3.确保消息在队列正确地存储

可能因为系统宕机、重启、关闭等等情况导致存储在队列的消息丢失,即③出现问题。

解决方案:

1.队列持久化

// String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments 
channel.queueDeclare(QUEUE_NAME, true, false, false, null);

2.交换机持久化

// String exchange, boolean durable 
channel.exchangeDeclare("MY_EXCHANGE","true");

3.消息持久化

AMQP.BasicProperties properties = new AMQP.BasicProperties
.Builder() 
// 2代表持久化,其他代表瞬态 
.deliveryMode(2) 
.build(); 
channel.basicPublish("", QUEUE_NAME, properties, msg.getBytes());

4.确保消息从队列正确地投递到消费者

如果消费者收到消息后未来得及处理即发生异常,或者处理过程中发生异常,会导致④失败。
为了保证消息从队列可靠性到达消费者,RabbitMQ提供了消息确认机制(message acknowledgement),消费者在订阅队列时,可以指定autoAck参数,当autoAck等于false时,RabbitMQ会等待消费者显示地回复确认消息才从队列中删除该消息。
如果消息消费失败,也可以调用Basic.Reject或者BasicNack来拒绝当前消息而不是确认,如果requere参数为true,可以把这条消息重新存入队列,以便发送给下一个消费者。

5.消费者回调

消费者处理消息之后,可以再发送一条消息给生产者,或者调用生产者地API,告知消息处理完毕。

6.补偿机制

对于一定时间没有响应地消息,可以设置一个定时重发地机制,但是要控制次数,比如最多重复三次,否则会造成消息堆积。

7.消息幂等性

服务端是没有这种控制的,只能在消费端控制。

如何避免消息的重复消费?消息重复消费可能会有两个原因:

  1. 生产者的问题。环节①重复发送消息,比如在开启Confirm模式但未收到确认
  2. 环节④出了问题,由于消费者未发送ACK或者其它原因,消息重复投递

对于重复发送的消息,可以对每一条消息生成一个唯一的业务id,通过日志或者建表来做重复控制。

8.消息的顺序性

消息的顺序性是指消费者消费消息的顺序跟生产者投递消息的顺序是一致的。

在RabbitMQ中,一个队列有多个消费者时,由于不同的消费者消费消息的速度是不一样的,顺序无法保证

学习分享

对于高并发下RabbitMq消息中间件的使用,这位大咖也有讲解的视频,在这免费分享给大家,有需要的朋友可以帮忙点个赞关注下吧,分享不易,然后关注我的专栏(Java快速进阶通道)看顶部提示,或直接(点我)领取哦!

视频教学的内容包括:

  1. 削峰限流、解耦作用
  2. 有限资源完成高并发购票
  3. RabbitMq原理透析
  4. 购票完整闭环流程
  5. 单元测试与多线程高并发测试

f002f99f3f911e2bb1becdc17349ec2a.png

不管多忙,每天给自己预留至少半小时的学习时间,拒绝做代码垃圾的搬运工!

有不对的地方可以在评论区留言,觉得不错的朋友希望能得到您的转发支持,同时可以持续关注我,每周定期会分享3到4篇精选干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245576.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 装完yum不能用,【linux】yum 不能安装应用,提示There are no enabled repos Run “yum repolist all”...

回答一般来说著名的linux系统基本上分两大类&#xff1a;1 RedHat系列&#xff1a;Redhat、Centos、Fedora等2 Debian系列&#xff1a;Debian、Ubuntu等RedHat 系列&#xff1a;1 常见的安装包格式 rpm 包&#xff0c;安装rpm包的命令是 “rpm -参数”2 包管理工具 yum3 支持ta…

更新fielddata为true_线程与更新UI,细谈原理

前言 相信不少读者都阅读过相类似的文章了&#xff0c;但是我还是想完整的把这之间的关系梳理清楚&#xff0c;细节聊好&#xff0c;希望你也能从中学到一些。进入正题&#xff0c;大家应该都听过这样一句话——“UI更新要在主线程&#xff0c;子线程更新UI会崩溃”。久而久之就…

linux sublime3 插件安装插件,手动安装sublimeText3插件

就在今天下午&#xff0c;我花了一个小时的时间安装sublime3插件stylus&#xff0c;就是为了让stylus文件能够高亮显示。网上找了很多方法&#xff0c;可以通过package control安装&#xff0c;然而&#xff0c;我的sublime package control能够正常显示&#xff0c;插件列表也…

vbs打开软件光标停在第一个输入框_三维设计软件,3DMAX最全快捷键大全,赶快收藏哦...

文章后有获取软件的方式。基本快捷键A-角度捕捉开关 B-切换到底视图C-切换到摄象机视图D-封闭视窗E-切换到轨迹视图F-切换到前视图G-切换到网格视图H-显示通过名称选择对话框I-交互式平移J-选择框显示切换K-切换到背视图L-切换到左视图M-材质编辑器N-动画模式开关O-自适应退化开…

mfc读取txt文件并显示_Python入门丨文件读写

文件读写文件读写&#xff0c;是Python代码调用调用电脑文件的主要功能&#xff0c;能被用于读取和写入文本记录、音频片段、Excel文档、保存邮件以及任何保存在电脑上的东西。读取文件读取文件三个步骤&#xff1a;准备工作&#xff1a;首先在桌面新建了一个test文件夹&#x…

c语言 多个线程对同一变量执行memcpy_手把手带你实现线程池

执行与任务分离的组件— 线程池wangbojing/threadpool​github.com多线程技术主要解决了处理器单元内多个线程执行的问题&#xff0c;它可以显著的减少处理器单元的闲置时间&#xff0c;增加处理器单元的吞吐能力。线程池是多线程编程的一个必要组件&#xff0c;并且对于很多编…

python手势识别_Python|使用opencv进行简单的手势检测

简单的手势识别&#xff0c;基本思路是基于皮肤检测&#xff0c;皮肤的颜色在HSV颜色空间下与周围环境的区分度更高&#xff0c;从RGB转换到HSV颜色空间下针对皮肤颜色进行二值化&#xff0c;得到mask&#xff1a; defHSVBin(img):hsvcv2.cvtColor(img,cv2.COLOR_RGB2HSV) lowe…

人工智能选go还是python_深圳人工智能学Python还是go,真实经历分享

深圳人工智能学Python还是go&#xff0c;进行选择深圳Python培训 的时候&#xff0c;第一要思考的就是该机构的口碑如何。如果该家机构没有一定的口碑信誉&#xff0c;就等于搬起石头砸了自己的招牌。为什么突然就那么火了&#xff0c;Python的工资待遇&#xff0c;人工智能&am…

python做excel数据分析统计服_Python也能做到Excel那样,条件统计轻松解决工作需求...

此系列文章收录在公众号中&#xff1a;数据大宇宙 > 数据处理 >E-pd 转发本文并私信我"python"&#xff0c;即可获得Python资料以及更多系列文章(持续更新的) 经常听别人说 Python 在数据领域有多厉害&#xff0c;结果学了很长时间&#xff0c;连数据处理都麻烦…

java贪吃蛇_如何用Java还原童年回忆?在线教你完成贪吃蛇小游戏

今天我就从零开始来完成这个小游戏&#xff0c;完成的方式也是一步一步的添加功能这样的方式来实现。额&#xff0c;不好意思&#xff0c;放错了&#xff0c;重来第一步完成的功能&#xff1a;写一个界面大家见到的贪吃蛇小游戏&#xff0c;界面肯定是少不了的。因此&#xff0…

jtextpane设置不能选中_在Bridge cc中不能使用camera raw 的编辑功能,解决方法

有时我们在Bridge cc中想对raw文件进行处理&#xff0c;这时需要启动camera raw功能&#xff0c;可是当我们启用时却显示不能编辑&#xff0c;下面说下如何启动使用camera raw 的编辑功能1.打开一张raw格式文件&#xff0c;在文件菜单或者右键选择在camera raw中打开&#xff0…

android icon命名规则,安卓手机的APP图标尺寸规范和图标命名规范

安卓手机的APP图标尺寸规范和图标命名规范点击查看原文android图标包括&#xff1a;程序启动图标、底部菜单图标、弹出对话框顶部图标、长列表内部列表项图标、底部和底部tab标签图标。1、安卓程序启动图标尺寸&#xff1a;ldpi(120dpi)小屏幕mdpi(160dpi)中屏幕hdpi(240dpi)大…

opencv python教程简书_Python-OpenCV —— 基本操作一网打尽

OpenCV是一个基于BSD许可&#xff08;开源&#xff09;发行的跨平台计算机视觉库&#xff0c;可以运行在Linux、Windows、MacOS操作系统上。它轻量级而且高效——由一系列 C 函数和少量C类构成&#xff0c;同时提供了Python、Ruby、MATLAB等语言的接口&#xff0c;实现了图像处…

opengles 顶点数组 android,OpenGLES顶点属性、顶点数组和缓冲区对象

顶点属性数据可以用一个顶点数组对每个顶点指定&#xff0c;也可以将一个常量值用于一个图元的所有顶点OpenGLES支持最少16个顶点属性。准确查询顶点数量方法如下&#xff1a;GLint maxVertexAttribs;glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);一、指定顶点…

java 实体类 临时注解_JPA:Java持久层API--配置流程

一、JPA概述1.1 JPA是什么JPA &#xff08;Java Persistence API&#xff09; Java持久化API。是一套Sun公司 Java官方制定的ORM 方案,是规范&#xff0c;是标准 &#xff0c;sun公司自己并没有实现 关注点&#xff1a; ORM &#xff0c;标准 概念 &#xff08;关键字&#xf…

android新架构,Android新架构组件 LifeCycles 简介

一、前言为了使开发者能尽快在 Android 平台上开发出高质量的项目&#xff0c;Android 官方推出了 Android Jetpack 项目&#xff0c;旨在从基础&#xff0c;架构&#xff0c;行为以及界面 4 大方面体系化地为我们提供组件级别的支持。当然&#xff0c;在实际开发过程中&#x…

领域驱动设计 pdf_什么是领域驱动设计?

什么是领域驱动设计&#xff1f;你可能使用领域驱动设计(DDD)开发了一些项目。你可能很满意&#xff0c; 使用领域模型来开发领域业务。并且得意地展示给你的同事看&#xff0c;他们会说“666”。但有的时候你使用领域模型你总觉得哪儿有点不对劲。你会嘀咕你可能遗漏了什么。 …

Android四级缓存,RecyclerView 源码四级缓存原理

入口我们从使用功能上去读取源码&#xff0c;通常的用法是这个样子-> 我们设置layoutmanager&#xff0c;GridLayouManager 继承LinearLayoutManager&#xff0c;所以我们就LinearLayoutManager 为基准查看rv.layoutManager GridLayoutManager(this,5)rv.addItemDecoration…

shell脚本发邮件内容html,[转]Shell脚本中发送html邮件的方法

作为运维人员&#xff0c;免不了要编写一些监控脚本&#xff0c;并将监控结果及时的发送出来。那么通过邮件发送是比较常用的一种通知方式了。通常的&#xff0c;如果需要发送的内容是简单的文本文件&#xff0c;那么使用/bin/mailx就可以了&#xff0c;但是如果想要发送更复杂…

HTML打开网页拒绝访问,192.168.1.1拒绝访问怎么办?

问&#xff1a;为什么设置路由器时&#xff0c;在浏览器中输入192.168.1.1&#xff0c;结果显示拒绝访问&#xff0c;这个问题怎么解决&#xff1f;答&#xff1a;如果是在设置路由器的时候&#xff0c;登录192.168.1.1被拒绝访问&#xff0c;多半是你自己操作有问题导致的&…