RocketMQ学习笔记
1.RocketMQ如何保证消息不丢失?
1.1 Producer端如何保证消息不丢失
- 采取send()同步发消息,发送结果是同步感知的。
- 发送失败后可以重试,设置重试次数。默认3次。
producer.setRetryTimesWhenSendFailed(10);
- 集群部署,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他Broker上。
1.2 Broker端如何保证消息不丢失
- 修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。
flushDiskType = SYNC_FLUSH
- 集群部署,主从模式,高可用。
1.3 Consumer端如何保证消息不丢失
- 完全消费正常后在进行手动ack确认。
2.RocketMQ 是如何保证数据的高容错性的?
- 在不开启容错的情况下,轮询队列进行发送,如果失败了,重试的时候过滤失败的Broker
- 如果开启了容错策略,会通过RocketMQ的预测机制来预测一个Broker是否可用
- 如果上次失败的Broker可用那么还是会选
择该Broker的队列 - 如果上述情况失败,则随机选择一个进行发送
- 在发送消息的时候会记录一下调用的时间与是否报错,根据该时间去预测broker的可用时间
源码:
org.apache.rocketmq.client.latency.MQFaultStrategy#selectOneMessageQueue()
3. 定时消息
- 定时消息:Producer将消息发送到消息队列RocketMQ版服务端,但并不期望立马投递这条消息,而是推迟到在当前时间点之后的某一个时间投递到Consumer进行消费,该消息即定时消息。
- 希望消息在特定的时间间隔后再被消息
- 目前只支持特定的时间间隔
- 延迟消息会先写入系统内置Topic(SCHEDULE_TOPIC_XXXX),后续由调度任务消费延迟消息,并写入真正Topic
- 延迟队列的核心思路: 【利用中间队列临时存储】—>所有的延迟消息由producer消息发憷之后,都会存放在一个topic下 (SHCEDULE_TOPIC_XXXX), 不同的延迟级别对应不同的队列序号,当延迟时间到了之后,由定时线程读取转换为普通的消息存到真实指定的topic下,此时对于consumer端此消息才可见,从而被consumer消费。
3.1 Q&A:
-
【定时消息如何在服务端保证顺序性?】
delayLevel和queue一一对应,同一个延迟队列按顺序消费。
-
【broker如何调度保证定时消息能及时被消费?】
通过计算剩余时间确定调度延迟时间,当没有消息时频繁的调度检查新消息。
3.2 使用和配置
-
关键点在于Producer生产者需要给消息设置特定延时级别,消费端代码与正常消费者没有差别。设置消息延时级别的方法是
setDelayTimeLevel()
,目前RocketMQ不支持任意时间间隔的延时消息,只支持特定级别的延时消息,时间间隔配置配置代码在MessageStoreConfig#messageDelayLevel中,默认值1s 5s 10s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h,空格分隔,支持4种时间单位:s、m、h