幂等性

概念

用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。 举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常, 此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱 了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误 立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等

消息重复消费

消费者在消费 MQ 中的消息时,MQ 已把消息发送给消费者,消费者在给 MQ 返回 ack 时网络中断, 故 MQ 未收到确认信息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但 实际上该消费者已成功消费了该条消息,造成消费者消费了重复的消息。

解决思路

MQ 消费者的幂等性的解决一般使用全局 ID 或者写个唯一标识比如时间戳 或者 UUID 或者订单消费 者消费 MQ 中的消息也可利用 MQ 的该 id 来判断,或者可按自己的规则生成一个全局唯一 id,每次消费消 息时用该 id 先判断该消息是否已消费过。

消费端的幂等性保障

在海量订单生成的业务高峰期,生产端有可能就会重复发生了消息,这时候消费端就要实现幂等性, 这就意味着我们的消息永远不会被消费多次,即使我们收到了一样的消息。业界主流的幂等性有两种操作:a. 唯一 ID+指纹码机制,利用数据库主键去重, b.利用 redis 的原子性去实现

唯一 ID+指纹码机制

指纹码:我们的一些规则或者时间戳加别的服务给到的唯一信息码,它并不一定是我们系统生成的,基 本都是由我们的业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id 是否存 在数据库中,优势就是实现简单就一个拼接,然后查询判断是否重复;劣势就是在高并发时,如果是单个数 据库就会有写入性能瓶颈当然也可以采用分库分表提升性能,但也不是我们最推荐的方式。

Redis 原子性

利用 redis 执行 setnx 命令,天然具有幂等性。从而实现不重复消费

优先级队列

使用场景

在我们系统中有一个订单催付的场景,我们的客户在天猫下的订单,淘宝会及时将订单推送给我们,如 果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall 商家对我们来说,肯定是要分大客户和小客户的对吧,比如像苹果,小米这样大商家一年起码能给我们创 造很大的利润,所以理应当然,他们的订单必须得到优先处理,而曾经我们的后端系统是使用 redis 来存 放的定时轮询,大家都知道 redis 只能用 List 做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用 RabbitMQ 进行改造和优化,如果发现是大客户的订单给一个相对比较高的优先级, 否则就是默认优先级。

如何添加

队列添加优先级

控制台添加

队列中代码添加优先级

Map<String, Object> params = new HashMap();
params.put("x-max-priority", 10);
channel.queueDeclare("hello", true, false, false, params);

消息添加优先级

AMQP.BasicProperties properties = new
AMQP.BasicProperties().builder().priority(5).build();

注意事项

要让队列实现优先级需要做的事情有如下事情:队列需要设置为优先级队列,消息需要设置消息的优先 级,消费者需要等待消息已经发送到队列中才去消费因为,这样才有机会对消息进行排序

惰性队列

使用场景

RabbitMQ 从 3.6.0 版本开始引入了惰性队列的概念。惰性队列会尽可能的将消息存入磁盘中,而在消 费者消费到相应的消息时才会被加载到内存中,它的一个重要的设计目标是能够支持更长的队列,即支持 更多的消息存储。当消费者由于各种各样的原因(比如消费者下线、宕机亦或者是由于维护而关闭等)而致 使长时间内不能消费消息造成堆积时,惰性队列就很有必要了。

默认情况下,当生产者将消息发送到 RabbitMQ 的时候,队列中的消息会尽可能的存储在内存之中, 这样可以更加快速的将消息发送给消费者。即使是持久化的消息,在被写入磁盘的同时也会在内存中驻留 一份备份。当 RabbitMQ 需要释放内存的时候,会将内存中的消息换页至磁盘中,这个操作会耗费较长的 时间,也会阻塞队列的操作,进而无法接收新的消息。虽然 RabbitMQ 的开发者们一直在升级相关的算法, 但是效果始终不太理想,尤其是在消息量特别大的时候。

两种模式

队列具备两种模式:default 和 lazy。默认的为 default 模式,在 3.6.0 之前的版本无需做任何变更。lazy 模式即为惰性队列的模式,可以通过调用 channel.queueDeclare 方法的时候在参数中设置,也可以通过 Policy 的方式设置,如果一个队列同时使用这两种方式设置的话,那么 Policy 的方式具备更高的优先级。 如果要通过声明的方式改变已有队列的模式的话,那么只能先删除队列,然后再重新声明一个新的。

在队列声明的时候可以通过“x-queue-mode”参数来设置队列的模式,取值为“default”和“lazy”。下面示 例中演示了一个惰性队列的声明细节:

Map<String, Object> args = new HashMap<String, Object>();
args.put("x-queue-mode", "lazy");
channel.queueDeclare("myqueue", false, false, false, args);

在发送 1 百万条消息,每条消息大概占 1KB 的情况下,普通队列占用内存是 1.2GB,而惰性队列仅仅 占用 1.5MB

RabbitMQ-8-其他知识点相关推荐

  1. 【零散知识点总结2】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  2. 【零散知识点总结1】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  3. 【零散知识点总结4】

    大部分来源于网络 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. Zookeeper.Kafka.Elasticsearch.Re ...

  4. 【零散知识点总结3】

    大部分知识点来源于该博主--骆昊 知识点来源于网络,知道的可以在评论区贴上来源喔 <零散知识点总结1> 该文章涉及:Dubbo.HTTP和HTTPS.Mybatis.Hibernate. ...

  5. RabbitMQ入门指南:初学者也能读懂的教程

    文章目录 1.消息队列 1.1.MQ的相关概念 1.1.1.什么是MQ 1.1.2.为什么要使用MQ 流量削峰 应用解耦 异步处理 1.1.3.MQ的分类 ActiveMQ KafKa RocketM ...

  6. 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

    [MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...

  7. active mq topic消费后删除_【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

    [MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...

  8. RabbitMQ官方文档知识点总结合集+代码注释(中文+Java版)

    全文代码.MD格式文档的github连接(求star~):https://github.com/Ruoyi-Chen/RabbitMQ-demos 文章目录 全文代码.MD格式文档的github连接( ...

  9. 【RabbitMQ】回顾下RabbitMQ知识点,还记得哪些?

    回顾下RabbitMQ知识点,还记得哪些? 什么是RabbitMQ? 为什么要选择RabbitMQ,不选其他MQ? 使用MQ可以解决那些问题? RabbitMQ如何保证消息的有序性? 如何防止MQ消息 ...

  10. RabbitMQ知识点+面试题总结

    RabbitMQ知识点+面试题总结 一.MQ的相关概念 1.什么是MQ? 2.为什么使用MQ?MQ的优点? 1)应用解耦 2)异步处理 3)流量削锋 3.常见的MQ分类 1)ActiveMQ 2)Ka ...

最新文章

  1. 清华姚班校友马腾宇斩获斯隆奖!与鬲融师承一脉,李飞飞点赞祝贺
  2. 什么是爱?什么是幸福?
  3. c语言图片见水印,[求助]C语言 bmp文件加上水印
  4. kotlin获取属性_Kotlin程序获取系统名称
  5. git 修改commit_结合IDEA与命令行,解决常用git操作与特殊情况的最佳实践
  6. VS2010下安装Cocos2dx完整教程(原)
  7. 101.接收上游响应的缓存处理流程
  8. mysql 随机取不重复数据_随机生成不重复数字,想做Excel抽奖器你必须掌握!
  9. css样式背景图片设置透明度,css如何设置背景图片的透明度
  10. windos无法对计算机进行,电脑提示windows无法完成格式化如何解决
  11. 【阿里云云计算工程师ACP认证】什么是ACP
  12. 奥赛 兔子繁殖 c语言,兔子繁殖问题(斐波拉契)
  13. 既然android service是运行在主线程中的,那service还有什么用?
  14. 【数论-Lucas定理】
  15. 关于买房的后的人生感悟
  16. android Button 和 TabLayout 英文自动大写的问题
  17. uniapp点击回复弹起键盘输入
  18. 计算机基础职中,职业高中计算机基础试卷一
  19. [转载]当你的女友改名为玛丽,你怎能送她一首《菩萨蛮》?——台湾诗人余光中! (2013-08-21 20:55:03)
  20. SQL 难点解决:集合及行号

热门文章

  1. 苹果iOS 15正式版发布,iOS 15 兼容所有运行 iOS 14 的 iPhone
  2. C++设计模式(20)——迭代器模式
  3. 生活中的年月日相关问题
  4. SpringBoot多数据源配置事务
  5. 最新字节跳动面试题与答案: 无序数组的中位数 (快排思想O(N) 时间复杂度)
  6. DS18B20与LCD1602温度测量显示案例
  7. linux内核mount过程超复杂的do_mount()、do_loopback()、attach_recursive_mnt()、propagate_mnt()函数详解
  8. 零售店库存管理有哪些方法?有哪些零售店库存管理软件可以使用?
  9. 谁给俺介绍个女朋友?俺谢谢了!(2)
  10. THINPAD E480可以支持超过32G内存,最大可以64G?