向mq写消息
1.基础版本
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import com.alibaba.fastjson.JSON; public class MQProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("G-Group_REQ");
producer.setNamesrvAddr("localhost:9876");
producer.start(); String jsonStr = JSON.toJSONString("Your JSON content");
Message msg = new Message("T-Topic", jsonStr.getBytes()); producer.send(msg);
producer.shutdown();
}
}
2.添加写消息失败处理:登记日志、定时处理、参数配置化
import cn.com.*.support.MQLogSupport;
import cn.com.*.entity.MQLog;
import cn.com.*.repository.MQLogRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.javacrumbs.shedlock.core.SchedulerLock;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; @Component
public class MQLogSupportImpl implements MQLogSupport{
private final Logger logger = LoggerFactory.getLogger(MQLogSupport.class);
@Autowired
private MQLogRepository mqLogRepository; @Value("${rocketmq.name-server}")
String namesrvAddr; // 写消息服务
public void sendMessageNoTag(MQLog mqLog) {
try {
DefaultMQProducer producer = new DefaultMQProducer(mqLog.getMqGroup());
producer.setNamesrvAddr(namesrvAddr);
// 设置发送消息的超时时间为30秒
producer.setSendMsgTimeout(30000);
producer.start();
Message msg = new Message(mqLog.getMqTopic(), mqLog.getMqMessage().getBytes());
producer.send(msg);
setMQlogSuccess(mqLog);
producer.shutdown();
} catch (Exception e) {
setMQlogError(mqLog, "9999", "初次:" + e.getMessage());
}
} // 定时任务,失败后重新写消息,每分钟执行一次
@Scheduled(cron = "0 0/1 * * * ?")
@SchedulerLock(name = "RocketMQ", lockAtLeastForString = "PT5M", lockAtMostForString = "PT30M")
public void readAndResendMessage() {
// 读取失败信息
List<MQLog> messageList = mqLogRepository.findByDealCodeNot("0000");
if(CollectionUtils.isEmpty(messageList)){
return;
}
// 重新写消息
for (MQLog message : messageList) {
try {
DefaultMQProducer producer = new DefaultMQProducer(message.getMqGroup());
producer.setNamesrvAddr(namesrvAddr);
producer.setSendMsgTimeout(30000);
producer.start();
Message msg = new Message(message.getMqTopic(), message.getMqMessage().getBytes());
producer.send(msg);
setMQlogSuccess(message);
producer.shutdown();
} catch (Exception e) {
setMQlogError(message, "定时任务:" + e.getMessage());
}
}
} public MQLog regMQlog(JSONObject mqLogJson){
logger.debug("登记 mq 消息......");
String topic = mqLogJson.getString("topic");
String tags = mqLogJson.getString("tags");
String msg = JSON.toJSONString(mqLogJson);
String key = mqLogJson.getString("key");
Boolean approveResult = mqLogJson.getBoolean("approved");
String approver = mqLogJson.getString("approver");
String comment = mqLogJson.getString("comment");
String finshTime = mqLogJson.getString("finshTime"); MQLog.MQLogBuilder mqLogBuilder = MQLog.builder();
mqLogBuilder.mqTopic(topic)
.mqTags(tags)
.key(key)
.mqMessage(msg)
.approveResult(approveResult)
.approver(approver)
.approveComment(comment)
.approveFinishTime(finshTime)
.regDateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))); MQLog savedMqLog = mqLogRepository.save(mqLogBuilder.build());
logger.debug("登记 mq 消息完成。");
return savedMqLog;
} public void setMQlogError(MQLog mqLog, String errorCode, String errorMsg){
mqLogRepository.save(mqLog.toBuilder().dealCode(errorCode).dealMsg(errorMsg).build());
} public void setMQlogError(MQLog mqLog, String errorMsg){
setMQlogError(mqLog,"Error",errorMsg);
} public void setMQlogSuccess(MQLog mqLog){
mqLogRepository.save(mqLog.toBuilder().dealCode("0000").dealMsg("success").build());
}
}
3.简化代码
import cn.com.*.support.MQLogSupport;
import cn.com.*.entity.MQLog;
import cn.com.*.repository.MQLogRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.javacrumbs.shedlock.core.SchedulerLock;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; @Component
public class MQLogSupportImpl implements MQLogSupport {
private final Logger logger = LoggerFactory.getLogger(MQLogSupport.class);
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Autowired
private MQLogRepository mqLogRepository; // 写消息服务
public void sendMessageNoTag(MQLog mqLog) {
rocketMQTemplate.asyncSend(mqLog.getMqTopic(), mqLog.getMqMessage(), new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
setMQlogSuccess(mqLog);
} @Override
public void onException(Throwable e) {
setMQlogError(mqLog, "初次:" + e.getMessage());
retrySendMessage(mqLog);
}
});
} // 重试发送消息
private void retrySendMessage(MQLog mqLog) {
int retryCount = mqLog.getRetryCount();
if (retryCount < 3) { // 最多重试3次
mqLog.setRetryCount(retryCount + 1);
mqLogRepository.save(mqLog);
sendMessageNoTag(mqLog);
} else {
setMQlogError(mqLog, "重试3次仍然失败");
}
} // 定时任务,失败后重新写消息,每分钟执行一次
@Scheduled(cron = "0 0/1 * * * ?")
@SchedulerLock(name = "RocketMQ", lockAtLeastForString = "PT5M", lockAtMostForString = "PT30M")
public void readAndResendMessage() {
// 读取失败信息
List<MQLog> messageList = mqLogRepository.findByDealCodeNot("0000");
if (CollectionUtils.isEmpty(messageList)) {
return;
}
// 重新写消息
for (MQLog message : messageList) {
rocketMQTemplate.asyncSend(message.getMqTopic(), message.getMqMessage(), new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
setMQlogSuccess(message);
} @Override
public void onException(Throwable e) {
setMQlogError(message, "定时任务:" + e.getMessage());
retrySendMessage(message);
}
});
}
} // 设置消息发送成功
private void setMQlogSuccess(MQLog mqLog) {
mqLog.setDealCode("0000");
mqLog.setDealDesc("发送成功");
mqLogRepository.save(mqLog);
} // 设置消息发送失败
private void setMQlogError(MQLog mqLog, String errorMsg) {
mqLog.setDealCode("9999");
mqLog.setDealDesc(errorMsg);
mqLogRepository.save(mqLog);
}
}
注意:
1) 配置文件
rocketmq:
name-server: IP:端口
producer:
group: "G-Group_REQ"
send-msg-timeout: 30000
2) 根据需要实现:
MQLogSupport、MQLog、MQLogRepository
向mq写消息的更多相关文章
- 通过JAVA从MQ读取消息的时候报错及解决
如果是通过JAVA将消息写入到MQ,再通过JAVA去读取消息,采用MQMessage读消息的方法readUTF()去读取的时候,就不会报错,可以正常读出来.如果采用在MQ资源管理器中插入测试消息或者是 ...
- springboot整合mq接收消息队列
继上篇springboot整合mq发送消息队列 本篇主要在上篇基础上进行activiemq消息队列的接收springboot整合mq发送消息队列 第一步:新建marven项目,配置pom文件 < ...
- MQ(队列消息的入门)
消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成,通过提供消息传递和消息排队模型,它可以在分布式环境下拓展进程间的通信,对于消息中间件,常见的角色大致也 ...
- 架构设计:系统间通信(20)——MQ:消息协议(下)
(接上文<架构设计:系统间通信(19)--MQ:消息协议(上)>) 上篇文章中我们重点讨论了"协议"的重要性.并为各位读者介绍了Stomp协议和XMPP协议. 这两种协 ...
- MQ中将消息发送至远程队列的配置
MQ中将消息发送至远程队列的配置 摘自MQ资源管理器帮助文档V7 在开始学习本教程之前,您需要从系统管理员处了解标识网络上接收机器的名称:IP地址.MQ的端口号.队列管理器.接收(远程机器)或者是发送 ...
- 聊聊mq中消息消费的几种方式
mq系列文章 对mq了解不是很多的,可以看一下下面两篇文章: 聊聊mq的使用场景 聊聊业务系统中投递消息到mq的几种方式 聊聊消息消费的几种方式 如何确保消息至少消费一次 如何保证消息消费的幂等性 本 ...
- 【MQ】消息队列及常见MQ比较
一.什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用.消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰. ...
- 分布式事务解决方案(二)消息系统避免分布式事务 & MQ事务消息 & Sagas 事务模型
参考文档: 如何用消息系统避免分布式事务:http://blog.jobbole.com/89140/ https://www.cnblogs.com/savorboard/p/distributed ...
- MQ解决消息重发--做到幂等性
一.MQ消息发送 1.发送端MQ-client(消息生产者:Producer)将消息发送给MQ-server: 2.MQ-server将消息落地: 3.MQ-server回ACK给MQ-client( ...
- MQ & RPC 消息队列与RPC的区别与使用场景
MQ: 区别:面向数据.生产者与消费者.有缓冲节点.异步.系统级/模块级通信 选型:RabbitMQ.ActiveMQ/Apollo.ZeroMQ.memcacheQ.Redis.MSMQ.kafk ...
随机推荐
- Kioptrix Level 1
Kioptrix这个系列靶机默认是桥接模式,如果我们kali使用NAT是扫描不到靶机的,通过VM的靶机网络设置也不能更改成功. 解决方式:每次下载好靶机先不导入VM,如果已经导入,需要"移除 ...
- 文盘Rust——子命令提示,提高用户体验
上次我们聊到 CLI 的领域交互模式.在领域交互模式中,可能存在多层次的子命令.在使用过程中如果全评记忆的话,命令少还好,多了真心记不住.频繁 --help 也是个很麻烦的事情.如果每次按 'tab' ...
- 最接地气的.NET微服务框架
前言: "人必有所执,方能有所成",从2018年底我就开始规划要写一个.NET微服务框架,5年了,今天终于正式发布了. 正文: Wing 致力于打造一个功能强大.最接地气的.NET ...
- HiAI Foundation助力端侧音视频AI能力,高性能低功耗释放云侧成本
过去三年是端侧AI高速发展的几年,华为在2020年预言了端侧AI的发展潮流,2021年通过提供端云协同的方式使我们的HiAI Foundation应用性更进一个台阶,2022年提供视频超分端到端的解决 ...
- numpy 索引,切片 ,转置,变值,多个数组的拼接
- Vue 中的 Ajax
1.1 使用代理服务器 1.1.1 方式一 在 vue.config.js 中添加如下配置: devServer:{ proxy:"http://localhost:5000" } ...
- Note -「Suffix Automaton」SAM
Part. 1 基本信息 Part. 1-1 SAM 的构成. SAM 由两个东西构成,一个是一个 DAWG,还有一棵外向树,叫 parent tree. 比如,给你一个字符串 \(S=\sf abb ...
- Solution -「ARC 103B」Robot Arms
Description Link. 给定 \(n\) 组坐标.构造长度为 \(m\) 的序列 \(\{c_n\}\) 和 \(n\) 组包含 LRUD 的路径,满足对于每一组坐标: \(c_i\) 表 ...
- 爬虫系列——selenium
文章目录 一 介绍 二 安装 三 基本使用 四 选择器 五 等待元素被加载 六 元素交互操作 七 其他 八 项目练习 一 介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决r ...
- Python基础——数字类型int与float、字符串、列表、元组、字典、集合、可变类型与不可变类型、数据类型总结
文章目录 一 引子 二 数字类型int与float 2.1 定义 2.2 类型转换 2.3 使用 三 字符串 3.1 定义: 3.2 类型转换 3.3 使用 3.3.1 优先掌握的操作 3.3.2 需 ...