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

【CouponHub项目开发】使用RocketMQ5.x实现延时修改优惠券状态,并通过使用模板方法模式重构消息队列发送功能

在上个章节中我实现了创建优惠券模板的功能,但是,优惠券总会有过期时间,我们怎么去解决到期自动修改优惠券状态这样一个功能呢?我们可以使用RocketMQ5.x新出的任意定时发送消息功能来解决。

初始方案:
在这里插入图片描述

  • 首先在创建优惠券模板下面继续添加代码。首先先创建topic
    在这里插入图片描述
  • 接着去定义消息体
// 执行 RocketMQ5.x 消息队列发送&异常处理逻辑SendResult sendResult;try {sendResult = rocketMQTemplate.syncSendDeliverTimeMills(couponTemplateDelayCloseTopic, message, deliverTimeStamp);log.info("[生产者] 优惠券模板延时关闭 - 发送结果:{},消息ID:{},消息Keys:{}", sendResult.getSendStatus(), sendResult.getMsgId(), messageKeys);} catch (Exception ex) {log.error("[生产者] 优惠券模板延时关闭 - 消息发送失败,消息体:{}", couponTemplateDO.getId(), ex);}
  • 接着去调用相关方法去发送消息

这样一个延时发送的消息生产者就定义好了,接着我们去定义消费者。

在这里插入图片描述

  • 我们可以创建一个消费者类让他去实现RocketMQListener然后添加 @RocketMQMessageListener 注解,其中加上 Topic 和消费者组定义
  • 接着我们可以在onMessage方法内去定义我们接收到消息以后需要去做什么
  • 这里我们需要去修改数据库当中的优惠券的状态

这样就已经解决了定时修改优惠券模板状态这样的功能,但是这样直接写在代码当中不是太优雅,而且耦合度太高。我们可以通过去定义一个生产者的抽象类(模板),然后去通过定义具体的类来继承这些抽象类。然后在创建优惠券模板的方法中我们只需要去定义一个事件,然后调用该类的方法去发送消息即可。

@RequiredArgsConstructor
@Slf4j(topic = "CommonSendProduceTemplate")
public abstract class AbstractCommonSendProduceTemplate<T> {private final RocketMQTemplate rocketMQTemplate;/*** 构建消息发送事件基础扩充属性实体** @param messageSendEvent 消息发送事件* @return 扩充属性实体*/protected abstract BaseSendExtendDTO buildBaseSendExtendParam(T messageSendEvent);/*** 构建消息基本参数,请求头、Keys...** @param messageSendEvent 消息发送事件* @param requestParam     扩充属性实体* @return 消息基本参数*/protected abstract Message<?> buildMessage(T messageSendEvent, BaseSendExtendDTO requestParam);/*** 消息事件通用发送** @param messageSendEvent 消息发送事件* @return 消息发送返回结果*/public SendResult sendMessage(T messageSendEvent) {BaseSendExtendDTO baseSendExtendDTO = buildBaseSendExtendParam(messageSendEvent);SendResult sendResult;try {// 构建 Topic 目标落点 formats: `topicName:tags`StringBuilder destinationBuilder = StrUtil.builder().append(baseSendExtendDTO.getTopic());if (StrUtil.isNotBlank(baseSendExtendDTO.getTag())) {destinationBuilder.append(":").append(baseSendExtendDTO.getTag());}// 延迟时间不为空,发送任意延迟消息,否则发送普通消息if (baseSendExtendDTO.getDelayTime() != null) {sendResult = rocketMQTemplate.syncSendDeliverTimeMills(destinationBuilder.toString(),buildMessage(messageSendEvent, baseSendExtendDTO),baseSendExtendDTO.getDelayTime());} else {sendResult = rocketMQTemplate.syncSend(destinationBuilder.toString(),buildMessage(messageSendEvent, baseSendExtendDTO),baseSendExtendDTO.getSentTimeout());}log.info("[生产者] {} - 发送结果:{},消息ID:{},消息Keys:{}", baseSendExtendDTO.getEventName(), sendResult.getSendStatus(), sendResult.getMsgId(), baseSendExtendDTO.getKeys());} catch (Throwable ex) {log.error("[生产者] {} - 消息发送失败,消息体:{}", baseSendExtendDTO.getEventName(), JSON.toJSONString(messageSendEvent), ex);throw ex;}return sendResult;}
}

在该抽象类中定义了两个抽象方法,

  • protected abstract BaseSendExtendDTO buildBaseSendExtendParam(T messageSendEvent);该方法用来补充事件的相关属性

  • protected abstract Message<?> buildMessage(T messageSendEvent, BaseSendExtendDTO requestParam);该方法是用来补充消息的属性

  • sendMessage方法中首先会通过buildBaseSendExtendParam方法把事件的属性进行补充,比如延时时间等。

  • 然后会获取这个时间是否存在延时时间这个属性,如果有则发送延时消息,如果没有,就发送普通消息。

在这里插入图片描述
这就是延时发送消息的生产者的一个实现类

在这里插入图片描述
这是消费者没有太大变化。

我们现在梳理一下它的执行流程

  • 创建完优惠券模板之后,我们根据优惠券的相关信息构建出一个发送事件templateDelayEvent
  • 然后通过自动注入的couponTemplateDelayExecuteStatusProducer延时发送消息的生产者,调用它的发送消息方法进行延时发送消息。
  • 这个生产者是去实现了生产者的一个抽象类,并实现了补充事件属性,以及构建消息体的抽象方法。
  • 然后消费者通过监听该消息来完成消费。

文章转载自:

http://Y1nFfYis.crrmg.cn
http://JQpW1Evi.crrmg.cn
http://fBg8rqoJ.crrmg.cn
http://PJ3GfMfT.crrmg.cn
http://ce9WNkjc.crrmg.cn
http://wYY60X2S.crrmg.cn
http://qeIFASZo.crrmg.cn
http://HaR9gqmE.crrmg.cn
http://v62nC2Td.crrmg.cn
http://B8eeSvsA.crrmg.cn
http://4cNDEh2O.crrmg.cn
http://YQ9tcBs9.crrmg.cn
http://xtfapPed.crrmg.cn
http://3u4LZMJ2.crrmg.cn
http://xa9lruDJ.crrmg.cn
http://MFEpFzKk.crrmg.cn
http://bQqU7E8J.crrmg.cn
http://8hAq0JB8.crrmg.cn
http://xdvXh5UH.crrmg.cn
http://XLd2RBTS.crrmg.cn
http://B6GFM08C.crrmg.cn
http://WZr1H1Mw.crrmg.cn
http://z3RdK6Zh.crrmg.cn
http://JGLnLO8K.crrmg.cn
http://zTGRaFxa.crrmg.cn
http://VnoukaDl.crrmg.cn
http://OPiJSzGD.crrmg.cn
http://AKXEeczY.crrmg.cn
http://Ulb5PJcf.crrmg.cn
http://Hx00Sviw.crrmg.cn
http://www.dtcms.com/a/366601.html

相关文章:

  • Unity中,软遮罩SoftMaskForUGUI可移动遮罩形状实现方法
  • 阻抗、瞬时阻抗、特性阻抗的区别
  • AI重构出海营销:HeadAI如何用“滴滴模式”破解红人营销效率困局?
  • 元宇宙与教育变革:沉浸式学习重构知识获取与能力培养
  • 从关键词到语义理解:小陌引擎如何重构AI搜索优化逻辑?
  • 【RNN-LSTM-GRU】第三篇 LSTM门控机制详解:告别梯度消失,让神经网络拥有长期记忆
  • 《ConfigMap热更新失效的深度解剖与重构实践》
  • Java GcExcel V8.2 新版本:效率升级与功能突破
  • Excel ——INDEX + MATCH 组合
  • Loopback for Mac:一键打造虚拟音频矩阵,实现跨应用音频自由流转
  • Leetcode—3516. 找到最近的人【简单】
  • wps的excel如何转为谷歌在线表格
  • JAVA层的权限与SELinux的关系
  • 【Python基础】 14 Rust 与 Python 标识符命名规则与风格对比笔记
  • AI编程:重塑软件开发范式的三大支柱
  • 微信小程序-day4
  • AI安全必修课:模型偏见检测与缓解实战
  • STL重点
  • 云手机的稳定性会受到哪些因素的影响?
  • 《嵌入式硬件(二):中断》
  • 多Agent协作案例:用AutoGen实现“写代码+测Bug”的自动开发流程
  • 【mysql】SQL自连接实战:查询温度升高的日期
  • 一键成文,标准随行——文思助手智能写作助力政务提效
  • PostgreSQL18-FDW连接的 SCRAM 直通身份验证
  • 金贝 KA Box 1.18T:一款高效能矿机的深度解析
  • 解锁桐果云零代码数据平台能力矩阵——赋能零售行业数字化转型新动能
  • 分布式电源接入电网进行潮流计算
  • 【C++详解】异常概念、抛出捕获与处理机制全解析
  • 当数据库宕机时,PostgreSQL 高可用在背后做了什么?
  • SQLynx 3.7 发布:数据库管理工具的性能与交互双重进化