# 全面解剖 消息中间件 RocketMQ-(4)

全面解剖 消息中间件 RocketMQ-(4)

一、RocketMQ 顺序消息分析

1、消息有序:指的是可以按照消息的发送顺序来消费(FIFO)。RocketMQ 可以严格的保证消息有序,可以分为分区有序或者全局有序。

2、顺序消费的原理解析

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

3、下面用订单进行分区有序的示例。一个订单的顺序流程是:创建、付款、推送、完成。订单号相同的消息会被先后发送到同一个队列中,消费时,同一个 Orderld 获取到的肯定是同一个队列。

在这里插入图片描述

二、RocketMQ 顺序消息发送者

1、在工程 rocketmq_demo (模块)中,创建 订单构建 实体类 OrderStep.java


/***  D:\java-test\idea2019\rocketmq_demo\src\main\java\djh\it\mq\rocketmq\order\OrderStep.java**  2024-6-2 创建 订单构建 实体类 OrderStep.java*/package djh.it.mq.rocketmq.order;import java.util.ArrayList;
import java.util.List;public class OrderStep {private long orderId;  //订单 idprivate String desc;   //订单描述public long getOrderId() {return orderId;}public void setOrderId(long orderId) {this.orderId = orderId;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}@Overridepublic String toString() {return "OrderStep{" +"orderId=" + orderId +", desc='" + desc + '\'' +'}';}public static List<OrderStep> buildOrders() {// 1039L    : 创建 付款 推送 完成// 1065L    : 创建 付款// 7235L    : 创建 付款List<OrderStep> orderList = new ArrayList<OrderStep>();OrderStep orderDemo = new OrderStep();orderDemo.setOrderId(1039L);orderDemo.setDesc("创建");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1065L);orderDemo.setDesc("创建");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1039L);orderDemo.setDesc("付款");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(7235L);orderDemo.setDesc("创建");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1065L);orderDemo.setDesc("付款");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(7235L);orderDemo.setDesc("付款");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1065L);orderDemo.setDesc("完成");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1039L);orderDemo.setDesc("推送");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(7235L);orderDemo.setDesc("完成");orderList.add(orderDemo);orderDemo = new OrderStep();orderDemo.setOrderId(1039L);orderDemo.setDesc("完成");orderList.add(orderDemo);return orderList;}
}

2、在工程 rocketmq_demo (模块)中,创建 顺序消息发送 类 Producer.java


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\order\Producer.java**   2024-6-2  创建 顺序消息发送 类 Producer.java*/
package djh.it.mq.rocketmq.order;import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;import java.util.List;public class Producer {public static void main(String[] args) throws Exception {//1.创建消息生产者 producer,并制定生产者组名DefaultMQProducer producer = new DefaultMQProducer("group1");//2.指定 Nameserver 地址(集群配置)//producer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)producer.setNamesrvAddr("172.18.30.110:9876");//3.启动 producerproducer.start();//构建消息集合List<OrderStep> orderSteps = OrderStep.buildOrders();//发送消息for(int i=0; i<orderSteps.size(); i++){String body = orderSteps.get(i)+"";//4.创建消息对象,指定主题 Topic、Tag 和消息体//参数一:消息对象, 参数二:消息队列选择器, 参数三:选择队列的业务标识(订单id)Message message = new Message("OrderTopic", "Order", "i"+i, body.getBytes());//5.发送 异步 消息SendResult sendResult = producer.send(message, new MessageQueueSelector(){/**** @param mqs :队列集合* @param msg :消息对象				 ** @param arg :业务标识的参数* @return*/public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {long orderId = (Long) arg;long index = orderId % mqs.size();return mqs.get((int) index);}}, orderSteps.get(i).getOrderId());System.out.println("发送结果:"+sendResult);}//6.关闭生产者 producer。producer.shutdown();  	   }
}

三、RocketMQ 顺序消息消费者

1、在工程 rocketmq_demo (模块)中,创建 顺序消息消费 类 Consumer.java


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\order\Consumer.java**   2024-6-2  创建 顺序消息消费 类 Consumer.java 。*/
package djh.it.mq.rocketmq.order;import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;import java.util.List;public class Consumer {public static void main(String[] args) throws Exception {//1.创建消费者 Consumer,制定消费者组名DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");//2.指定 Nameserver 地址(集群配置)//consumer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)consumer.setNamesrvAddr("172.18.30.110:9876");//3.订阅主题 Topic 和 Tagconsumer.subscribe("OrderTopic", "*");  //接收所有消息。//4.注册消息监听器consumer.registerMessageListener(new MessageListenerOrderly() {public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {for(MessageExt msg : msgs){System.out.println("线程名称:【"+Thread.currentThread().getName() + "】 消费消息:" + new String(msg.getBody()));  //转换为字符串消息}return ConsumeOrderlyStatus.SUCCESS;}});//5.启动消费者 consumer。consumer.start();System.out.println("消费消息启动了");}
}

2、先启动 顺序消息发送 类 Producer.java,再启动 顺序消息消费 类 Consumer.java 进行测试。

在这里插入图片描述

四、RocketMQ 延迟消息

1、RocketMQ 延迟消息

比如电商里,提交了一个订单就可以发送一个延时消息,1h 后去检查这个订单的状态,
如果还是未付款就取消订单释放库存。

2、RocketMQ 延迟消息 使用限制

//org/apache/rocketmg/store/config/Messagestoreconfig.java

private string messageDelayLevel = “1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h”.

现在 RocketMg 并不支持任意时间的延时,需要设置几个固定的延时等级,从 1s 到 2h 分别对应着等级 1 到 18。

3、在工程 rocketmq_demo (模块)中,创建 延迟消息 发送 类 Producer.java


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\delay\Producer.java**   2024-6-2  创建 延迟消息 发送 类 Producer.java*/
package djh.it.mq.rocketmq.delay;import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import java.util.concurrent.TimeUnit;public class Producer {public static void main(String[] args) throws Exception {//1.创建消息生产者 producer,并制定生产者组名DefaultMQProducer producer = new DefaultMQProducer("group1");//2.指定 Nameserver 地址(集群配置)//producer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)producer.setNamesrvAddr("172.18.30.110:9876");//3.启动 producerproducer.start();//发送消息for(int i=0; i<10; i++){//4.创建消息对象,指定主题 Topic、Tag 和消息体//参数一:消息主题 Topic, 参数二:消息 Tag, 参数三:消息内容Message msg = new Message("DelayTopic", "Tag1", ("Hello World"+i).getBytes());//设定延迟发送 时间为 5 秒(目前 rocketmq 支持的延迟等级:"1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h".)msg.setDelayTimeLevel(2);//5.发送消息SendResult result = producer.send(msg);System.out.println("发送结果:"+result);TimeUnit.SECONDS.sleep(1);  //线程睡1秒}//6.关闭生产者 producer。producer.shutdown();}
}

4、在工程 rocketmq_demo (模块)中,创建 延迟消息 消费 类 Consumer.java 。


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\delay\Consumer.java**   2024-6-2  创建 延迟消息 消费 类 Consumer.java 。*/
package djh.it.mq.rocketmq.delay;import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;import java.util.List;public class Consumer {public static void main(String[] args) throws Exception {//1.创建消费者 Consumer,制定消费者组名DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");//2.指定 Nameserver 地址(集群配置)//consumer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)consumer.setNamesrvAddr("172.18.30.110:9876");//3.订阅主题 Topic 和 Tag//consumer.subscribe("base", "Tag1");  //接收同步消息//consumer.subscribe("base", "Tag2");  //接收异步消息前,可以让先发送异步消息。//consumer.subscribe("base", "Tag1 | Tag2");  //接收同步消息 和 异步消息consumer.subscribe("DelayTopic", "*");  //接收所有消息。//添加消费模式//consumer.setMessageModel(MessageModel.CLUSTERING);  //默认是负载均衡模式消费consumer.setMessageModel(MessageModel.BROADCASTING);  //广播模式消费//4.设置回调函数,处理消息consumer.registerMessageListener(new MessageListenerConcurrently(){//接受消息内容public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context){//System.out.println(msgs); //接收到的消息是未转换的字节码for(MessageExt msg : msgs){System.out.println("消息ID:【" + msg.getMsgId()+"】,延迟时间:"+(System.currentTimeMillis()-msg.getStoreTimestamp()));  //转换为字符串消息}return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});//5.启动消费者 consumer。consumer.start();System.out.println("消费者启动");}
}

5、先启动 延迟消息 消费 类 Consumer.java 再启动 延迟消息 发送 类 Producer.java 进行测试。

在这里插入图片描述

五、RocketMQ 批量消息发送

1、批量发送消息能显著提高传递小消息的性能。限制是这些批量消息应该有相同的 topic,相同的 waitstoreMsgOK,而且不能是延时消息。此外,这一批消息的总大小不应超过無 4MB。如果消息的总长度可能大于4MB时,这时候最好把消息进行分割。

2、在工程 rocketmq_demo (模块)中,创建 批量消息发送 发送 类 Producer.java


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\batch\Producer.java**   2024-6-2  创建 批量消息发送的 发送 类 Producer.java*/
package djh.it.mq.rocketmq.batch;import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;public class Producer {public static void main(String[] args) throws Exception {//1.创建消息生产者 producer,并制定生产者组名DefaultMQProducer producer = new DefaultMQProducer("group1");//2.指定 Nameserver 地址(集群配置)//producer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)producer.setNamesrvAddr("172.18.30.110:9876");//3.启动 producerproducer.start();//创建一个集合List<Message> msgs = new ArrayList<Message>();//发送消息//4.创建消息对象,指定主题 Topic、Tag 和消息体//参数一:消息主题 Topic, 参数二:消息 Tag, 参数三:消息内容Message msg1 = new Message("BatchTopic", "Tag1", ("Hello World"+1).getBytes());Message msg2 = new Message("BatchTopic", "Tag1", ("Hello World"+2).getBytes());Message msg3 = new Message("BatchTopic", "Tag1", ("Hello World"+3).getBytes());msgs.add(msg1);msgs.add(msg2);msgs.add(msg3);//5.发送消息SendResult result = producer.send(msgs);System.out.println("发送结果:"+result);TimeUnit.SECONDS.sleep(1);  //线程睡1秒//6.关闭生产者 producer。producer.shutdown();}
}

3、在工程 rocketmq_demo (模块)中,创建 批量消息发送 消费 类 Consumer.java 。


/***   rocketmq_demo\src\main\java\djh\it\mq\rocketmq\batch\Consumer.java**   2024-6-2  创建 批量消息发送 消费 类 Consumer.java 。*/
package djh.it.mq.rocketmq.batch;import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;import java.util.List;public class Consumer {public static void main(String[] args) throws Exception {//1.创建消费者 Consumer,制定消费者组名DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");//2.指定 Nameserver 地址(集群配置)//consumer.setNamesrvAddr("192.168.25.135:9876;192.168.25.138:9876");//2.指定 Nameserver 地址(非集群配置)consumer.setNamesrvAddr("172.18.30.110:9876");//3.订阅主题 Topic 和 Tagconsumer.subscribe("BatchTopic", "*");  //接收所有消息。//4.设置回调函数,处理消息consumer.registerMessageListener(new MessageListenerConcurrently(){//接受消息内容public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context){//System.out.println(msgs); //接收到的消息是未转换的字节码for(MessageExt msg : msgs){System.out.println("consumeThread=" + Thread.currentThread().getName()+", "+new String(msg.getBody()));  //转换为字符串消息}return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});//5.启动消费者 consumer。consumer.start();System.out.println("消费者启动");}
}

4、先启动 批量消息发送 消费 类 Consumer.java 再启动 批量消息发送 发送 类 Producer.java 进行测试。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/21677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vfrom二开给左边添加字段或者容器

例如&#xff0c;我在左侧加入一个 我的公司 字段 修改三个文件&#xff0c;这是文件目录 这个文件是当界面选择 简体中文 的时候&#xff0c;显示的 字段组件 或者 容器组件的中文名 这个文件是当界面选择 English 的时候&#xff0c;显示的 字段组件 或者 容器组件的英文名 把…

Spring Boot 集成 zxing 生成条形码与二维码

前面我们知道了怎么通过 使用 zxing 生成二维码以及条形码&#xff0c; 由于我们现在都是 web 端的项目了&#xff0c;那么我们看下怎么使用 Spring Boot 集成然后返回给前端展示&#xff1a; 工程源码 对应的工程源码我放到了这里&#xff1a;github源码路径&#xff0c;点击…

d2-crud-plus 使用小技巧(六)—— 表单下拉选择 行样式 溢出时显示异常优化

问题 vue2 elementUI d2-crud-plus&#xff0c;数据类型为select时&#xff0c;行样式显示为tag样式&#xff0c;但是如果选择内容过长就会出现下面这种bug&#xff0c;显然用户体验不够友好。 期望 代码 js export const crudOptions (vm) > {return {...columns:…

图书管理系统(https://github.com/plusmultiply0/bookmanagesystem)

特意去github找了一个用flask框架的项目&#xff0c;一起来学习它吧 这个系统包括很多功能&#xff1a;用户权限管理模块&#xff08;管理员和普通用户&#xff09;&#xff0c;注册登录模块&#xff08;滑块验证码功能&#xff09;&#xff0c;图书有关信息模块&#xff08;借…

毫米级精度3D人脸扫描设备,助推打造元宇宙虚拟分身

在元宇宙中&#xff0c;虚拟分身对应的是一个三维模型&#xff0c;数字化的过程则是三维重建过程&#xff0c;通过3D人脸扫描可以通过多相机同步采集人脸部&#xff0c;可快速、准确地重建出真人地脸部模型及贴图&#xff0c;通过3D人脸扫描设备可快速重建出高逼真的虚拟分身。…

Linux系统下+jmeter分布式压测

一.配置jdk&#xff08;Linux机都需配置同一个版本&#xff09; 下载Linux系统的jdk&#xff0c;下载地址&#xff1a;https://repo.huaweicloud.com/java/jdk/ 下载后的jdk文件上传到 /opt目录下 进入opt目录&#xff0c;查看jdk文件 cd /opt ll 1.解压文件 tar xzvf jd…

真国色码上赞,科技流量双剑合璧,商家获客新纪元开启

在数字化浪潮汹涌的今天,真国色研发团队依托红玉房网络科技公司的雄厚实力,凭借科技领先的核心竞争力,推出了创新性的商家曝光引流工具——码上赞。这款工具借助微信支付与视频号已有功能,为实体商家提供了一种全新的引流获客方式,实现了科技与商业的完美融合。 科技领先,流量黑…

CSS 空间转换 动画

目录 1. 空间转换1.1 视距 - perspective1.2 空间转换 - 旋转1.3 立体呈现 - transform-style1.4 空间转换 - 缩放 2. 动画 - animation2.1 动画的基本用法2.1 animation 复合属性2.2 animation 拆分属性2.3 多组动画 正文开始 1. 空间转换 空间&#xff1a;是从坐标轴角度定义…

Paddle实现单目标检测

单目标检测 单目标检测&#xff08;Single Object Detection&#xff09;是人工智能领域中的一个重要研究方向&#xff0c;旨在通过计算机视觉技术&#xff0c;识别和定位图像中的特定目标物体。单目标检测可以应用于各种场景&#xff0c;如智能监控、自动驾驶、医疗影像分析等…

短视频矩阵系统搭建开发,ai智能剪辑系统,矩阵发布,一键管理多个账户

前言&#xff1a; 企业短视频矩阵是企业通过搭建多个短视频平台账号&#xff0c;形成一个多元化的内容传播网络。它旨在通过多平台内容的同步传播&#xff0c;实现企业品牌价值的最大化。短视频矩阵包括抖音、快手、视频号、小红书、百家号等热门短视频平台&#xff0c;其核心…

向日葵抓住哪三个要点,帮助企业构建专业技术支持服务体系?

售后技术支持是销售行为的延续&#xff0c;在存量时代企业是否能够提供优质专业的售后技术支持服务显得尤为重要&#xff0c;它直接关系到企业产品在市场中的口碑&#xff0c;进而影响企业的发展命运。 因此&#xff0c;企业势必需要重视技术支持服务体系的搭建&#xff0c;引…

【数据分享】水体分布与五级水系和流域矢量数据+2000-2022年植被指数(NDVI)数据(全国/分省/分市)

1. 数据介绍 数据分为3个层次结构&#xff0c;分别为省、地级市、县。其中&#xff0c;省级水体31个&#xff08;不包含香港、台湾等&#xff09;&#xff0c; 地级市水体366个&#xff0c;县级市水体2847个。每一个文件夹中都包含该省、地级市或者县的水体矢量数据、行政边界…

数学建模 —— 灰色系统(4)

目录 什么是灰色系统&#xff1f; 一、灰色关联分析 1.1 灰色关联分析模型 1.2 灰色关联因素和关联算子集 1.2.1 灰色关联因素 1.2.2 关联算子集 1.3 灰色关联公理与灰色关联度 1.3.1 灰色关联度 1.3.2 灰色关联度计算步骤 1.4 广义关联度 1.4.1 灰色绝对关联…

一文读懂GDPR

GDPR将对人们的网络足迹、使用的APP和服务如何保护或利用这些数据产生重大影响。 下面我们将对有关GDPR人们最关心的问题进行解读。 GDPR是什么&#xff1f; 一般数据保护条例&#xff08;General Data Protection Regulation&#xff09;是一项全面的法律&#xff0c;赋予了…

风电Weibull+随机出力!利用ARMA模型随机生成风速+风速Weibull分布程序代码!

前言 随着能源问题日益突出&#xff0c;风力发电等以可再生能源为基础的发电技术越来越受到关注。建立能够正确反映实际风速特性的风速模型是研究风力发电系统控制策略以及并网运行特性的重要基础叫。由于风速的随机性和波动性&#xff0c;系统中的机械设备和电气设备以及电网…

计算机网络⑩ —— Linux系统如何收发网络包

转载于小林coding&#xff1a;https://www.xiaolincoding.com/network/1_base/how_os_deal_network_package.html 1. OSI七层模型 应用层&#xff0c;负责给应用程序提供统一的接口&#xff1b;表示层&#xff0c;负责把数据转换成兼容另一个系统能识别的格式&#xff1b;会话…

深度剖析云边对接技术:探索开放API接口的价值与意义

在当今数字化时代的浪潮中&#xff0c;云边对接与开放API接口成为了塑造行业生态的重要驱动力。随着云计算、物联网和边缘计算等技术的快速发展&#xff0c;传统产业正在迈向数字化转型的关键时刻。而在这个过程中&#xff0c;云边对接技术以及开放的应用程序接口(API)扮演着举…

Facebook海外三不限 | 如何降低Facebook频繁被封的风险

本文将讨论Facebook账户被封的原因及降低封禁风险的方法&#xff0c;以维护用户的账户安全和社交乐趣。 1. 常见原因&#xff1a;账户被封通常与发布违反社区标准的内容有关&#xff0c;如仇恨言论、暴力内容、欺诈虚假信息、非法活动、骚扰、版权侵权等。此外&#xff0c;未授…

el-date-picker选择开始日期的近半年

<el-date-pickerv-model"form[val.key]":type"val.datePickerType || daterange":clearable"val.clearable && true"range-separator"~"start-placeholder"开始日期"end-placeholder"结束日期"style&q…

玩转Linux进度条

准备工作&#xff1a; 一.关于缓冲区 首先&#xff0c;咱们先来一段有意思的代码&#xff1a; #include<stdio.h> #include<unistd.h> int main() {printf("you can see me");sleep(5);} 你可以在你的本地运行一下&#xff0c;这里我告诉大家运行结果…