前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RocketMQ高级特性②

RocketMQ高级特性②

原创
作者头像
会洗碗的CV工程师
发布2024-05-08 08:54:05
2010
发布2024-05-08 08:54:05
举报
文章被收录于专栏:消息中间件

一、顺序消息

消息有序指的是按照消息的发送顺序来消费(FIFO)。RocketMQ可以保证消息有序,消息有序分为部分有序和全局有序。全局有序是指某个Topic下的所有消息都要保证顺序;部分顺序消息只要保证每一组消息被顺序消费即可。

如果要实现全局顺序消息,那么只能使用一个队列,一个生产者,这会严重影响性能。

因此,我们常说的顺序消息通常指部分顺序消息。

顺序消费的原理解析,在默认的情况下消息发送会采取轮询方式把消息发送到不同的分区队列;而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的。

二、消息重试

  1. 生产端重试

例如由于网络原因导致生产者发送消息到MQ失败,即发送端没有收到Broker的ACK,导致最终Consumer无法消费消息,此时RocketMQ会自动进行重试。

代码语言:java
复制
// 同步发送消息,如果5秒内没有发送成功,则重试3次
DefaultMQProducer producer = new
DefaultMQProducer("DefaultProducer");
producer.setRetryTimesWhenSendFailed(3);
producer.send(msg, 5000L);

  1. 消费端重试

同样的,由于网络原因,Broker发送消息给消费者后,没有受到消费端的ACK响应,所以Broker又会尝试将消息重新发送给Consumer,在实际开发过程中,我们更应该考虑的是消费端的重试。消费端的消息重试可以分为顺序消息的重试以及无序消息的重试。

  • 顺序消息重试

对于顺序消息,当消费者消费消息失败后,消息队列 RocketMQ会自动不断进行消息重试(每次间隔时间为 1 秒),这时,应用会出现消息消费被阻塞的情况。因此,在使用顺序消息时,务必保证应用能够及时监控并处理消费失败的情况,避免阻塞现象的发生

  • 无序消息重试

对于无序消息(普通、定时、延时、事务消息),当消费者消费消息失败时,可以通过设置返回状态达到消息重试的结果。

  • 最大重试次数

消息消费失败后,可被消息队列RocketMQ重复投递的最大次数。

TCP协议无序消息重试时间间隔:

消费失败后重新配置方式

需要在消息监听器接口的实现中明确进行配置(三种方式任选一种):

  1. 返回 ConsumeConcurrentlyStatus.RECONSUME_LATER; (推荐)
  2. 返回 Null
  3. 抛出异常

三、延迟消息

Producer将消息发送到消息队列RocketMQ服务端,但并不期望立马投递这条消息,而是延迟一定时间后才投递到Consumer进行消费,该消息即延时消息。

消息生产和消费有时间窗口要求,例如在电商交易中超时未支付关闭订单的场景,在订单创建时会发送一条延时消息。这条消息将会在30分钟以后投递给消费者,消费者收到此消息后需要判断对应的订单是否已完成支付。如支付未完成,则关闭订单。如已完成支付则忽略。通过消息触发一些定时任务,例如在某一固定时间点向用户发送提醒消息。

定时消息会暂存在名为SCHEDULE_TOPIC_XXXX的topic中,并根据delayTimeLevel存入特定的queue,queueId = delayTimeLevel –1,即一个queue只存相同延迟的消息,保证具有相同发送延迟的消息能够顺序消费。broker会调度地消费SCHEDULE_TOPIC_XXXX,将消息写入真实的topic。

代码语言:java
复制
//
org/apache/rocketmq/store/config/MessageStore
Config.java
private String messageDelayLevel = "1s 5s 10s
30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h
2h";

四、消息查询

在实际开发中,经常需要查看MQ中消息的内容来排查问题。RocketMQ提供了三种消息查询的方式,分别是按Message ID、Message Key以及Unique Key查询。

代码语言:java
复制
//返回结果
SendResult [
sendStatus=SEND_OK,
msgId=C0A801030D4B18B4AAC247DE4A0D0000,
offsetMsgId=C0A8010300002A9F000000000007BEE9,
messageQueue=MessageQueue [topic=TopicA,
brokerName=broker-a, queueId=0],
queueOffset=0]

1. 按MessageId查询消息

Message Id 是消息发送后,在Broker端生成的,其包含了Broker的地址、偏移信息,并且会把Message Id作为结果的一部分返回。Message Id中属于精确匹配,代表唯一一条消息,查询效率更高。

2. 按照Message Key查询消息

消息的key是开发人员在发送消息之前自行指定的,通常把具有业务含义,区分度高的字段作为消息的key,如用户id,订单id等。

3. 按照Unique Key查询消息

除了开发人员指定的消息key,生产者在发送发送消息之前,会自动生成一个UNIQ_KEY,设置到消息的属性中,从逻辑上唯一代表一条消息。

消息在消息队列RocketMQ中存储的时间默认为3天(不建议修改),即只能查询从消息发送时间算起3天内的消息,三种查询方式的特点和对比如下表所述:

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、顺序消息
  • 二、消息重试
  • 三、延迟消息
  • 四、消息查询
相关产品与服务
消息队列 CMQ
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档