前言
传统java想要集成rocketmq来发送消息,如果改框架,必定耗时耗力,且稳定性无法保障。本文讲讲述非springboot的传统java如果快速集成rocketmq,不分析原理,只讲使用。
mq的搭建和配置请参考官方文档,本文不做讲解。
提示:以下是本篇文章正文内容,下面案例可供参考
一、rocketmq是什么?
RocketMQ 是阿里巴巴开源的分布式消息中间件。支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。它里面有几个区别于标准消息中件间的概念,如Group、Topic、Queue等。系统组成则由Producer、Consumer、Broker、NameServer等。详细介绍传送门:RocketMQ之一:RocketMQ整体介绍
二、集成步骤
1.引入依赖
代码如下:
<!-- rocketmq相关依赖 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId>
<version>4.6.0</version>
</dependency>
2.rocketmq工具类
代码如下:
import com.dc.open.eureka.apollo.ApolloClient;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
/**
* @author 系统异常
* Time 2021-11-30 15:51
* Description:RocketMq工具类
* @version 1.0
*/
public class RocketMqProducerHelper {
private static final Logger logger = LoggerFactory.getLogger(RocketMqProducerHelper.class);
private static RocketMqProducerHelper instance = null;
private DefaultMQProducer producer = null;
public static RocketMqProducerHelper getInstance() {
if (instance == null) {
synchronized (RocketMqProducerHelper.class) {
if (instance == null) {
instance = new RocketMqProducerHelper();
}
}
}
return instance;
}
/**
* 构造方法,可用于服务器中运行,参数是从apollo上获取,也可以改成其他方式获取
*/
public RocketMqProducerHelper() {
try {
String namesrvAddr = ApolloClient.externalServiceConfig.getProperty(("rocketmq.namesrvAddr"), null);
String producerGroup = ApolloClient.externalServiceConfig.getProperty(("rocketmq.producerGroup"), null);
boolean retryAnotherBrokerWhenNotStoreOk = Boolean.parseBoolean(ApolloClient.externalServiceConfig.getProperty(("rocketmq.retryAnotherBrokerWhenNotStoreOk"), null));
int sendTimeOut = Integer.parseInt(ApolloClient.externalServiceConfig.getProperty(("rocketmq.sendTimeOut"), null));
int retryTimesWhenSendFailed = Integer.parseInt(ApolloClient.externalServiceConfig.getProperty(("rocketmq.retryTimesWhenSendFailed"), null));
// mq账号(大概是这个意思)
String accessKey = ApolloClient.externalServiceConfig.getProperty(("rocketmq.accessKey"), null);
// mq密码(大概是这个意思)
String secretKey = ApolloClient.externalServiceConfig.getProperty(("rocketmq.secretKey"), null);
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(secretKey)) {
producer = new DefaultMQProducer();
producer.setProducerGroup(producerGroup);
} else {
producer = new DefaultMQProducer(producerGroup, new AclClientRPCHook(new SessionCredentials(accessKey, secretKey)));
}
producer.setNamesrvAddr(namesrvAddr);
producer.setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOk);
producer.setSendMsgTimeout(sendTimeOut);
producer.setRetryTimesWhenSendFailed(retryTimesWhenSendFailed);
// producer.setVipChannelEnabled(false);
// Producer对象在使用之前必须要调用start初始化,初始化一次即可
// 注意:切记不可以在每次发送消息时,都调用start方法
producer.start();
logger.info("[{}:{}] start successd!", producerGroup, namesrvAddr);
} catch (Exception e) {
logger.error("RocketMQ初始化异常", e);
}
}
/**
* 构造方法,可以用于本地测试
*
* @param namesrvAddr NameServer地址列表,多个nameServer地址用分号隔开
* @param producerGroup Producer组名,多个Producer如果属于一个应用,发送同样的消息,则应该将它们归为同一组。
* @param retryAnotherBrokerWhenNotStoreOk 如果发送消息返回sendResult,但是sendStatus!=SEND_OK,是否重试发送
* @param sendTimeOut 发送消息超时时间,单位毫秒
* @param retryTimesWhenSendFailed 发送失败重试次数
* @param accessKey 账号
* @param secretKey 密码
*/
public RocketMqProducerHelper(String namesrvAddr, String producerGroup, boolean retryAnotherBrokerWhenNotStoreOk, int sendTimeOut, int retryTimesWhenSendFailed, String accessKey, String secretKey) {
try {
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(secretKey)) {
producer = new DefaultMQProducer();
producer.setProducerGroup(producerGroup);
} else {
producer = new DefaultMQProducer(producerGroup, new AclClientRPCHook(new SessionCredentials(accessKey, secretKey)));
}
producer.setNamesrvAddr(namesrvAddr);
producer.setRetryAnotherBrokerWhenNotStoreOK(retryAnotherBrokerWhenNotStoreOk);
producer.setSendMsgTimeout(sendTimeOut);
producer.setRetryTimesWhenSendFailed(retryTimesWhenSendFailed);
// producer.setVipChannelEnabled(false);
// Producer对象在使用之前必须要调用start初始化,初始化一次即可
// 注意:切记不可以在每次发送消息时,都调用start方法
producer.start();
logger.info("[{}:{}] start successd!", producerGroup, namesrvAddr);
} catch (Exception e) {
logger.error("RocketMQ初始化异常", e);
}
}
/**
* 销毁
*/
public void destroy() {
if (producer != null) {
logger.info("producer: [{}:{}] end ", producer.getProducerGroup(), producer.getNamesrvAddr());
producer.shutdown();
}
}
/**
* 发送MQ消息
*
* @param topic 主题
* @param tags 官方的解释,是第二主题,子主题
* @param keys 消息关键词,据说是查找用的
* @param msgBody 消息内容
*/
public void send(String topic, String tags, String keys, String msgBody) {
try {
Message msg = new Message(topic, tags, keys, msgBody.getBytes(StandardCharsets.UTF_8));
logger.info("发送MQ消息详情 --->" + "topic --->" + topic + " tags --->" + tags + " keys --->" + keys + " msgBody --->" + msgBody);
producer.send(msg);
} catch (Exception e) {
logger.error(keys.concat(":发送消息失败"), e);
}
}
}
3.测试方法
/**
* @author 系统异常
* Time 2021-11-30 16:12
* Description:MQ测试类
* @version 1.0
*/
public class MQTest {
public static void main(String[] args) {
String namesrvAddr = "xxx.xxx.xxx.xxx:9876";
String producerGroup = "producerGroup";
boolean retryAnotherBrokerWhenNotStoreOK = true;
Integer sendTimeOut = 3000;
Integer retryTimesWhenSendFailed = 3;
String accessKey = "zhangsan";
String secretKey = "password";
RocketMqProducerHelper rocketMqProducerHelper = new RocketMqProducerHelper(namesrvAddr, producerGroup, retryAnotherBrokerWhenNotStoreOK, sendTimeOut, retryTimesWhenSendFailed, accessKey, secretKey);
rocketMqProducerHelper.send("test_topic", "", "", "{\"testkey\":\"testvalue\",\"content\":{\"name\":\"张三\"}}");
System.out.println("发送成功");
rocketMqProducerHelper.destroy();
}
}