• RocketMq面试题


    RocketMq运行原理

    RocketMq架构中有四大角色,分别是NameServer、Broker、Producer、Consumer
    NameServer:是一个注册中心,类似于ZooKeeper和SpringCloud中的Eureka,他能够管理Borker和路由信息;为了提高可用性,通常做集群部署,NameServer是去中心化的,没有主节点,所有NameServer节点不进行信息复制
    Broker:消息队列服务器,负责消息的接收、存储和投递;生产者生产消息到Broker,消费者从Broker拉取消息并消费;单个Broker和所有NameServer保持长连接,每30秒向nameServer发送包含Topic配置信息的心跳;broker可以做集群和主从部署,主从架构下如果master主服务器宕机可由slave从服务器提供消费服务,但是slave不能写入消息
    Producer:生产者,进行消息发布;
    发送消息时指定topic和消息二级标签tag,再从NameServer获取关于Broker的路由信息,然后再根据轮询的方法去向Topic中每个队列发送以达到负载均衡的一个效果;发送的时候可以选择同步发送(send)、异步发送(sendAsync)或者单向发送sendOneway()这几种发送消息的方式
    Consumer: 消费者,进行消息消费;
    消费消息时,从NameServer获取到所有的Broker路由信息并选择订阅了的Topic,向Broker发送pull请求获取队列中的消息数据,拉取到消息之后再根据消息中的二级标签tag去选择具体的业务进行处理。支持集群方式和广播方式的消费;集群模式下一条消息发送给一个消费者,广播模式下一条消息发送给一个消费者组中的所有消费者

    消息丢失

    一个消息从生产到最终的消费过程需要经历总共三个阶段,分别是producer的发送端、broker的存储端、以及consumer的消费端;消息丢失可以分为以下三种情况:生产者没有将消息发送到Broker、Broker发生宕机导致内存中的消息丢失、消费者拉取消息之后没有成功消费
    从生产者的角度采取同步发送send()模式,只需要发送消息之后,接收到返回的SendResult响应即可,就可以代表消息发送成功,发送失败重新设置重试3次
    消费者的角度消费成功返回消费状态CONSUME_SUCCES给Broker,消费失败在非业务情况导致的话重新拉取消费
    从Broker角度,可以将消息的保存机制修改为同步刷盘(设置 Broker 的参数 FlushDiskType 来调整你的刷盘策略(ASYNC_FLUSH 或者 SYNC_FLUSH)),在Broker将消息保存到磁盘成功之后再返回响应(不过同步刷盘需要损耗性能,像金融等特定业务场景使用,发送验证码消息等场景不建议使用);还可做Broker集群进行一个主从部署,确保Master宕机之后还有slave提供服务

    重复消费

    给消费者实现幂等,对同一消息的处理结果,执行多次都不变
    1、在生产者发送消息的时候设置一个消费状态字段,消费者消费成功之后将消费状态修改为已消费,每次消费之前检验消息的消费状态判断是否已经消费过
    2、消费者在消费成功之后将消息写入Redis,消费之前在Redis里面判断是否有这条消息,消息没有消费正常写入,消息消费之后无法写入
    3、使用数据库插入法,消费者在消费成功之后将消息写入到数据库中,基于数据库的唯一键来保证数据不会被插入多条

    顺序消费

    RocketMq在主题上是无序的,发送到Topic上不同队列的信息没办法保证先后顺序;只能在队列层面保证,将信息发送到同一队列上
    顺序模式的话有两种,一种是普通顺序一种是严格顺序
    严格顺序指消费者获取到的所有消息都是有序的,但在异常情况下也会保证消息的一个有序性,一台Broker机器出现问题,整个集群都将不可用,系统可用性极低
    普通顺序指消费者通过同一队列获取到的消息是有序的,不同队列获取到的消息是无序的;我们只需要关注部分消息的一个消费顺序,比如同一订单的订单创建、订单支付、订单完成的几个消息保证它们的一个消费顺序;具体的话可以使用hash取模法实现,即订单ID%(取模)队列数量得到该ID的订单在队列列表中的索引,然后将同一订单的消息都发送到该索引位置上的队列中

    如何保证分布式事务

    事务要么都执行要么都不执行,在同一个系统中可以轻松实现,但在分布式架构中很多服务都是部署在不同系统之间的,而且不同服务之间又需要调用,就没有办法去保证这种场景下的事务
    RocketMq使用的是half半消息加上事务反查机制来解决分布式事务问题
    1、消息生产者在事务执行之前发送half半消息给mq服务器
    2、如果事务执行成功,则发送事务提交,否则发送事务回滚
    消息只有在提交之后才投递给消费者,消费者对一开始的half半消息和回滚的消息都是不可见的。
    3、服务端在一段时间后如果一直收不到提交或回滚,则发起事务回查
    4、生产者在收到回查后重新发送事务提交或回滚。

    消息堆积

    1、从生产端的话对生产者实行限流等办法
    2、从消费端的话首先检查是否是消费者出现了大量的消费错误,避免线程卡死等影响消费速度的情况
    3、还可以增加消费者实例以及broker消息队列服务器里的队列数量
    3、比如还可以设置后台定时任务每隔72小时,删除旧的没有使用过的一些消息

  • 相关阅读:
    在RVIZ中显示深度数据
    ASP.NET Core - 缓存之内存缓存(上)
    25、四大函数式接口(消费型接口(Consumer)和供给型接口(Supplier))
    [附源码]Python计算机毕业设计SSM健身网站平台(程序+LW)
    【Linux】JumpServer 堡垒机远程访问
    [附源码]Python计算机毕业设计django学生学习评价与分析系统
    信息检索与数据挖掘 | (五)文档评分、词项权重计算及向量空间模型
    软件工程师真的只是编码吗?不,他有10个隐蔽的工作
    SpringBoot 2.6. 整合springfox 3.0报错问题解决
    WPS/word 表格跨行如何续表、和表的名称
  • 原文地址:https://blog.csdn.net/C2667378040/article/details/134444255