zoukankan      html  css  js  c++  java
  • RabbitMQ 整理

    RabbitMQ 整理

    一、概述

      RabbitMq是一种消息队列技术,最大的特点是实现了服务之间的高度解耦。因为消费并不需要确保提供方存在,只要消息传过来就行了。

    二、为什么要使用rabbitmq

    1、在分布式系统下具备异步、削峰、负载均衡等功能

    2、拥有持久化机制,进程消息,队列中的信息也可以保存下来

    3、实现消费者和生产者之间的解耦。

    4、在高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,利于数据库的操作。

    5、可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单。

    三、使用rabbitmq的场景

    服务间异步通讯

    顺序消费

    定时任务

    请求削峰

    四、如何确保消息正确地发送至Rabbitmq?如何确保消息接收方消费了消息

    发送方确认模式confirm

    1. 发送方发送前, 将要发送到rabbitmq中的数据, 发送到的目标交换器名称目标队列名称等信息存入redis中一份

    2. 发送将数据发送到rabbitmq服务器

    3. rabbitmq服务器接收到数据后会返回接收成功的消息给发送方

    4. 发送方接收到rabbitmq服务器返回的发送成功的消息后, 将redis中保存的数据删除

    5. 如果rabbitmq服务器宕机, 过一段时间发送方会接收到超时的异常信息, 捕获后从redis中从新获取之前保存的发送的内容, 发送的目标交换器名称和目标队列名称等信息, 从新发送数据给rabbitmq服务器

    6. 如果rabbitmq服务器依然宕机, 则一直重复上面的流程发送, 保证数据一定不会丢失

    接收方确认机制 ack

    1. mq服务器将数据发给接收方

    2. 接收方接收到数据后做业务操作

    3. 捕获业务操作代码中的异常

    4. 如果没有捕获到异常, 手动给mq返回消息, 说我接收到了, mq服务器会将给我发送的数据从队列中删除

    5. 如果捕获到异常, 手动给mq返回消息, 说我没有接收到, mq服务器会将刚才给我发送的数据重新发送.

    五、如何避免消息重复投递或重复消费

      在消息生产时,MQ 内部针对每条生产者发送的消息生成一个 inner-msg-id,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列;

      在消息消费时,要求消息体中必须要有一个 bizId(对于同一业务全局唯一,如支付 ID、订单 ID、帖子 ID 等)作为去重的依据,避免同一条消息被重复消费。
    六、消息基于什么传输
      由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制。
    七、消息如何分发?
      若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。通过路由可实现多消费的功能
    8、消息怎么路由?
      通过交换机和队列的绑定来实现路由。
     
    fanout:如果交换器收到消息,将会广播到所有绑定的队列上
    direct:如果路由键完全匹配,消息就被投递到相应的队列
    topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic 交换器时,
    可以使用通配符
    9、如何确保消息不丢失?
      消息持久化,当然前提是队列必须持久化RabbitMQ 确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件,当发布一条持久性消息到持久交换器上时,Rabbit 会在
    消息提交到日志文件后才发送响应。一旦消费者从持久队列中消费了一条持久化消息,RabbitMQ 会在持久化日志中把这条消息标记为等待垃圾收集。如果持久化消息在被消费之前 RabbitMQ 重启,那么 Rabbit 会自动重建交换器和队列(以及绑定),并重新发布持久化日志文件中的消息到合适的队列。
    10、使用 RabbitMQ 有什么好处?
    1、服务间高度解耦
    2、异步通信性能高
    3、流量削峰
    12、mq 的缺点
    系统可用性降低
    系统引入的外部依赖越多,越容易挂掉
    本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一MQ 挂了咋整?MQ 挂了,整套系统崩溃了,你不就完了么。
    系统复杂性提高
    一致性问题
    A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
    13、使用rabbitmq完成超时任务
    在保存订单的时候,将订单id作为消息发送到rabbitmq延时队列中,如果超时了,会成为死信,发送到死信交换器,死信交换器中的订单会发送到死信队列。写个微服务监听私信队列,获取超时的订单号,可以执行一些业务逻辑。
    14、rabbitmq模式
    fanout模式---》广播模式
    • 需要自定义交换机和队列并且完成绑定

    • 生产者只需要发送一次消息,那么与交换机绑定的队列都可以接收到消息

    direct --》路由键模式/点对点模式
    • 需要自定义交换机和队列并且完成绑定,而且需要设置routingKey

    • 生产者发送消息到交换机后,交换机会根据发送时指定的routingKey将消息路由至绑定时设置的routingKey队列,穿的时候要把routingkey一块传过来,没有消息会丢失

    5. Topic模式----》主题模式/通配符模式
    • 需要自定义交换机和队列并且完成绑定,而且需要设置routingKey

    • "#" 匹配大于等于零个词

    • “*” 匹配一个词

  • 相关阅读:
    N、Z、Q、R 分别代表什么
    Android常用代码-监听网络状态
    完整的android use SSL发送邮件
    android 发送邮件相关文章
    Spring RMI的实现原理
    spring+quartz配置
    Quartz配置表达式
    singleton容器
    Spring学习-框架概览
    [Shader2D]漩涡效果
  • 原文地址:https://www.cnblogs.com/gushiye/p/13997149.html
Copyright © 2011-2022 走看看