6-MQ篇 RabbitMQ

简介: acascaca

01- 你们项目中哪里用到了RabbitMQ ?

我们项目中很多地方都使用了RabbitMQ , RabbitMQ 是我们项目中服务通信的主要方式之一 , 我们项目中服务通信主要有二种方式实现 :

  1. 通过Feign实现服务调用
  2. 通过MQ实现服务通信

基本上除了查询请求之外, 大部分的服务调用都采用的是MQ实现的异步调用 , 例如 :

  1. 发布内容的异步审核
  2. 验证码的异步发送
  3. 用户行为数据的异步采集入库
  4. 搜索历史记录的异步保存
  5. 用户信息修改的异步通知(用户修改信息之后, 同步修改其他服务中冗余/缓存的用户信息)
  6. 静态化页面的生成
  7. MYSQL和Redis , ES之间的数据同步
  8. ....

02- 为什么会选择使用RabbitMQ ? 有什么好处 ?

选择使用RabbitMQ是因为RabbitMQ的功能比较丰富 , 支持各种消息收发模式(简单队列模式, 工作队列模式 , 路由模式 , 直接模式 , 主题模式等) , 支持延迟队列 , 惰性队列而且天然支持集群, 保证服务的高可用, 同时性能非常不错 , 社区也比较活跃, 文档资料非常丰富

使用MQ有很多好处:

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速
  • 故障隔离:服务没有直接调用,不存在级联失败问题
  • 调用间没有阻塞,不会造成无效的资源占用
  • 耦合度极低,每个服务都可以灵活插拔,可替换
  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

使用MQ也有很多缺点:

  • 架构复杂了,业务没有明显的流程线,不好管理
  • 需要依赖于Broker的可靠、安全、性能

03- 使用RabbitMQ如何保证消息不丢失 ?

消息从发送,到消费者接收,会经理多个过程 , 其中的每一步都可能导致消息丢失

针对这些问题,RabbitMQ分别给出了解决方案:

  • 消息发送到交换机丢失 : 发布者确认机制publisher-confirm消息发送到交换机失败会向生产者返回ACK , 生产者通过回调接收发送结果 , 如果发送失败, 重新发送, 或者记录日志人工介入
  • 消息从交换机路由到队列丢失 : 发布者回执机制publisher-return消息从交换机路由到队列失败会向生产者返回失败原因 , 生产者通过回调接收回调结果 , 如果发送失败, 重新发送, 或者记录日志人工介入
  • 消息保存到队列中丢失 : MQ持久化(交换机持久化, 队列持久化 , 消息持久化)
  • 消费者消费消息丢失 : 消费者确认机制 , 消费者失败重试机制

通过RabbitMQ本身所提供的机制基本上已经可以保证消息不丢失 , 但是因为一些特殊的原因还是会发送消息丢失问题 , 例如 : 回调丢失 , 系统宕机, 磁盘损坏等 , 这种概率很小 , 但是如果想规避这些问题 , 进一步提高消息发送的成功率, 也可以通过程序自己进行控制

设计一个消息状态表 , 主要包含 : 消息id , 消息内容 , 交换机 , 消息路由key , 发送时间, 签收状态等字段 , 发送方业务执行完毕之后 , 向消息状态表保存一条消息记录, 消息状态为未签收 , 之后再向MQ发送消息 , 消费方接收消息消费完毕之后 , 向发送方发送一条签收消息 , 发送方接收到签收消息之后 , 修改消息状态表中的消息状态为已签收 ! 之后通过定时任务扫描消息状态表中这些未签收的消息 , 重新发送消息, 直到成功为止 , 对于已经完成消费的消息定时清理即可 !

04- 消息的重复消费问题如何解决的 ?

在使用RabbitMQ进行消息收发的时候, 如果发送失败或者消费失败会自动进行重试, 那么就有可能会导致消息的重复消费 , 具体的解决方案其实非常简单, 为每条消息设置一个唯一的标识id , 将已经消费的消息记录保存起来 , 后期再进行消费的时候判断是否已经消费过即可 , 如果已经消费过则不消费 , 如果没有消费过则正常消费

05- 如果有100万消息堆积在MQ , 如何解决 ?

解决消息堆积有三种思路:

  • 提高消费者的消费能力 使用多线程消费
  • 增加更多消费者,提高消费速度 使用工作队列模式, 设置多个消费者消费消费同一个队列中的消息
  • 扩大队列容积,提高堆积上限 使用RabbitMQ惰性队列

06- RabbitMQ如何保证消费的顺序性 ?

一个队列只设置一个消费者消费即可 , 多个消费者之间是无法保证消息消费顺序性的

07- RabbitMQ的延迟队列有了解过嘛 ?

RabbitMQ的延迟队列有二种实现方案 :

  1. 使用消息过期TTL + 死信交换机
  2. 使用延迟交换机插件
相关文章
|
6天前
|
Java Go 开发者
IDEA开发常用的快捷键
IntelliJ IDEA常用快捷键汇总:涵盖代码生成(如main、sout)、编辑(复制、删除、重命名)、导航(跳转、查找)、格式化、代码阅读及版本控制等高频操作,提升开发效率。熟练掌握可显著优化编码体验,是Java开发者必备技能。
132 1
|
6天前
|
Oracle Java 关系型数据库
Java命名规范
Java命名规范涵盖包、类、方法、变量等命名规则。包名全小写,类名首字母大写采用驼峰法,接口常用形容词,抽象类以Abstract/Base开头,异常类以Exception结尾,方法名小写驼峰,常量全大写用下划线分隔,枚举值按常量规范命名,提升代码可读性与一致性。
101 0
|
6天前
经典题:求一个数是否为质数
介绍质数判断与自幂数概念:质数为仅被1和自身整除的大于1的自然数;自幂数是n位数等于各位数字n次幂之和,如水仙花数(三位)、四叶玫瑰数(四位)等,体现数字的独特数学之美。(239字)
48 1
|
6天前
|
Java
经典题:贪吃蛇
一款基于Java Swing实现的贪吃蛇小游戏,通过方向键控制蛇移动,吃食物成长,撞墙或撞自身则游戏重置。代码结构清晰,适合学习GUI编程与游戏逻辑设计。
47 0
|
9天前
|
存储 安全 编译器
C++数据类型:
C++基本数据类型包括bool、char、int、float、double等,支持signed、unsigned、short、long修饰。wchar_t用于宽字符,typedef可为类型定义别名,enum定义枚举常量。支持static_cast、dynamic_cast、const_cast和reinterpret_cast四种类型转换,实现安全或强制类型变换。
52 1
|
9天前
|
存储 C++
C++变量类型
C++变量类型包括基本类型如bool、char、int、float、double等,支持整数、浮点数、字符和布尔值的存储。还包含指针、数组、结构体、类、共用体等复合类型。变量命名由字母、数字、下划线组成,首字符须为字母或下划线。支持变量声明与定义分离,局部变量需显式初始化,静态变量自动初始化为0。
49 1
|
9天前
|
C++
C++变量作用域
C++变量作用域分为局部、全局、块和类作用域。局部变量在函数内定义,仅内部可用;全局变量在所有函数外定义,整个程序可访问;块作用域变量存在于代码块内;类作用域变量属于类成员。同名时,内层作用域覆盖外层。全局变量自动初始化,局部变量需手动初始化。
37 1
|
10天前
|
监控 NoSQL 数据可视化
|
9天前
|
SQL 前端开发 Java
|
9天前
|
JavaScript 前端开发 关系型数据库

热门文章

最新文章