RabbitMQ

1.为啥要用mq?优点是啥?

  • 异步通讯 ,帮助我们微服务的解耦,降低我们业务场景的复杂度

  • 整个耦合执行效率解耦后 执行效率变高

  • 吞吐量高, 但是消费者能力不足时,可能会造成消息堆积

  • 流量削峰, 拿时间换空间

  • mq代码层面执行发送消息服务 执行效率是很高的

2.怎么保证消息发送到了mq?又如何保证消费者接收到消息?(如何保证消息不丢失?)

  • 生产者保证消息发送到mq, 开启confirm确认模式

    • 消息的生产者 通过channel的confirm模式 进行消息的发送

    • 发送到queue当中后,queue要给消息的生产者一个ack回告

    • 消息的生产者收到ack之后,才确认消息发送到我们的消息队列

    • 如果mq开启了持久化,消息会在持久化之后给消息的生产者一个ack回告

  • 消费者保证接收消息

    • 消费者从队列当中接收到消息

    • 消费者默认情况是自动进行消息的回告,回告队列消息已确认

    • 队列收到回告,删除被消费消息

    • 将自动回告修改为手动回告,放在处理消息之后

       

3.消息队列里的消息丢了怎么办?怎么解决?消费者消息丢失怎么办?

  • 消息的发送者没有收到队列的回告 消息持久化的回告 消息的发送者在一定内未收到 会重新发送消息

  • mq内部 会给消息的发送者发送的每条消息定义一个唯一的msg_id 就是为了防止消息的重复发送

  • 消费者

    • 消费者在收到消息且自动进行消息确认的回告,还未进行消息的处理,当前消费者宕机,可能会造成消息丢失,因为在给队列回告时,队列已经将消息给删除了

    • 取消消息确认的自动回告,在我们的消费逻辑执行完成之后,再进行手动回告,队列再进行消息的删除

4.有了解过消息幂等吗?作用是啥?如何做消息幂等?(重复消费怎么做?)

  • 对于重复消息,我们仅处理一次。这个过程就是保证消息幂等。

  • 场景:消息的消费逻辑是进行库存的扣减,如果重复消费,会造成超卖/负卖。

  • 例子:工单 定义消息的唯一标识(bizId)

    • 工单编号+状态+时间 100_1_2022-12-03

  • 消息的发送者和消息的消费者 需定义一个业务上的唯一id

  • 消息的发送者发送的消息的时候 协议中 是要带你们定义的唯一标识

  • 消费者在解析时,进行唯一id的去重执行 (执行过的消息再次接收时进行丢弃)

    • 建议采用redis进行 唯一id的存储 在每次消费的时候 去redis查询一下 是否存在相同的id

      • 如果有 消费者把消息丢弃掉(return掉)

      • 如果没有 才正常执行 执行完 将唯一消息id 存储在redis中

5.RabbitMq的工作模式(消息模型)有哪些?

  • 简单队列(simple Queue)

  • 工作队列(work Queue)

  • 基于交换机的发布订阅模式

    • Fanout(广播)

    • Direct(路由)

    • Topic(通配符)

6.消息持久化的条件有了解吗?(如何做消息的持久化?)

  • 声明队列必须设置持久化 durable 设置为 true

  • 消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)

  • 消息已经到达持久化交换器

  • 消息已经到达持久化队列

7.死信队列有了解过吗,项目中如何使用?一般作用什么场景?

  • 什么消息会被投递到死信队列?

    • 你得配置了死信队列(普通队列),死信队列下绑定了对应的死信消费者

    • 消息被拒绝

    • 消息TTL过期

    • 队列达到最大长度

       

  • 延迟消息场景,延迟队列

    • 即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费

  • 使用场景

    • 订单在十分钟之内未支付则自动取消

    • 用户注册成功后,如果三天内没有登陆则进行短信提醒

    • 用户发起退款,如果24h内没有得到处理则通知相关客服人员/直接退款

    • 预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议(飞书,钉钉,企业微信)

8.消息积压怎么处理?

  • 当消费者消费消息的速率<生产者生产消息的速率时,会造成消息积压

    • 如果上述问题长时间存在,会存在消息溢出的问题

  • 可以增强消费者消费能力来缓解

    • 通过代码层面的优化来提高单台消费者的消费能力

      • 使用多线程来消费消息

    • 通过增加消费者数量,来提升消费者能力,多加几台消费者服务器

      • 成本增加

  • 可以在消息的生产者之前,进行消息的限流,防止消息积压

    • 可能导致调用方服务失败,或者影响调用方正常的系统逻辑(改变调用策略)

  • 可以手动去释放mq压力

    • 通过手动方式去将积压的消息 给丢弃掉

    • 需要记录丢弃的消息 在消息非积压时 将丢弃的消息 重新投递到队列当中

    • 消息延迟了 比正常情况下 时间要久

    • 保证消息的最终一致性

  • 增加队列存储能力

    • 弹性扩容

    • 镜像集群模式

9.mq是如何去做的负载均衡?

  • producer发送消息的负载均衡:默认会轮询向Topic的所有queue发送消息,以达到消息平均落到不 同的queue上;而由于queue可以落在不同的broker上,就可以发到不同broker上

  • consumer订阅消息的负载均衡:假设有5个队列,两个消费者,则第一个消费者消费3个队列,第二 个则消费2个队列,以达到平均消费的效果。而需要注意的是,当consumer的数量大于队列的数量的 话,多出来的队列不会去消费数据,因此建议consumer的数量小于或者等于 queue的数量,避免不必要的浪费

  • 如何保证消息的最终一致性?(如何保证消息的事务?)

    • 生产者发送一条消息,最终是达到预期的效果

    • 导致最终消息不一致

      • 生产者丢失消息, 消息队列丢失消息,消费者丢失消息

      • 生产者发消息,指定confirm模式,未来,队列会给生产者一个ack回告,以此来保证生产者和消息队列的消息一致性

      • 消息队列声明为持久化

      • 消费者在消费的时候,由于宕机/异常/重复消费,也有可能导致消息不一致

        • 宕机:

          • 补发消息

            • 需要你手动去重新发一下消息

          • 消息自动回告变更为手动回告

        • 异常:

          • 取消消息确认的自动回告,在我们的消费逻辑执行完成之后,再进行手动回告,队列再进行消息的删除

          • 先定义 异常的影响范围

            • 如果你负责的是非常核心的业务,排查是否是因为最近发布导致的 如果是这种情况 回滚到上个代码版本重新发布

            • 如果是非核心业务,看看日志,分析定位一下bug的位置,修改bug,测试,上线

        • 重复消费

          • 保证我们消息幂等,防止消息重复消费

10.队列中的消息能无限制的存储吗? (消息存满了怎么办?)

  • 扩容&&镜像集群

  • 提高消费者的消费能力,降低生产者生产消息的速率,手动回收一些消息,等闲时再将消息投递到我们的队列当中

  • 可以认为是无限制,因为限制取决于机器的内存,但是消息过多会导致处理效率的下降。会将多余的消息存入到磁盘当中,等队列当中有空余的内存,再将消息投递回来,进行消费

11.怎么保证高可用?rabbitmq的集群模式有了解吗?

  • 单机模式(工作场上没有)

    • 本地搭建一个mq的demo

  • 普通集群模式(工作场上可能有)

    • 只有一个队列是存储消息,其他的节点仅仅提供接收消息的服务,提升mq的吞吐量

       

  • 镜像集群模式

    • 单机模式与普通集群模式无法满足高可用,镜像集群模式指定多个节点复制 queue 中的消息做到高可用,但消息之间的同步网络性能开销较大

       

12.你们mq目前tps大概多少?这么大tps你消息队列能存的住吗?如果存不了怎么办?

  • 测试场景下,50 以内

  • 搭建镜像集群

  • 磁盘

13.有没有踩过mq什么坑?(做项目的时候有没有遇到过什么难点?)

  • 消息丢失

    • 由于异常导致消息丢了 但是队列里面消息也删除了 因为你进行了消息确认的自动回告

    • 将自动回告改成了手动回告,在我们代码里面,业务处理完成之后,写了一段代码去手动确认消息消费,这样就能保证我们的消息在消费者中是不丢失的。

      • setReturnsCallBack(); 消费者消息确认机制

        • setConfirmCallBack(); 生产者消息确认机制

      • try{"消费者逻辑"}catch{"重试"}finally{"验证最终结果是否符合预期,报警"}

        • try{"库存减1"}catch{"库存减1"}finally{"查询数据库库存是否减1,如不符合预期,报警"}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值