return producer;
}
}
4.新建消费者
package cn.baocl.rocketmq.consumer;
import cn.baocl.rocketmq.processor.MQConsumeMsgListenerProcessor;
import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
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.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;
@SpringBootConfiguration
public class MQConsumerConfiguration {
public static final Logger LOGGER = LoggerFactory.getLogger(MQConsumerConfiguration.class);
@Value(“${rocketmq.consumer.namesrvAddr}”)
private String namesrvAddr;
@Value(“${rocketmq.consumer.groupName}”)
private String groupName;
@Value(“${rocketmq.consumer.consumeThreadMin}”)
private int consumeThreadMin;
@Value(“${rocketmq.consumer.consumeThreadMax}”)
private int consumeThreadMax;
@Value(“${rocketmq.consumer.topics}”)
private String topics;
@Value(“${rocketmq.consumer.consumeMessageBatchMaxSize}”)
private int consumeMessageBatchMaxSize;
@Autowired
private MQConsumeMsgListenerProcessor mqMessageListenerProcessor;
@Bean
public DefaultMQPushConsumer testRocketMQConsumer() throws Exception {
if (StringUtils.isEmpty(groupName)){
throw new Exception(“groupName is null !!!”);
}
if (StringUtils.isEmpty(namesrvAddr)){
throw new Exception(“namesrvAddr is null !!!”);
}
if(StringUtils.isEmpty(topics)){
throw new Exception(“topics is null !!!”);
}
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
consumer.setNamesrvAddr(namesrvAddr);
consumer.setConsumeThreadMin(consumeThreadMin);
consumer.setConsumeThreadMax(consumeThreadMax);
consumer.registerMessageListener(mqMessageListenerProcessor);
/**
-
设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费
-
如果非第一次启动,那么按照上次消费的位置继续消费
*/
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
/**
- 设置消费模型,集群还是广播,默认为集群
*/
//consumer.setMessageModel(MessageModel.CLUSTERING);
/**
- 设置一次消费消息的条数,默认为1条
*/
consumer.setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize);
try {
/**
- 设置该消费者订阅的主题和tag,如果是订阅该主题下的所有tag,则tag使用*;如果需要指定订阅该主题下的某些tag,则使用||分割,例如tag1||tag2||tag3
*/
String[] topicTagsArr = topics.split(“;”);
for (String topicTags : topicTagsArr) {
String[] topicTag = topicTags.split(“~”);
consumer.subscribe(topicTag[0],topicTag[1]);
}
consumer.start();
LOGGER.info(“consumer is start !!! groupName:{},topics:{},namesrvAddr:{}”,groupName,topics,namesrvAddr);
}catch (MQClientException e){
LOGGER.error(“consumer is start !!! groupName:{},topics:{},namesrvAddr:{}”,groupName,topics,namesrvAddr,e);
throw new Exception(e);
}
return consumer;
}
}
5.新建处理类
package cn.baocl.rocketmq.processor;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Component
public class MQConsumeMsgListenerProcessor implements MessageListenerConcurrently {
private static final Logger logger = LoggerFactory.getLogger(MQConsumeMsgListenerProcessor.class);
/**
-
默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息
-
不要抛异常,如果没有return CONSUME_SUCCESS ,consumer会重新消费该消息,直到return CONSUME_SUCCESS
*/
@Override
public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
if(CollectionUtils.isEmpty(msgs)){
logger.info(“接受到的消息为空,不处理,直接返回成功”);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
MessageExt messageExt = msgs.get(0);
logger.info(“接受到的消息为:”+messageExt.toString());
if(messageExt.getTopic().equals(“你的Topic”)){
if(messageExt.getTags().equals(“你的Tag”)){
//TODO 判断该消息是否重复消费(RocketMQ不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重)
//TODO 获取该消息重试次数
int reconsume = messageExt.getReconsumeTimes();
if(reconsume ==3){//消息已经重试了3次,如果不需要再次消费,则返回成功
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
//TODO 处理对应的业务逻辑
}
}
// 如果没有return success ,consumer会重新消费该消息,直到return success
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
6.接口调用
package cn.baocl.rocketmq.controllor;
import cn.baocl.rocketmq.entity.TestVo;
import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendCallback;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(“/test”)
public class TestControllor {
private static final Logger logger = LoggerFactory.getLogger(TestControllor.class);
/**
- 使用RocketMq的生产者
*/
@Autowired
private DefaultMQProducer defaultMQProducer;
@RequestMapping(“/send”)
public void send() throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
String msg = “demo msg test”;;
logger.info(“开始发送消息:” + msg);
Message sendMsg = new Message(“DemoTopic”, “DemoTag”, msg.getBytes());
最后
Mapping(“/send”)
public void send() throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
String msg = “demo msg test”;;
logger.info(“开始发送消息:” + msg);
Message sendMsg = new Message(“DemoTopic”, “DemoTag”, msg.getBytes());
最后
[外链图片转存中…(img-OPgKnyMn-1720026183547)]
[外链图片转存中…(img-qu2Suv0m-1720026183548)]