rocketmq的面试题及原理
消息队列怎么避免重复消息
消息队列一般都有重试机制,或者生产者多次发送。
所以需要保证消费者接口幂等性保障:
比如可以使用redis的setnx。
接口幂等性
一锁、二判断、三更新
加分布式锁,判断状态机,更新至持久化的数据源中。
rocketmq如何保证消息的可靠性传输
需要生产者、broker、消费者共同配置。
生产者使用同步或异步发送,重试。
broker使用多主多从架构,nameServer使用集群,broker采用同步复制及同步刷盘。硬盘使用RAID10。
消费者消费成功之后返回正确的ACK,异常返回未消费ack。
消息发生大量堆积应该怎么处理
消费者可以消费,非bug
1.增加消费者数量
2.如果是消费者代码慢,优化代码。
3.降低生产者生产的速度。
4.清理过期数据,比如有一些消息已经处理过了或者过期了。
5.调整消费者的配置参数,提高消费者的效率。
6.增加topic队列数。
消费者bug, 堆积消息
没有做好监控,做好监控,提前报警。
1.增加消费者,看是否能抗住压力。这种会影响正在运的用户。
2.改变offset,旧的队列直接从最新开始,从旧topic快速读取新的临时topic,新的topic增加多队列数,启动新的消费者消费新topic。
rocketmq如何保障顺序消息的顺序性
rocketmq保障消息队列的顺序。
慎用顺序消息。
生产者
4.0 生产者使用MessageQueueSelector,同一业务ID(比如订单ID)的发送到同一消息队列中。
4.0感觉也不太对。
5.0的文档:
单一生产者 + 串行发送。
比如说有两个订单服务,服务A支付成功,服务B接收到取消订单,因为网络问题有可能取消订单在支付成功之前,这时没有退款,所以需要保证同一订单,要访问一个服务。或者直接支侍时使用支付中,支付中不能取消,不使用顺序消息。
消费者
消费者使用消费模式使用ConsumeMode.ORDERLY 顺序消费模式。
rocketmq的消费逻辑是,申请分布式锁,这时只有这个消费者内的线程可以消费,去申请broker的messageQueue锁,然后只有这个线程可以消费,然后消费者线程去申请broker的processQueue进行加锁,当新增加消费者时,不会把消息重复给新的消费者。
延时消息如何实现的
当消息发送到broker后,根据延时级别存储消息(不能消费),然后使用不同延时级别的定时器把消息改为可以消费。
延时定时器:它只支持:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h这几个时长。
广播消息与集群消息怎么做到的
是消息者设置的消息模式。
当广播消息时,是每个消费者都有offset。
当集群消息时,一个消息队列一个offset。
rocketmq的消息是推还是拉?
Push是服务端主动推送消息给客户端,pull是客户端需要主动到服务端轮询获取数据。
推:及时性比较好。
拉:流处理框架场景下集成使用。
推模式:
推模式其底层的实现还是基于pull实现的,SDK内置了一个长轮询线程,先将消息异步拉取到SDK内置的缓存队列中,再分别提交到消费线程中,触发监听器执行本地消费逻辑。