Pom文件添加
<!--begin rocketMq -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.2.0</version>
</dependency>
<!--end rocketMq -->
<!-- 导入配置文件处理器,配置文件进行绑定就会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.1.10.RELEASE</version>
</dependency>
配置文件application.properties
#rocketmq
###producer
#该应用是否启用生产者
rocketmq.producer.isOnOff=on
#发送同一类消息的设置为同一个group,保证唯一,默认不需要设置,rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示
rocketmq.producer.groupName=hmop
#mq的nameserver地址,集群的时候用分号分隔多个127.0.0.1:9876;127.0.0.1:9877
rocketmq.producer.namesrvAddr=49.235.21.109:9876
#消息最大长度 默认1024*4(4M)
rocketmq.producer.maxMessageSize=4096
#发送消息超时时间,默认3000
rocketmq.producer.sendMsgTimeout=30000
#发送消息失败重试次数,默认2
rocketmq.producer.retryTimesWhenSendFailed=2
###consumer
##该应用是否启用消费者
rocketmq.consumer.isOnOff=on
rocketmq.consumer.groupName=hmop
#mq的nameserver地址
rocketmq.consumer.namesrvAddr=49.235.21.109:9876
#该消费者订阅的主题和tags("*"号表示订阅该主题下所有的tags),格式:topic~tag1||tag2||tag3;topic2~*;
rocketmq.consumer.topics=test_topic~*;
rocketmq.consumer.consumeThreadMin=20
rocketmq.consumer.consumeThreadMax=64
#设置一次消费消息的条数,默认为1条
rocketmq.consumer.consumeMessageBatchMaxSize=1
配置属性类
package com.hmop.tpda.core;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 创建人:sunp
* 创建时间:2020/4/8 0008
* 文件名:RocketMqConsumerProperties
* 版本 修改时间 作者
* V1.0 2020/4/8 0008 sunp
*/
@Component
@ConfigurationProperties(prefix = "rocketmq.consumer")
@Data
public class RocketMqConsumerProperties {
private String isOnOff;
private String groupName;
private String namesrvAddr;
private String topics;
private Integer consumeThreadMin;
private Integer consumeThreadMax;
private Integer consumeMessageBatchMaxSize;
}
package com.hmop.tpda.core;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 创建人:sunp
* 创建时间:2020/4/8 0008
* 文件名:RocketMqProducerProperties
* 版本 修改时间 作者
* V1.0 2020/4/8 0008 sunp
*/
@Component
@ConfigurationProperties(prefix = "rocketmq.producer")
@Data
public class RocketMqProducerProperties {
private String isOnOff;
private String groupName;
private String namesrvAddr;
private Integer maxMessageSize;
private Integer sendMsgTimeout;
private Integer retryTimesWhenSendFailed;
}
配置类
package com.hmop.tpda.configuration;
import com.hmop.tpda.core.RocketMqConsumerProperties;
import com.hmop.tpda.core.RocketMqProducerProperties;
import com.hmop.tpda.listener.RocketMQConsumeMsgListenerProcessor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* 创建人:sunp
* 创建时间:2020/4/8
* 文件名:RocketMQConfig
* 版本 修改时间 作者
* V1.0 2020/4/8 sunp
*/
@Configuration
@Slf4j
public class RocketMQConfig {
@Resource
private RocketMqProducerProperties rocketMqProducerProperties;
@Resource
private RocketMqConsumerProperties rocketMqConsumerProperties;
@Resource
private RocketMQConsumeMsgListenerProcessor rocketMQConsumeMsgListenerProcessor;
/***
* 生产者
* @return
*/
@Bean
public DefaultMQProducer getRocketMQProducer() {
if (StringUtils.isEmpty(rocketMqProducerProperties.getGroupName())) {
throw new RuntimeException("rocketMq producer groupName is blank");
}
if (StringUtils.isEmpty(rocketMqProducerProperties.getNamesrvAddr())) {
throw new RuntimeException("rocketMq producer nameServerAddr is blank");
}
DefaultMQProducer producer;
producer = new DefaultMQProducer(rocketMqProducerProperties.getGroupName());
producer.setNamesrvAddr(rocketMqProducerProperties.getNamesrvAddr());
//如果需要同一个jvm中不同的producer往不同的mq集群发送消息,需要设置不同的instanceName
if (rocketMqProducerProperties.getMaxMessageSize() != null) {
producer.setMaxMessageSize(rocketMqProducerProperties.getMaxMessageSize());
}
if (rocketMqProducerProperties.getSendMsgTimeout() != null) {
producer.setSendMsgTimeout(rocketMqProducerProperties.getSendMsgTimeout());
}
//如果发送消息失败,设置重试次数,默认为2次
if (rocketMqProducerProperties.getRetryTimesWhenSendFailed() != null) {
producer.setRetryTimesWhenSendFailed(rocketMqProducerProperties.getRetryTimesWhenSendFailed());
}
try {
producer.start();
log.info(String.format("producer is start ! groupName:[%s],namesrvAddr:[%s]"
, rocketMqProducerProperties.getGroupName(), rocketMqProducerProperties.getNamesrvAddr()));
} catch (MQClientException e) {
log.error(String.format("producer is error {}"
, e.getMessage(), e));
throw new RuntimeException(e);
}
return producer;
}
/***
* 消费者
* @return
*/
@Bean
public DefaultMQPushConsumer getRocketMQConsumer() {
if (StringUtils.isEmpty(rocketMqConsumerProperties.getGroupName())) {
throw new RuntimeException("rocketMq consumer groupName is null !");
}
if (StringUtils.isEmpty(rocketMqConsumerProperties.getNamesrvAddr())) {
throw new RuntimeException("rocketMq consumer namesrvAddr is null !");
}
if (StringUtils.isEmpty(rocketMqConsumerProperties.getTopics())) {
throw new RuntimeException("rocketMq consumer topics is null !");
}
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(rocketMqConsumerProperties.getGroupName());
consumer.setNamesrvAddr(rocketMqConsumerProperties.getNamesrvAddr());
consumer.setConsumeThreadMin(rocketMqConsumerProperties.getConsumeThreadMin());
consumer.setConsumeThreadMax(rocketMqConsumerProperties.getConsumeThreadMax());
//消息消费处理类
consumer.registerMessageListener(rocketMQConsumeMsgListenerProcessor);
/**
* 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费
* 如果非第一次启动,那么按照上次消费的位置继续消费
*/
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
/**
* 设置消费模型,集群还是广播,默认为集群
*/
//consumer.setMessageModel(MessageModel.CLUSTERING);
/**
* 设置一次消费消息的条数,默认为1条
*/
consumer.setConsumeMessageBatchMaxSize(rocketMqConsumerProperties.getConsumeMessageBatchMaxSize());
try {
/**
* 设置该消费者订阅的主题和tag,如果是订阅该主题下的所有tag,则tag使用*;如果需要指定订阅该主题下的某些tag,则使用||分割,例如tag1||tag2||tag3
*/
String[] topicTagsArr = rocketMqConsumerProperties.getTopics().split(";");
for (String topicTags : topicTagsArr) {
String[] topicTag = topicTags.split("~");
consumer.subscribe(topicTag[0], topicTag[1]);
}
consumer.start();
log.info("consumer is start !!! groupName:{},topics:{},namesrvAddr:{}", rocketMqConsumerProperties.getGroupName(),
rocketMqConsumerProperties.getTopics(), rocketMqConsumerProperties.getNamesrvAddr());
} catch (MQClientException e) {
log.error("consumer is start !!! groupName:{},topics:{},namesrvAddr:{}" , rocketMqConsumerProperties.getGroupName(),
rocketMqConsumerProperties.getTopics(), rocketMqConsumerProperties.getNamesrvAddr(), e);
throw new RuntimeException(e);
}
return consumer;
}
}
消费处理类
package com.hmop.tpda.listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
* 创建人:sunp
* 创建时间:2020/4/8 0008
* 文件名:RocketMQConsumeMsgListenerProcessor
* 版本 修改时间 作者
* V1.0 2020/4/8 0008 sunp
*/
@Component
@Slf4j
public class RocketMQConsumeMsgListenerProcessor implements MessageListenerConcurrently {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
if(CollectionUtils.isEmpty(msgs)){
System.out.println("接受到的消息为空,不处理,直接返回成功");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
MessageExt messageExt = msgs.get(0);
System.out.println("接受到的消息为:"+messageExt.toString());
if("你的Topic".equals(messageExt.getTopic())){
if("你的Tag".equals(messageExt.getTags())){
//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;
}
}
测试代码
package com.hmop.tpda;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 创建人:sunp
* 创建时间:2020/4/8 0008
* 文件名:Test
* 版本 修改时间 作者
* V1.0 2020/4/8 0008 sunp
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class DefaultProductTest {
/**使用RocketMq的生产者*/
@Autowired
private DefaultMQProducer defaultMQProducer;
/**
* 发送消息
* @throws InterruptedException
* @throws MQBrokerException
* @throws RemotingException
* @throws MQClientException
*/
@Test
public void send() throws MQClientException, RemotingException, MQBrokerException, InterruptedException{
String msg = "demo msg test";
System.out.println("开始发送消息:"+msg);
Message sendMsg = new Message("test_topic","*",msg.getBytes());
//默认3秒超时
SendResult sendResult = defaultMQProducer.send(sendMsg);
System.out.println("消息发送响应信息:"+sendResult.toString());
}
}