RocketMQ整合Spring基础Java实战

1.RocketMQ安装

  1. 首先需要安装maven工具,因为RocketMq是使用java代码实现的,官方的工程使用maven构建,所以需要现在本地安装maven工具

  2. 下载 RocketMq 压缩包,将压缩文件解压到想要安装的目录

    #我的是MAC环境,所以这里以mac环境为例
    #解压并进入安装目录
    cd /Users/kangning/apache/rocketmq/
    unzip rocketmq-all-4.4.0-source-release.zip
    
  3. 使用maven编译下载的源文件

    #进入文件目录
    cd rocketmq-all-4.4.0/
    #对源文件进行编译
    mvn -Prelease-all -DskipTests clean install -U
    
  4. 启动Name Server

    #进入变异完的目录
    cd distribution/target/apache-rocketmq
    #启动Name Server
    nohup sh bin/mqnamesrv &
    #查看是否启动 成功
    tail -f ~/logs/rocketmqlogs/namesrv.log
    #出现:**The Name Server boot success...** 说明成功
    
  5. 启动Broker

    #启动Broker
    nohup sh bin/mqbroker -n localhost:9876 &
    #查看是否启动成功
    tail -f ~/logs/rocketmqlogs/broker.log 
    #出现 **The broker[%s, 172.30.30.233:10911] boot success...**	说明启动成功
    
  6. 关闭服务

    #关闭broker
    sh bin/mqshutdown broker
    #出现如下则成功:**The mqbroker(36695) is running... Send shutdown request to mqbroker(36695) OK**
    #关闭nameserver
    sh bin/mqshutdown namesrv
    #出现如下则成功:**The mqnamesrv(36664) is running... Send shutdown request to mqnamesrv(36664) OK**
    

2.RocketMQ客户端

  1. 进入rocketmq-externals项目GitHub地址,选择对应的rocketmq-console分支,如下图,可以看到对应的代码,将代码clone到本地。因为只需要分支的代码,所以下载对应的分支就可以
    $ git clone -b release-rocketmq-console-1.0.0 https://github.com/apache/rocketmq-externals.git
    

RocketMQ整合Spring基础Java实战_第1张图片

  1. 进入项目文件夹并修改配置文件

    cd rocketmq-externals/rocketmq-console/
    vi src/main/resources/application.properties
    

    配置文件内容:

    #管理后台访问上下文路径,默认为空,如果填写,一定要前面加“/”,后面不要加,否则启动报错
    server.contextPath=/rocketmq
    #访问端口
    server.port=8080
    #spring.application.index=true
    spring.application.name=rocketmq-console
    spring.http.encoding.charset=UTF-8
    spring.http.encoding.enabled=true
    spring.http.encoding.force=true
    #logback配置文件路径
    logging.config=classpath:logback.xml
    #if this value is empty,use env value rocketmq.config.namesrvAddr
    NAMESRV_ADDR | now, you can set it in ops page.default
    localhost:9876
    #Name Server地址,修改成你自己的服务地址
    rocketmq.config.namesrvAddr=10.0.74.198:9876;10.0.74.199:9876
    #if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel
    should be false.default true
    rocketmq.config.isVIPChannel=
    #rocketmq-console's data path:dashboard/monitor
    rocketmq.config.dataPath=/tmp/rocketmq-console/data
    #set it false if you don't want use dashboard.default true
    rocketmq.config.enableDashBoardCollect=true
    
  2. 编译jar包并启动客户端命令

    mvn clean package -Dmaven.test.skip=true
    java -jar target/rocketmq-console-ng-1.0.0.jar
    
  3. 访问路径本地路径:http://localhost:8080/rocketmq 即可在页面操作

3.发送/接收消息

首先需要在客户端创建消息队列:TestQueue

   1. 生产者代码实现
  1. 创建生产者代理对象
    /**
     * @author kangning Date: 2019-04-22 Time: 15:50
     * @version $Id$
     */
    public class CommonDemoProderProxy {
    
        private static final Logger logger = LoggerFactory.getLogger(CommonDemoProderProxy.class);
    
        private DefaultMQProducer defaultMQProducer;
    
        private String nameSrv;
    
        private String groupName;
    
        private String instanceName;
    
        private int retryTimes;
    
        public CommonDemoProderProxy(String nameSrv, String groupName, String instanceName, int retryTimes) {
            try {
                this.nameSrv = nameSrv;
                this.groupName = groupName;
                this.instanceName = instanceName;
                this.retryTimes = retryTimes;
                //新建生产者对象
                this.defaultMQProducer = new DefaultMQProducer(groupName);
                //设置nameserver
                this.defaultMQProducer.setNamesrvAddr(nameSrv);
                //设置实例名称
                this.defaultMQProducer.setInstanceName(instanceName);
                //设置失败重试次数
                this.defaultMQProducer.setRetryTimesWhenSendFailed(retryTimes);
                //启动实例
                this.defaultMQProducer.start();
            } catch (MQClientException e) {
                logger.error("init rocket produce error", e);
            }
        }
    
        /**
         * 实际调用生产者发送消息的接口
         * @param message
         * @return
         * @throws InterruptedException
         * @throws RemotingException
         * @throws MQClientException
         * @throws MQBrokerException
         */
        public SendResult sendMsg(Message message) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
            return defaultMQProducer.send(message);
        }
    
    
        public DefaultMQProducer getDefaultMQProducer() {
            return defaultMQProducer;
        }
    
        public void setDefaultMQProducer(DefaultMQProducer defaultMQProducer) {
            this.defaultMQProducer = defaultMQProducer;
        }
    
        public String getNameSrv() {
            return nameSrv;
        }
    
        public void setNameSrv(String nameSrv) {
            this.nameSrv = nameSrv;
        }
    
        public String getGroupName() {
            return groupName;
        }
    
        public void setGroupName(String groupName) {
            this.groupName = groupName;
        }
    
        public String getInstanceName() {
            return instanceName;
        }
    
        public void setInstanceName(String instanceName) {
            this.instanceName = instanceName;
        }
    
        public int getRetryTimes() {
            return retryTimes;
        }
    
        public void setRetryTimes(int retryTimes) {
            this.retryTimes = retryTimes;
        }
    
        @Override
        public String toString() {
            return "CommonDemoProderProxy{" +
                "defaultMQProducer=" + defaultMQProducer +
                ", nameSrv='" + nameSrv + '\'' +
                ", groupName='" + groupName + '\'' +
                '}';
        }
    }
    
    
  2. 配置生产者代理信息
    	<bean id="commonDemoProderProxy" class="com.kangning.demo.framework.mq.CommonDemoProderProxy">
            <constructor-arg name="groupName" value="${rocketmq.group}"/>
            <constructor-arg name="nameSrv" value="${rocketmq.namespace}"/>
            <constructor-arg name="instanceName" value="${rocketmq.instanceName}"/>
            <constructor-arg name="retryTimes" value="${rocketmq.retryTimes}"/>
        bean>
    
  3. 添加基础生产者抽象类
    /**
     * @author kangning Date: 2019-04-22 Time: 16:39
     * @version $Id$
     */
    public abstract class BaseCommonProducer<T> {
    
        private static final Logger logger = LoggerFactory.getLogger(BaseCommonProducer.class);
    
        @Autowired
        private CommonDemoProderProxy commonDemoProderProxy;
    
        private String topicName;
    
        public SendResult sendMsg(T object){
            Message message = new Message(this.getTopicName(), JSONObject.toJSONString(object).getBytes());
            try {
                return commonDemoProderProxy.sendMsg(message);
            } catch (InterruptedException | RemotingException | MQClientException | MQBrokerException e) {
                logger.error("send rocketMq msg error", e);
                e.printStackTrace();
            }
            return null;
        }
    
        public String getTopicName() {
            return topicName;
        }
    
        public void setTopicName(String topicName) {
            this.topicName = topicName;
        }
    }
    
  4. 添加具体生产者实现类
    /**
     * @author kangning Date: 2019-04-22 Time: 16:57
     * @version $Id$
     */
    public class TestProducer extends BaseCommonProducer<RegionInfo> {
    }
    
  5. 配置具体生产者信息
        <bean id="testProducer" class="com.kangning.demo.rocketmq.producer.TestProducer">
            <property name="topicName" value="TestQueue"/>
        bean>
    
   2. 消费者代码实现
  1. 创建消费者公共抽象类(用于规范共有的业务逻辑以及接收到消息之后回调接口处理消息)
    /**
     * @author kangning Date: 2019-04-22 Time: 16:39
     * @version $Id$
     */
    public abstract class BaseCommonConsumer<T> {
    
        private static final Logger logger = LoggerFactory.getLogger(BaseCommonConsumer.class);
    
        public abstract boolean receive(MessageExt messageExt);
    }
    
    
  2. 添加具体的消费者实现
    
    /**
     * @author kangning Date: 2019-04-22 Time: 17:09
     * @version $Id$
     */
    public class TestConsumer extends BaseCommonConsumer<RegionInfo> {
    	@Override
     	public boolean receive(MessageExt messageExt) {
    	   String msgStr = new String(messageExt.getBody());
           RegionInfo regionInfo = JSONObject.parseObject(msgStr,RegionInfo.class);
            System.out.println(regionInfo.getRegionCN());
            return true;
        }
    }
    
  3. 配置消费者bean
    <bean id="testConsumer" class="com.kangning.demo.rocketmq.consumer.TestConsumer"/>
    
  4. 添加消费者代理类
    /**
     * @author kangning Date: 2019-04-22 Time: 17:17
     * @version $Id$
     */
    public class CommonDemoConsumerProxy {
    
        private static final Logger logger = LoggerFactory.getLogger(CommonDemoConsumerProxy.class);
    
        private final Map<String, BaseCommonConsumer> topics;
    
        private String nameSrv;
    
        private String groupName;
    
        private DefaultMQPushConsumer defaultMQPushConsumer;
    
        private String messageModel;
    
        private int reconsumeTimes;
    
        public CommonDemoConsumerProxy(Map<String, BaseCommonConsumer> topics, String nameSrv, String groupName, String messageModel, int reconsumeTimes) {
    
            //检查消息队列配置
            if (CollectionUtils.isEmpty(topics)){
                logger.error("no topic={} for group", groupName);
                topics = new HashMap<>(0);
            }
            this.topics = topics;
            this.nameSrv = nameSrv;
            this.groupName = groupName;
            this.defaultMQPushConsumer = new DefaultMQPushConsumer();
            this.messageModel = messageModel;
            this.reconsumeTimes = reconsumeTimes;
    
            MessageModel enumMessageModel = null;
            if (StringUtils.isNoneBlank(this.messageModel)){
                enumMessageModel = EnumUtils.getEnum(MessageModel.class, this.messageModel);
            }
            //初始化消费者信息
            initConsumer(topics, nameSrv, groupName, enumMessageModel, reconsumeTimes);
        }
    
        private void initConsumer(Map<String, BaseCommonConsumer> topics,String nameSrv, String groupName, MessageModel messageModel, int reconsumeTimes) {
            try {
                //设置nameserver
                this.defaultMQPushConsumer.setNamesrvAddr(nameSrv);
                //设置消费者组
                this.defaultMQPushConsumer.setConsumerGroup(groupName);
                //设置启动时消费起始点
                this.defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
                //设置消费失败重试次数
                this.defaultMQPushConsumer.setMaxReconsumeTimes(reconsumeTimes);
                //设置消费模式
                if (messageModel == null){
                    //默认集群模式
                    this.defaultMQPushConsumer.setMessageModel(MessageModel.CLUSTERING);
                }else {
                    this.defaultMQPushConsumer.setMessageModel(messageModel);
                }
                //订阅消费队列
                for (Entry<String, BaseCommonConsumer> entry : topics.entrySet()){
                    this.defaultMQPushConsumer.subscribe(entry.getKey(), "*");
                }
                //注册回调接口
                this.defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() {
                    //消费消息
                    @Override
                    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                        for (MessageExt messageExt : msgs){
                            //获取消息队列对应的具体消费者
                            BaseCommonConsumer baseCommonConsumer = topics.get(messageExt.getTopic());
                            if (baseCommonConsumer == null){
                                logger.error("no topic={} for service", messageExt.getTopic());
                            }
                            try {
                                //调用回调接口receive处理消息
                                if (baseCommonConsumer== null || !baseCommonConsumer.receive(messageExt)){
                                    //返回消费失败
                                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                                }
                            } catch (Exception var6) {
                                logger.error("consumer message error", var6);
                                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                            }
                        }
                        //返回消费成功
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }
                });
                //启动消费者实例
                this.defaultMQPushConsumer.start();
            } catch (MQClientException e) {
                logger.error("init rocket consumer error", e);
            }
        }
    
        public Map<String, BaseCommonConsumer> getTopics() {
            return topics;
        }
    
        public String getNameSrv() {
            return nameSrv;
        }
    
        public void setNameSrv(String nameSrv) {
            this.nameSrv = nameSrv;
        }
    
        public String getGroupName() {
            return groupName;
        }
    
        public void setGroupName(String groupName) {
            this.groupName = groupName;
        }
    
        public DefaultMQPushConsumer getDefaultMQPushConsumer() {
            return defaultMQPushConsumer;
        }
    
        public void setDefaultMQPushConsumer(DefaultMQPushConsumer defaultMQPushConsumer) {
            this.defaultMQPushConsumer = defaultMQPushConsumer;
        }
    
        public String getMessageModel() {
            return messageModel;
        }
    
        public void setMessageModel(String messageModel) {
            this.messageModel = messageModel;
        }
    
        public int getReconsumeTimes() {
            return reconsumeTimes;
        }
    
        public void setReconsumeTimes(int reconsumeTimes) {
            this.reconsumeTimes = reconsumeTimes;
        }
    
        @Override
        public String toString() {
            return "CommonDemoConsumerProxy{" +
                "topics=" + topics +
                ", nameSrv='" + nameSrv + '\'' +
                ", groupName='" + groupName + '\'' +
                ", defaultMQPushConsumer=" + defaultMQPushConsumer +
                ", messageModel='" + messageModel + '\'' +
                ", reconsumeTimes=" + reconsumeTimes +
                '}';
        }
    }
    
    
  5. 配置消费者代理对象信息
    <bean id="commonDemoConsumerProxy" class="com.kangning.demo.framework.mq.CommonDemoConsumerProxy">
            <constructor-arg name="groupName" value="TestGroup"/>
            <constructor-arg name="nameSrv" value="${rocketmq.namespace}"/>
            <constructor-arg name="topics">
                <map>
                    <entry key="TestQueue" value-ref="testConsumer"/>
                map>
            constructor-arg>
            
            <constructor-arg name="messageModel" value="CLUSTERING"/>
            <constructor-arg name="reconsumeTimes" value="3"/>
        bean>
    

到这里一个简单的RocketMQ就基本实现了,启动项目,发送消息即可收到信息

你可能感兴趣的:(java,RocketMQ)