Springboot2.3集成RocketMQ4.7.1

首先要部署安装rocketmq服务, 安装教程请看上篇文章

切入正题,springboot 集成rocketmq 要pom引入rocketmq-client 注意一定和安装的rocketmq版本保持一致;

<dependency>
			<groupId>org.apache.rocketmq</groupId>
			<artifactId>rocketmq-client</artifactId>
			<version>4.7.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.rocketmq</groupId>
			<artifactId>rocketmq-common</artifactId>
			<version>4.7.1</version>
		</dependency>

而后 编写Producer生产者初始化代码



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.common.protocol.heartbeat.MessageModel;
import org.springframework.stereotype.Component;

@Component
public class Producer {

    private static  String producerGroup = "test_producer_group";


    private static DefaultMQProducer producer;


    public static DefaultMQProducer getProducer() {

        if (producer == null) {
   /**
     * 生产者group名
     */
            producer = new DefaultMQProducer(producerGroup);
            producer.setVipChannelEnabled(false);
   /**
     * Name Server 地址,因为是集群部署 所以有多个用 分号 隔开
     */
            producer.setNamesrvAddr(RocketMqConfig.NAME_SERVER);
/**
     * 主题名称 主题一般是服务器设置好 而不能在代码里去新建topic( 如果没有创建好,生产者往该主题发送消息 会报找不到topic错误)
     */
            producer.setCreateTopicKey(RocketMqConfig.TOPIC);

            try {
                producer.start();
            } catch (MQClientException e) {
                e.printStackTrace();
            }
        }

        return producer;
    }

    /**
     * 一般在应用上下文,使用上下文监听器,进行关闭
     */
    public void shutdown(){
        producer.shutdown();
    }

consume  消费者代码

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * InitializingBean 项目启动时候加载
 */
@Component
public class Consumer implements InitializingBean {
    /**
     * 消费者实体对象
     */

    private DefaultMQPushConsumer  consumer;

    /**
     * 消费者组
     */
    public static final String CONSUMER_GROUP = "test_consumer";

    /**
     *构造函数 实例化对象
     */

    public DefaultMQPushConsumer getPushConsumer () {
        if (null != consumer)
            return consumer;
        consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);
        consumer.setNamesrvAddr(RocketMqConfig.NAME_SERVER);
        //消费模式:一个新的订阅组第一次启动从队列的最后位置开始消费
        // 后续再启动接着上次消费的进度开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        /**
         * 监听拉取消息
         */
        consumer.registerMessageListener(new TestListenerConcurrently());
        try {
            consumer.subscribe(RocketMqConfig.TOPIC, "*");
            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        return consumer;


    }


    @Override
    public void afterPropertiesSet() throws Exception {
        DefaultMQPushConsumer consumer = getPushConsumer();

    }

编写监听要实现

org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently接口 或者 org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly接口 

他们之间主要区别是MessageListenerConcurrently 无序消费,MessageListenerOrderly 是顺序消费

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 *
 * 无序消费MessageListenerConcurrently
 * 顺序消费MessageListenerOrderly
 *
 */


public class TestListenerConcurrently implements MessageListenerConcurrently {
    static final Log log = LogFactory.getLog(TestListenerConcurrently.class);

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
        String body = null;

        for (MessageExt messageExt : list) {

            try {
                body = new String(messageExt.getBody(), "utf-8");

//                jsonMsg = JSON.parseObject(body);

                log.info("consume收到消息:" + body);

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                //消息消费失败 重新放入队列
                reSendPushToMq(messageExt);
            } catch (Exception e ) {
                e.printStackTrace();

                reSendPushToMq(messageExt);

            }


        }
        //返回消费成功状态码  ,报错或者返回null broker 则会重新推消息,注意幂等性判断
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;

    }


    /**
     * 重新发 推送消息 发送到队列中
     * @param message
     */
    public void reSendPushToMq(Message message) {
        try {
            SendResult result = Producer.getProducer().send(message);
            if (SendStatus.SEND_OK != result.getSendStatus()) {
                log.error("reSendPushToMq > " + result.toString());
            }
        } catch (Exception e) {
            log.error("reSendPushToMq Exception " + e.getMessage());
//            reSendPushToMq(message);
        }
    }
}

测试类 这里方便测试就写了个定时任务 来定时生产消息

import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class TaskController {

    private static Logger logger = LoggerFactory.getLogger(TaskController.class);


    @Scheduled(cron = "0/10 * * * * ?") // 每10s执行一次
    public void task() throws Exception {


        LocalDateTime localDateTime = LocalDateTime.now();
        Thread.currentThread().setName(UUID.randomUUID().toString());
        String msg=new StringBuffer().append(localDateTime + ":" + Thread.currentThread().getName()).toString();
        org.apache.rocketmq.common.message.Message message=
                new org.apache.rocketmq.common.message.Message(RocketMqConfig.TOPIC,msg.getBytes("utf-8"));


        java.util.Random random= new  java.util.Random(); // 定义随机类
        int  radnow=random.nextInt( 10 );
        logger.info("radnow : " + radnow );
        ExecutorService threadPool = ExecutorUtils.getTaskExecutor();
        for (int i = 0; i <radnow; i++) {
            SendResult result = Producer.getProducer().send(message);
            //返回状态码 ok则发送成功
            if(SendStatus.SEND_OK!=result.getSendStatus()){
                logger.error(result.toString() );
            } else {
                logger.info(Thread.currentThread().getName() + " : 发送成功");
            }


        }





    }

}

启动springboot 项目  

同时,看 rocketmq-console 控制台消息

 

TIPS:遇到的问题

No route info of this topic  TESTcotip

可能是pom引用  rocketmq-client版本不对

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值