SpringBoot集成RocketMQ(简单版)

本文讲解SpringBoot如何集成RocketMQ(简单版),合适初学者。

后面还有一篇进阶版。SpringBoot集成RocketMQ(进阶版)

一、首先新建一个maven项目(也可以直接新建一个springboot项目)

导入如下jar包

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-boot-version>2.0.2.RELEASE</spring-boot-version>
    <fastjson-version>1.2.38</fastjson-version>
    <rocketmq-version>3.5.9</rocketmq-version>
    <commons-lang-version>2.6</commons-lang-version>
  </properties>

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- 添加spring boot需要的两个jar包 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>${spring-boot-version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>${spring-boot-version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>${spring-boot-version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <version>${spring-boot-version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>${fastjson-version}</version>
    </dependency>
    <!--整合rocketMQ-->
    <dependency>
      <groupId>com.alibaba.rocketmq</groupId>
      <artifactId>rocketmq-common</artifactId>
      <version>${rocketmq-version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba.rocketmq</groupId>
      <artifactId>rocketmq-client</artifactId>
      <version>${rocketmq-version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>${commons-lang-version}</version>
    </dependency>
  </dependencies>

二、application.properties 配置文件,目录格式如下。

SpringBoot集成RocketMQ(简单版)_第1张图片
在resources目录下新建一个application.properties文件。文件配置如下;

server.port=7777

rocketmq.producer.groupName=vehicleProducerGroup
rocketmq.producer.namesrvAddr=192.168.1.242:9876//根据自己的地址修改
rocketmq.producer.instanceName=vehicleProducer
rocketmq.producer.topic=topic2019
rocketmq.producer.tag=test
rocketmq.producer.maxMessageSize=131072
rocketmq.producer.sendMsgTimeout=10000

rocketmq.consumer.namesrvAddr=192.168.1.242:9876
rocketmq.consumer.groupName=vehicleProducerGroup
rocketmq.consumer.topic=topic2019
rocketmq.consumer.tag=test
rocketmq.consumer.consumeThreadMin=20
rocketmq.consumer.consumeThreadMax=64

三、producer、consumer配置

目录结构:

SpringBoot集成RocketMQ(简单版)_第2张图片

(1)先看RocketMQProducer这个类
package com.lw.study.rocketmq.producer;

import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.lw.study.exception.RocketMQException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;


/**
 * @author: 
 * @Date: 16:46 2019/1/15
 */
@Component
public class RocketMQProducer {
    private static final Logger log = LoggerFactory.getLogger(RocketMQProducer.class);
    //使用Value注解加载配置文件的配置
    @Value("${rocketmq.producer.groupName}")
    private String groupName;
    @Value("${rocketmq.producer.namesrvAddr}")
    private String nameserAddr;
    @Value("${rocketmq.producer.instanceName}")
    private String instanceName;
    @Value("${rocketmq.producer.maxMessageSize}")
    private int maxMessageSize;
    @Value("${rocketmq.producer.sendMsgTimeout}")
    private int sendMsgTimeout;

    private DefaultMQProducer producer;
    @Bean
    public DefaultMQProducer getRocketMQProducer() {
       
        producer = new DefaultMQProducer(groupName);
        producer.setNamesrvAddr(nameserAddr);
        producer.setInstanceName(instanceName);
        producer.setMaxMessageSize(maxMessageSize);
        producer.setSendMsgTimeout(sendMsgTimeout);
        producer.setVipChannelEnabled(false);

        try {
            producer.start();
            log.info("rocketMQ is start !!groupName : {},nameserAddr:{}",groupName,nameserAddr);
        } catch (MQClientException e) {
            log.error(String.format("rocketMQ start error,{}",e.getMessage()));
            e.printStackTrace();
        }
        return producer;
    }

}

(2)MessageProcessor消息处理接口
package com.lw.study.rocketmq.message;
import com.alibaba.rocketmq.common.message.MessageExt;

/**
 * @author:
 * @Date: 19:25 2019/1/15
 */
public interface MessageProcessor {
    boolean handle(MessageExt messageExt);
}

MessageProcessorImpl实现接口
package com.lw.study.rocketmq.message.impl;

import com.alibaba.rocketmq.common.message.MessageExt;
import com.lw.study.rocketmq.message.MessageProcessor;
import org.springframework.stereotype.Service;

/**
 * @author: 
 * @Date: 19:26 2019/1/15
 */
@Service
public class MessageProcessorImpl implements MessageProcessor {
    @Override
    public boolean handle(MessageExt messageExt) {
    //这里收到的body(也就是消息体)是字节类型,转为String
        String result = new String(messageExt.getBody());
        System.out.println("收到了消息:"+ result);
        return true;
    }
}

(3)MessageListen消息监听类

必须要实现MessageListenerConcurrently这个类。消费者收到消息后,就会调用里面的consumeMessage()方法,按照我们的需求去处理消息。

package com.lw.study.rocketmq.message;


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.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
 * @author: 
 * @Date: 19:29 2019/1/15
 */
public class MessageListen implements MessageListenerConcurrently {
    @Autowired
    private MessageProcessor messageProcessor;

    public void setMessageProcessor(MessageProcessor messageProcessor) {
        this.messageProcessor = messageProcessor;
    }

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
        MessageExt ext = list.get(0);
        boolean result = messageProcessor.handle(ext);
        if (!result) {
            return ConsumeConcurrentlyStatus.RECONSUME_LATER;
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}

(4)RocketMQConsumer
package com.lw.study.rocketmq.consumer;

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.lw.study.exception.RocketMQException;
import com.lw.study.rocketmq.message.MessageListen;

import com.lw.study.rocketmq.message.MessageProcessor;
import org.apache.commons.lang.StringUtils;
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.context.annotation.Bean;
import org.springframework.stereotype.Component;




/**
 * @author: 
 * @Date: 17:15 2019/1/15
 */
@Component
public class RocketMQConsumer  {
    private static final Logger log = LoggerFactory.getLogger(RocketMQConsumer.class);
    @Autowired
    private MessageProcessor messageProcessor;

    @Value("${rocketmq.consumer.namesrvAddr}")
    private String namesrvAddr;
    @Value("${rocketmq.consumer.groupName}")
    private String groupName;
    @Value("${rocketmq.consumer.topic}")
    private String topic;
    @Value("${rocketmq.consumer.tag}")
    private String tag;
    @Value("${rocketmq.consumer.consumeThreadMin}")
    private int consumeThreadMin;
    @Value("${rocketmq.consumer.consumeThreadMax}")
    private int consumeThreadMax;

    @Bean
    public DefaultMQPushConsumer getRocketMQConsumer() 
    {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
        consumer.setNamesrvAddr(namesrvAddr);
        consumer.setConsumeThreadMin(consumeThreadMin);
        consumer.setConsumeThreadMax(consumeThreadMax);
        consumer.setVipChannelEnabled(false);
        //我们自己实现的监听类
        MessageListen messageListen = new MessageListen();
        messageListen.setMessageProcessor(messageProcessor);
        consumer.registerMessageListener(messageListen);
        try {
            consumer.subscribe(topic,tag);
            consumer.start();
            log.info("consume is start ,groupName:{},topic:{}",groupName,topic);
        } catch (MQClientException e) {
            log.error("consume start error");
            e.printStackTrace();
        }
        return consumer;
    }


}
(5)最后在Application类中写个发消息的方法。
package com.lw.study;


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.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

/**
 * @author: 
 * @Date: 17:36 2019/1/15
 */
@SpringBootApplication
public class Application {
    public static void main(String[] args) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        ApplicationContext context = SpringApplication.run(Application.class,args);
        DefaultMQProducer producer = context.getBean(DefaultMQProducer.class);
        for(int i = 0; i < 10; i ++) {
            String body = "hello rocketMQ" + i;
            //注意,第一个参数是topic,第二个tag,要和配置文件保持一致,第三个是body,也就是我们要发的消息,字节类型。
            Message message = new Message("topic2019", "test", body.getBytes());
            SendResult result = producer.send(message);
            Thread.sleep(1000);
        }
        //关闭资源
        producer.shutdown();
        System.out.println("producer shutdown!");

//        System.out.println("send:"+ result);

    }
}

好了,来run一下main方法。

SpringBoot集成RocketMQ(简单版)_第3张图片
oh yeah!成功了。

碰到的几个问题
  • 问题:org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.lw.study.Application]; nested exception is java.lang.NoSuchMethodError: org.springframework.util.Assert.notNull(Ljava/lang/Object;Ljava/util/function/Supplier;)V
    解决:springboot版本不一致导致,将spring-boot-starter-parent版本与其他springboot包的版本改为统一的

  • 问题:Exception in thread “main” com.alibaba.rocketmq.client.exception.MQClientException: The producer service state not OK, CREATE_JUST
    解决:DefaultMQProducer 构造失败,构造参数为空。
    使用 DefaultMQProducer producer = context.getBean(DefaultMQProducer.class);来构建

你可能感兴趣的:(学习笔记,框架集成)