MQ系列1:消息中间件执行原理

MQ系列2:消息中间件的技术选型

MQ系列3:RocketMQ 架构分析

MQ系列4:NameServer 原理解析

MQ系列5:RocketMQ消息的发送模式

MQ系列6:消息的消费

MQ系列7:消息通信,追求极致性能

MQ系列8:数据存储,消息队列的高可用保障

MQ系列9:高可用架构分析

MQ系列10:如何保证消息幂等性消费

MQ系列11:如何保证消息可靠性传输

MQ系列12:如何保证消息顺序性

MQ系列13:消息大量堆积如何解决

1 背景

在互联网业务的实际应用场景中,消息的延时处理是非常必要的。例如,在金融交易系统中,某些交易的确认可能需要一段时间才能完成。又如,在物流跟踪系统中,货物的运输状态需要一段时间才能更新。而MQ作为中间件的角色专门来处理消息媒介,实际也具备了使用消息的延时处理来保证信息的及时性的能力。

这边举两个具体的例子:

  • 火车票订购,提交了订单就把车票给占位了,这时候可以发送一个延时确认的消息,15m 未付款,就要把该车票释放,这样其他人就可以购买了。
  • 购买电影票,可以发送一个核销检查消息,在电影开场前15分钟就无法退票了。

既然消息延迟处理的使用场景这么常见,那我们就要详细来分析下怎么使用MQ来实现,这边以RocketMQ为技术选型。

2 消息延时处理原理

RocketMQ的消息延时处理是通过预定义的消息延时级别和延时队列来实现的。在发送消息时,生产者可以设置一个延时级别,该消息将会被延迟一段时间后才能被消费者消费。RocketMQ默认提供了18个延时级别,每个级别对应不同的延迟时间。

所以延时时间并不是随意指定的,Rocket源码中指定的18种等级如下:

// org/apache/rocketmq/store/config/MessageStoreConfig.java 的第198行
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
  • RocketMq不支持任意时间延时,需设置固定的延时等级,从1s到2h分别对应着等级1到18
  • 可以使用setDelayTimeLevel(int level) 方法设置延时等级,level 从 0 开始

在RocketMQ中,每个Broker都设置了一个延时队列,用于存储延时消息。当消息的延时时间到达时,该消息将会被自动转移到普通的消息队列中,等待消费者的消费。这种方式可以有效地避免因为网络延迟或者消费者处理速度慢而导致消息的延迟。

3 消息延时处理实战

使用RocketMQ的消息延时处理非常简单。在发送消息时,生产者只需要设置一个延时级别,然后将消息发送到RocketMQ即可。例如:

public class DelayProducerApplication {
public static void main(String[] args) throws InterruptedException, RemotingException, MQClientException, MQBrokerException , UnsupportedEncodingException {
// 1、创建生产者producer,并指定生产者组名为 example_group_name
DefaultMQProducer producer = new DefaultMQProducer("example_group_name");
// 2、指定NameServer的地址,以获取Broker路由地址
producer.setNamesrvAddr("127.0.0.1:9876");
// 3、启动生产者producer
producer.start();
// 4、创建消息,并指定Topic,Tag和消息体
Message msg = new Message("example_topic","example_key", "试一试延迟30s发送的消息".getBytes("UTF-8"));
// 5、设置延时等级3,对应30s,所以这个消息在30秒之后发送
msg.setDelayTimeLevel(3);
// 6、发送消息到一个Broker
SendResult sendResult = producer.send(msg);
// 7、通过sendResult返回消息是否成功送达
System.out.printf("%s%n", sendResult);
// 8、如果不再发送消息,关闭生产者Producer
producer.shutdown();
}
}

在上述代码中,我们首先创建了一个生产者,然后指定了NameServer的地址,并启动了生产者。接着,我们创建了一个延时级别为3的消息,即该消息将会被延迟30秒后才能发送并被消费者消费。最后,我们发送了该消息,并关闭了生产者。

4 消息延时的优化

虽然RocketMQ的消息延时处理功能已经非常强大,但是在实际应用中,我们可能还需要根据自己的业务需求进行一些优化。以下是一些可能的优化方式:

  • 调整延时队列的大小。在RocketMQ中,每个Broker都只有一个延时队列,队列太小可能导致一些延时消息被miss。可以根据实际需求调整延时队列的大小。
  • 使用多个消费者来消费同一主题的消息。在RocketMQ中,可能有批量执行被设置了同样的延迟时间,这个就存在了一些风险,类似缓存的批量过期一样,稍有不慎,可能会击穿数据库。如果只有一个消费者来消费该主题的消息,可能会导致该消费者的处理速度不够快,从而影响到消息的及时性。我们可以根据实际需求增加消费者数量,以提高消息的处理速度。
  • 调整RocketMQ的配置参数。RocketMQ提供了一些配置参数,可以用来调整其性能和可靠性。我们可以根据实际需求调整这些参数,以优化消息的延时处理效果。

总之,RocketMQ的消息延时处理功能非常强大,可以满足许多实际应用场景的需求。在实际应用中,我们可以根据自己的业务需求进行一些优化,以进一步提高消息的及时性和可靠性。

5 总结

本文我们介绍了RocketMQ如何使用消息延时来处理特殊的业务场景。除了上述的方法之外,我们还有一些其他方法,比如:

  • 定时发送消息。在定时发送中,生产者可以指定一个未来的时间戳,在该时间戳到达时,该消息将会被发送到Broker。RocketMQ内部会维护一个定时任务,每隔一段时间检查一次待定时发送的消息,并判断是否到达了指定的时间戳。如果到达了指定的时间戳,该消息将会被发送到Broker。
  • 自建环形队列来实现“延时消息” ,参考这篇:1分钟实现“延迟消息”功能,写的不错

MQ系列14:MQ如何做到消息延时处理的更多相关文章

  1. MQ系列11:如何保证消息可靠性传输(除夕奉上)

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

  2. MQ系列10:如何保证消息幂等性消费

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

  3. 【SpringBoot MQ 系列】RabbitListener 消费基本使用姿势介绍

    [MQ 系列]RabbitListener 消费基本使用姿势介绍 之前介绍了 rabbitmq 的消息发送姿势,既然有发送,当然就得有消费者,在 SpringBoot 环境下,消费可以说比较简单了,借 ...

  4. MQ系列5:RocketMQ消息的发送模式

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 在之前的篇章中,我们学习了RocketMQ的原理, ...

  5. MQ系列6:消息的消费

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...

  6. MQ系列8:数据存储,消息队列的高可用保障

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 MQ系 ...

  7. 《吃透MQ系列》核心基础全在这里了

    这是<吃透XXX>技术系列的开篇,这个系列的思路是:先找到每个技术栈最本质的东西,然后以此为出发点,逐渐延伸出其他核心知识.所以,整个系列侧重于思考力的训练,不仅仅是讲清楚 What,而是 ...

  8. 【SpringBoot MQ 系列】RabbitMq 核心知识点小结

    [MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...

  9. MQ系列(0)——MQ简介

    mq简介 mq 就是消息队列(Message Queue).想必大家对队列的数据结构已经很熟悉了,消息队列可以简单理解为:把要传输的数据放在队列中,mq 就是存放和发送消息的这么一个队列中间件.在消息 ...

  10. 《吃透MQ系列》之扒开Kafka的神秘面纱

    大家好,这是<吃透 MQ 系列>的第二弹,有些珊珊来迟,后台被好几个读者催更了,实属抱歉! 这篇文章拖更了好几周,起初的想法是:围绕每一个具体的消息中间件,不仅要写透,而且要控制好篇幅,写 ...

随机推荐

  1. 2014年蓝桥杯C/C++大学B组省赛真题(六角填数)

    题目描述: 如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 分析:先将a数组初始化为1-12 ...

  2. webpack Dev Server Invalid Options options should NOT have additional prop

    今日npm run serve时提示ERROR ValidationError: webpack Dev Server Invalid Options options should NOT have ...

  3. 曲线艺术编程 coding curves 第六章 平托图 (Pintographs)

    第六章 平托图 (Pintographs) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗( ...

  4. c++中vector容器的用法

    C语言中const关键字是constant的缩写,通常翻译为常量.常数等,它可以修饰变量.数组.指针.函数参数. vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器.ve ...

  5. midjourney国内版上线! 快来体验一下midjourney的强大功能

    最近大火的midjourney国内版上线了!该网站对接了midjourneyAPI,以文生图.以图生图功能都支持,下面我们来体验一下它的功能. 网址:https://www.weijiwangluo. ...

  6. uniapp企业微信web-view父子通信问题

    项目背景:开发工具为HBuilderX,框架为uniapp,开发移动端的Web应用,在企业微信中使用(自建应用),Web开发的应用,不是小程序. 需求:页面中用到<web-view>组件, ...

  7. 8. 自定义映射resultMap

    ‍ 在 Mybatis 中,resultType 和 resultMap 都用于定义查询结果的映射关系.它们的使用场景如下: resultType resultType 用于指定返回结果的数据类型,通 ...

  8. 如何将PCM格式的原始音频采样数据编码为MP3格式或AAC格式的音频文件?

    一.打开和关闭输入文件和输出文件以及判断输入文件是否读取完毕 //io_data.cpp static FILE* input_file= nullptr; static FILE* output_f ...

  9. 前端:Uncaught TypeError: Cannot set property 'value' of null;

    1.在写JS代码中的绑定事件时(将JS与HTML标签分开时),发现会有如下错误提示: Uncaught TypeError: Cannot set property 'onclick' of null ...

  10. Python与MySQL如何保持长连接

    Python与MySQL如何保持长连接 介绍 在python后端开发中,时常会与数据库交互,重复的断开.连接 会大大消耗数据库资源. 所以一般都是定义全局变量,来弥补这个缺陷. 但是 Python 与 ...