本文将对rocktmq-spring-boot的设计实现做一个简单的介绍,读者可以通过本文了解将RocketMQ Client端集成为spring-boot-starter框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个spring-boot-starter工具包来配置,发送和消费RocketMQ消息。下面直接上代码。
org.apache.rocketmq
rocketmq-client
4.6.0
org.apache.rocketmq
rocketmq-common
4.6.0
# 消费者的组名
apache.rocketmq.consumer.PushConsumer=orderConsumer
# 生产者的组名
apache.rocketmq.producer.producerGroup=Producer
# NameServer地址
apache.rocketmq.namesrvAddr=127.0.0.1:9876
package com.core.controller;
import com.core.bean.JsonData;
import com.core.jms.MsgProducer;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
@RestController
@RequestMapping("/api/v1")
public class OrderRocketController {
@Autowired
private MsgProducer msgProducer;
/**
* 功能描述:微信支付回调接口
* @param msg 支付信息
* @param tag 消息二级分类
* @return
*/
@GetMapping("rocketorder")
public Object order(String msg, String tag) throws UnsupportedEncodingException, InterruptedException, RemotingException, MQClientException, MQBrokerException {
/**
* 创建一个消息实例,包含 topic、tag 和 消息体
*/
Message message=new Message("testTopic",tag,msg.getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult result=msgProducer.getProducer().send(message);
System.out.println("发送响应:MsgId:" + result.getMsgId() + ",发送状态:" + result.getSendStatus());
return JsonData.buildSuccess();
}
@GetMapping("comment")
public Object comment(String msg) throws MQClientException, RemotingException, MQBrokerException, InterruptedException, UnsupportedEncodingException{
/**
* 创建一个消息实例,包含 topic、tag 和 消息体
*/
Message message = new Message("commentTopic","add", msg.getBytes(RemotingHelper.DEFAULT_CHARSET));
//同步的方式,会有返回结果,发送的是普通消息
SendResult result = msgProducer.getProducer().send(message);
System.out.println("发送响应:MsgId:" + result.getMsgId() + ",发送状态:" + result.getSendStatus());
return JsonData.buildSuccess();
}
}
(1)MsgProducer //消息生成类
package com.core.jms;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MsgProducer {
/**
* 生产者的组名
*/
@Value("${apache.rocketmq.producer.producerGroup}")
private String producerGroup;
/**
* NameServer 地址
*/
@Value("apache.rocketmq.namesrvAddr")
private String namesrvAddr;
private DefaultMQProducer producer ;
public DefaultMQProducer getProducer(){
return this.producer;
}
@PostConstruct
public void init(){
//生产者的组名
producer=new DefaultMQProducer(producerGroup);
//指定NameServer地址,多个地址以 ; 隔开
//如 producer.setNamesrvAddr("192.168.100.141:9876;192.168.100.142:9876;192.168.100.149:9876");
producer.setNamesrvAddr(namesrvAddr);
producer.setVipChannelEnabled(false);
try {
/**
* Producer对象在使用之前必须要调用start初始化,只能初始化一次
*/
producer.start();
} catch (Exception e) {
e.printStackTrace();
}
// producer.shutdown(); 一般在应用上下文,关闭的时候进行关闭,用上下文监听器
}
}
(2)MsgConsumer //消息消费类
package com.core.jms;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class MsgConsumer {
/**
* 消费者的组名
*/
@Value("${apache.rocketmq.consumer.PushConsumer}")
private String consumerGroup;
/**
* NameServer 地址
*/
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
@PostConstruct
public void defaultMQPushConsumer(){
//消费者的组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
//指定NameServer地址,多个地址以 ; 隔开
consumer.setNamesrvAddr(namesrvAddr);
//设置consumer所订阅的Topic和Tag,*代表全部的Tag
try {
consumer.subscribe("testTopic","*");
//CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,跳过历史消息
//CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
//MessageListenerOrderly 这个是有序的
//MessageListenerConcurrently 这个是无序的,并行的方式处理,效率高很多
consumer.registerMessageListener((MessageListenerConcurrently) (list, context) -> {
try {
for (MessageExt messageExt : list) {
System.out.println("messageExt: " + messageExt);//输出消息内容
String messageBody = new String(messageExt.getBody(), RemotingHelper.DEFAULT_CHARSET);
System.out.println("消费响应:msgId : " + messageExt.getMsgId() + ", msgBody : " + messageBody);//输出消息内容
}
} catch (Exception e) {
e.printStackTrace();
return ConsumeConcurrentlyStatus.RECONSUME_LATER; //稍后再试
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; //消费成功
});
consumer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
}
}
其中,JsonData类:
package com.core.bean;
import java.io.Serializable;
/**
* 功能描述:响应结果类
*/
public class JsonData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer code; // 状态码 0 表示成功,1表示处理中,-1表示失败
private Object data; // 数据
private String msg;// 描述
public JsonData() {
}
public JsonData(Integer code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
// 成功,传入数据
public static JsonData buildSuccess() {
return new JsonData(0, null, null);
}
// 成功,传入数据
public static JsonData buildSuccess(Object data) {
return new JsonData(0, data, null);
}
// 失败,传入描述信息
public static JsonData buildError(String msg) {
return new JsonData(-1, null, msg);
}
// 失败,传入描述信息,状态码
public static JsonData buildError(String msg, Integer code) {
return new JsonData(code, null, msg);
}
// 成功,传入数据,及描述信息
public static JsonData buildSuccess(Object data, String msg) {
return new JsonData(0, data, msg);
}
// 成功,传入数据,及状态码
public static JsonData buildSuccess(Object data, int code) {
return new JsonData(code, data, null);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "JsonData [code=" + code + ", data=" + data + ", msg=" + msg
+ "]";
}
}
项目搭建好后,访问Controller层的@GetMapping路径,就可以产生消息,并且消费消息。
结果如下:
https://blog.csdn.net/sqzhao/article/details/54834761
https://blog.csdn.net/mayifan0/article/details/67633729
https://blog.csdn.net/a906423355/article/details/78192828