当前位置: 首页 > news >正文

RocketMq详解:三、RocketMq通用生产和消费方法改造

文章目录

  • 1.背景
  • 2.通用方法改造
    • 2.1添加maven依赖
    • 2.2 RocketMq基础配置
    • 2.3 配置类
    • 2.5 消息传输的对象和结果
    • 2.4 消息生产者
    • 2.5 消息消费者
    • 2.6 功能测试

1.背景

在第二章:《RocketMq详解:二、SpringBoot集成RocketMq》中我们已经实现了消费基本生产和消费的实现,但是在真实的开发环境中如果按照这种方式去实现,冗余代码较多,且通过实现RocketMQListeneronMessage的方法去完成消息消费无返回结果,在后期的流程中不易维护,因此,本章将对这些问题进行二次改造和优化。

为了防止新同学从头开始学,本章将如何配置和实现简单在复述一下,至于具体怎么安装RocketMq,本文提供两种安装方法:

  • 《MacOS环境下RocketMQ安装及部署 RocketMQ Dashboard 可视化》
  • 《docker安装rocketMq》

2.通用方法改造

2.1添加maven依赖

		<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.3</version></dependency>

2.2 RocketMq基础配置

接着,在application.yml或application.properties文件中配置RocketMQ的相关参数,如NameServer地址、生产者组、消费者组等:

rocketmq:name-server: 127.0.0.1:9876# 生产者producer:group: boot_group_1# 消息发送超时时间send-message-timeout: 3000# 消息最大长度4Mmax-message-size: 4096# 消息发送失败重试次数retry-times-when-send-failed: 3# 异步消息发送失败重试次数retry-times-when-send-async-failed: 2# 消费者consumer:group: boot_group_1# 每次提取的最大消息数pull-batch-size: 5

上面的配置如果是在分布式环境下也可以配置在Apollonacos等配置中心里进行动态配置

2.3 配置类

在配置类中主要定义两个Bean的加载,即RocketMQTemplateDefaultMQProducer,主要是提供消息发送的能力,即生产消息;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author ninesun* @ClassName RocketMqConfig* @description: 消息中间件配置类* @date 2024年05月19日* @version: 1.0*/
@Configuration
public class RocketMqConfig {@Value("${rocketmq.name-server}")private String nameServer;@Value("${rocketmq.producer.group}")private String producerGroup;@Value("${rocketmq.producer.send-message-timeout}")private Integer sendMsgTimeout;@Value("${rocketmq.producer.max-message-size}")private Integer maxMessageSize;@Value("${rocketmq.producer.retry-times-when-send-failed}")private Integer retryTimesWhenSendFailed;@Value("${rocketmq.producer.retry-times-when-send-async-failed}")private Integer retryTimesWhenSendAsyncFailed;@Beanpublic RocketMQTemplate rocketMqTemplate() {RocketMQTemplate rocketMqTemplate = new RocketMQTemplate();rocketMqTemplate.setProducer(defaultMqProducer());return rocketMqTemplate;}@Beanpublic DefaultMQProducer defaultMqProducer() {DefaultMQProducer producer = new DefaultMQProducer();producer.setNamesrvAddr(this.nameServer);producer.setProducerGroup(this.producerGroup);producer.setSendMsgTimeout(this.sendMsgTimeout);producer.setMaxMessageSize(this.maxMessageSize);producer.setRetryTimesWhenSendFailed(this.retryTimesWhenSendFailed);producer.setRetryTimesWhenSendAsyncFailed(this.retryTimesWhenSendAsyncFailed);return producer;}
}

在编写消费者和生产者之前,我们先统一一下消息传输的对象,以及消费的结果

2.5 消息传输的对象和结果

  • 基本传输对象
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MessageDTO<T> {private T data;private Integer delayTime;@NotBlank(message = "Topic must not be blank")private String topic;@NotBlank(message = "Key must not be blank")private String key;private List<String> tags;private String messageType;
}
  • 消费结果枚举
public enum MsgRetryStatus {SUCCEED(-1), FAILURE(0), RETRY(0), RETRY_1S(1), RETRY_5S(2),RETRY_10S(3), RETRY_30S(4), RETRY_1M(5), RETRY_2M(6), RETRY_3M(7),RETRY_4M(8), RETRY_5M(9), RETRY_6M(10), RETRY_7M(11), RETRY_8M(12),RETRY_9M(13), RETRY_10M(14), RETRY_20M(15), RETRY_30M(16), RETRY_1H(17), RETRY_2H(18),RETRY_1D(19), RETRY_3D(20),  RETRY_7D(21), RETRY_14D(22), RETRY_21D(23),  RETRY_28D(24),RETRY_35D(25);int level;MsgRetryStatus(int level) {this.level = level;}public int getLevel() {return level;}
}

2.4 消息生产者

@Component
public class MessageProduct {@Resourceprivate RocketMQTemplate rocketMqTemplate;public SendResult SendMessage(MessageDTO data) {// 创建一个Message对象org.springframework.messaging.Message<?> message = MessageBuilder.withPayload(JSON.toJSONString(data)).setHeader(RocketMQHeaders.KEYS,data.getKey()).setHeader(RocketMQHeaders.TAGS,data.getTags()).build();return rocketMqTemplate.syncSendDelayTimeSeconds(data.getTopic(), message, data.getDelayTime());}
}

2.5 消息消费者

在原始的实现中,我们通过实现RocketMQListener接口中的onMessage方法来完成消息的消费。

然而,这种方式存在一个问题:如果消息消费失败,我们无法获取到返回结果,也不便于进行错误处理和重试。

为了优化这个问题,我们可以使用@RocketMQMessageListener注解的returnTopic属性来指定一个返回主题,当消息消费失败时,将消息发送到这个返回主题中。

同时,我们可以创建一个专门的处理失败消息的消费者来处理这些返回的消息。

另外,我们还可以在onMessage方法中添加异常处理逻辑,以便在消费失败时进行错误处理和记录日志。

新增一个抽象类CommonConsumer去实现RocketMQListener,并提供一个有返回值的doConsumerProcess方法,去实现具体的消费逻辑,具体实现如下:

@Slf4j
@Component
public abstract class CommonConsumer implements RocketMQListener<MessageDTO> {public void onMessage(MessageDTO message) {log.info("收到延迟消息成功,消息体:{}", message);doConsumerProcess(message);}public abstract MsgRetryStatus doConsumerProcess(MessageDTO messageDTO);
}

以boot-mq-topic为例,我们实现具体的消费,新增一个对象BootMqConsumer继承我们的CommonConsumer,来实现具体的消费逻辑

@Slf4j
@Component
public abstract class CommonConsumer implements RocketMQListener<MessageDTO> {public void onMessage(MessageDTO message) {try {// 处理消息的逻辑log.info("收到延迟消息成功,消息体:{}", message);MsgRetryStatus msgRetryStatus = doConsumerProcess(message);if (MsgRetryStatus.RETRY.equals(msgRetryStatus)|| MsgRetryStatus.FAILURE.equals(msgRetryStatus)) {//TODO 消费失败或重试 则发送重试Topic}} catch (Exception e) {// 记录错误日志e.printStackTrace();// 可以选择将失败消息发送到指定Topicthis.sendReturnMessgae();}}public abstract MsgRetryStatus doConsumerProcess(MessageDTO messageDTO);private void doRetrytConsumerProcess() {//TODO:待实现,后面补上}
}

2.6 功能测试

package com.example.demo.controller;import com.alibaba.fastjson.JSON;
import com.example.demo.annoation.Idempotent;
import com.example.demo.mq.producer.MessageProduct;
import com.example.demo.po.MessageDTO;
import com.example.demo.po.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;@RestController
@Slf4j
@Validated
public class TestController01 {@Resourceprivate RocketMQTemplate rocketMqTemplate;@Resourceprivate DefaultMQProducer defaultMqProducer;@Resourceprivate MessageProduct messageProduct;@GetMapping("/send/msg4")public String sendMsg4() {try {User user = User.builder().id(1).name("ninesun").build();MessageDTO<User> messageDTO = MessageDTO.<User>builder().data(user).delayTime(3).topic("boot-mq-topic").key(String.valueOf(UUID.randomUUID())).build();SendResult sendResult = messageProduct.SendMessage(messageDTO);log.info("msgId:{},sendStatus:{},data:{}", sendResult.getMsgId(), sendResult.getSendStatus(), JSON.toJSONString(messageDTO));} catch (Exception e) {e.printStackTrace();}return "OK";}
}

附:User对象

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String name;private String desc;
}

访问:/send/msg4接口,结果如下:
在这里插入图片描述

至此,我们便可以在真实环境中很容易的去集成消息队列实现功能的解耦,流量的削峰。

相关文章:

RocketMq详解:三、RocketMq通用生产和消费方法改造

文章目录 1.背景2.通用方法改造2.1添加maven依赖2.2 RocketMq基础配置2.3 配置类2.5 消息传输的对象和结果2.4 消息生产者2.5 消息消费者2.6 功能测试 1.背景 在第二章&#xff1a;《RocketMq详解&#xff1a;二、SpringBoot集成RocketMq》中我们已经实现了消费基本生产和消费…...

基于SpringBoot+Vue+Uniapp的仓库点单小程序的详细设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图代码运行效果图 代码运行效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发…...

R语言从多波段tif数据中逐个提取单波段数据

在遥感和地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;将多个波段存储在一个文件中可以更有效地进行数据压缩和管理&#xff0c;减少了存储空间的需求。 在R语言中&#xff0c;处理多波段栅格数据通常涉及以下步骤&#xff1a; 读取数据&#xff1a;使用raster包中…...

华为海思:大小海思的双轮驱动战略分析

华为海思,作为华为旗下的半导体设计部门,近年来在芯片设计领域取得了显著成就,成为了中国乃至全球芯片设计的重要力量。实际上,华为海思并非单一实体,而是由两个主要分支构成:大海思和小海思。这两个分支虽然同属华为海思,但在定位、产品布局以及市场策略上有所不同,共…...

LeetCode | 704.二分查找

标准的二分查找&#xff0c;直接上模板&#xff01; class Solution(object):def search(self, nums, target):""":type nums: List[int]:type target: int:rtype: int"""l 0r len(nums) - 1while l < r:mid (l r 1) / 2if nums[mid] …...

TCP三握四挥

TCP三握(简述) 一开始&#xff0c;客户端和服务端都处于closed状态&#xff0c;服务端主动监听某个端口&#xff0c;处于listen状态 一握要进行C-S的第一个SYN发送&#xff0c;客户端会随机初始化序列号(client_isn)并将其置于TCP首部的序列号字段中&#xff0c;并且将SYN标志…...

java项目之大型商场应急预案管理系统(源码+文档)

项目简介 大型商场应急预案管理系统实现了以下功能&#xff1a; 大型商场应急预案管理系统的主要使用者管理员功能有个人中心&#xff0c;员工管理&#xff0c;预案信息管理&#xff0c;预案类型管理&#xff0c;事件类型管理&#xff0c;预案类型统计管理&#xff0c;事件类…...

【C++】--内存管理

&#x1f47e;个人主页: 起名字真南 &#x1f47b;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 C/C内存分布2 C语言中动态内存管理方式 &#xff1a;3 C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4 operator new与operator delete4.1 opera…...

【设计模式系列】模板方法模式

一、什么是模板方法模式 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;它在父类中定义一个算法的框架&#xff0c;允许子类在不改变算法结构的情况下重写算法的某些特定步骤。这种模式非常适合于那些存在共同行为的类&#x…...

java8 Stream流详细API及用法

目录 整理的更全面的API及用法 创建Stream流 中间操作 filter 过滤 map 映射 flatMap 扁平映射 sorted 排序 limit 截断 skip 跳过 distinct 去重 peek 遍历 终端操作 forEach 遍历 forEachOrdered 顺序遍历 min 统计最小值 max 统计最大值 count 统计元素数量 f…...

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份&#xff1a;RDB触发机制rdb的触发时机&#xff1a;手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置&#xff0c;自动生成rdb快照RDB的优缺点 实时备份&#xff1a;AOFAOF是否会影响到red…...

川字结构布局/国字结构布局

1.串字结构布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style&g…...

2013年国赛高教杯数学建模C题古塔的变形解题全过程文档及程序

2013年国赛高教杯数学建模 C题 古塔的变形 由于长时间承受自重、气温、风力等各种作用&#xff0c;偶然还要受地震、飓风的影响&#xff0c;古塔会产生各种变形&#xff0c;诸如倾斜、弯曲、扭曲等。为保护古塔&#xff0c;文物部门需适时对古塔进行观测&#xff0c;了解各种变…...

web 0基础第一节 文本标签

这是一个html文件的基本结构 在vs code 中使用英文的 ! 可快捷设置这样的结构 <!-- --> 是在html写注释的结构 <!DOCTYPE html> <!--标识当前文档类型为html--> <html> …...

Zookeeper快速入门:部署服务、基本概念与操作

文章目录 一、部署服务1.下载与安装2.查看并修改配置文件3.启动 二、基本概念与操作1.节点类型特性总结使用场景示例查看节点查看节点数据 2.文件系统层次结构3.watcher 一、部署服务 1.下载与安装 下载&#xff1a; 一定要下载编译后的文件&#xff0c;后缀为bin.tar.gz w…...

【Sqlite】sqlite内部函数sqlite3_value_text特性

目录 ⚛️1 结论 ☪️2 说明 ☪️3 传入数值转成科学计数法 ♋3.1 只有整数部分 ♏3.2 只有小数部分 ♐3.3 整数小数 ⚛️1 结论 整数(sqlite视为int64)位数 > 20位&#xff0c;sqlite3_value_text 采用科学计数法。否则正常表示。 浮点数(sqlite视为double)的整数部…...

树莓派应用--AI项目实战篇来啦-4.OpenCV读取、写入和显示视频

1. 介绍 视频是由一张一张图片组成的&#xff0c;所以读取视频就相当于读取很多张图片&#xff0c;然后将其连起来cv2.VideoCapture可以捕获摄像头&#xff0c;但是针对树莓派的CSI摄像头调用方式采用了之前介绍的Picamera2 库&#xff0c;所以在调用的时候是有区别的&#xff…...

智能电子后视镜,汽车驾驶更安全,会是一种趋势

相比于传统的后视镜&#xff0c;智能电子后视镜的确有很多的优点。在下雨天和夜晚场景&#xff0c;电子后视镜可以说是表现优秀。 我之前一直以为我们国内是有规定不能使用电子后视镜。没想到&#xff0c;偶然刷到享界S9的视频&#xff0c;这电子后视镜&#xff0c;妥妥的给安排…...

IEC104规约的秘密之九----链路层和应用层

104规约从TCP往上&#xff0c;分成链路层和应用层。 如图&#xff0c;APCI就是链路层&#xff0c;ASDU的就是应用层 我们看到报文都是68打头的&#xff0c;因为应用层报文也要交给链路层发送&#xff0c;链路层增加了开头的6个字节再进行发送。 完全用于链路层的报文每帧都只有…...

最新Prompt预设词指令教程大全ChatGPT、AI智能体(300+预设词应用)

使用指南 直接复制在AI工具助手中使用&#xff08;提问前&#xff09; 可以前往已经添加好Prompt预设的AI系统测试使用&#xff08;可自定义添加使用&#xff09; SparkAi系统现已支持自定义添加官方GPTs&#xff08;对专业领域更加专业&#xff0c;支持多模态文档&#xff0…...

OpCore-Simplify:实现OpenCore EFI自动化生成的黑苹果配置解决方案

OpCore-Simplify&#xff1a;实现OpenCore EFI自动化生成的黑苹果配置解决方案 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 副标题&#xff1a;告别…...

别再手动同步了!利用STM32定时器主从模式与ITR触发,实现硬件级精准定时联动

嵌入式系统中的定时器协同&#xff1a;STM32主从模式与ITR触发的硬件级联动 在工业控制、电机驱动和精密测量等场景中&#xff0c;多个定时器的精确协同往往是系统可靠性的关键。想象一下&#xff0c;当你的电机控制PWM需要与电流采样ADC严格同步&#xff0c;或者多个通信接口必…...

Beyond Compare 5密钥生成器:专业文件对比工具的永久激活方案

Beyond Compare 5密钥生成器&#xff1a;专业文件对比工具的永久激活方案 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 你是否正在为Beyond Compare 5的30天评估期到期而烦恼&#xff1f;这款…...

AMD GPU高效部署Ollama:专业本地大语言模型实战指南

AMD GPU高效部署Ollama&#xff1a;专业本地大语言模型实战指南 【免费下载链接】ollama-for-amd Get up and running with Llama 3, Mistral, Gemma, and other large language models.by adding more amd gpu support. 项目地址: https://gitcode.com/gh_mirrors/ol/ollama…...

DeepSeek LintCode 3866.有效子数组的数量 public int validSubarrays(int[] nums)

这是关于LintCode 3866 “有效子数组的数量”的问题。这是一个典型的单调栈应用问题&#xff0c;需要计算数组中所有满足特定条件的子数组数量。 问题理解 有效子数组的定义&#xff1a; 对于数组 nums 中的某个子数组 nums[i..j]&#xff08;i ≤ j&#xff09;&#xff0c;如…...

35:L构建数据泄露检测:蓝队的数据保护

作者&#xff1a; HOS(安全风信子) 日期&#xff1a; 2026-03-11 主要来源平台&#xff1a; GitHub 摘要&#xff1a; 当基拉开始针对数据进行攻击时&#xff0c;数据泄露成为蓝队防御的关键挑战。L构建了数据泄露检测系统&#xff0c;通过AI算法分析数据流动、访问模式和异常行…...

解锁智能导航核心:从基础到进阶的路径规划实践指南

解锁智能导航核心&#xff1a;从基础到进阶的路径规划实践指南 【免费下载链接】PathPlanning Common used path planning algorithms with animations. 项目地址: https://gitcode.com/gh_mirrors/pa/PathPlanning 路径规划算法是机器人导航、自动驾驶和游戏AI等领域的…...

Buildroot构建根文件系统时,为什么你的rootfs.tar总比别人的大?深度解析裁剪技巧

Buildroot构建根文件系统时rootfs.tar体积优化实战指南 当你在嵌入式Linux开发中使用Buildroot构建根文件系统时&#xff0c;是否经常遇到生成的rootfs.tar文件体积过大的问题&#xff1f;本文将深入解析Buildroot的打包机制&#xff0c;揭示那些容易被忽视的体积膨胀陷阱&…...

突破3大技术瓶颈:抖音音乐批量下载工具的创新解决方案

突破3大技术瓶颈&#xff1a;抖音音乐批量下载工具的创新解决方案 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 在数字内容创作领域&#xff0c;音频素材的获取与管理已成为制约生产力的关键因素。特别是当…...

终极免费Jable视频下载指南:3步搞定Chrome插件完整教程

终极免费Jable视频下载指南&#xff1a;3步搞定Chrome插件完整教程 【免费下载链接】jable-download 方便下载jable的小工具 项目地址: https://gitcode.com/gh_mirrors/ja/jable-download jable-download是一款专为普通用户设计的免费Jable视频下载工具&#xff0c;通过…...