Spring MVC 集成 RocketMQ

因为项目中需要使用mq进行模块解耦操作,项目为SSM项目 找了好久没有相关源码,所以按照网上的文章自己集成了一个:

一、载入依赖

		<dependency>
		    <groupId>com.alibaba.rocketmq</groupId>
		    <artifactId>rocketmq-client</artifactId>
		    <version>3.2.6</version>
		</dependency>

二、配置创建spring-context-rocketmq.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd" >

       
       <description>RocketMQ Configuration</description>

	<!-- 加载配置属性文件 --> 此处可以省略,是因为我们系统载入配置文件
    <context:property-placeholder ignore-unresolvable="true" location="classpath:jeesite.properties" />
       
       //配置消费者类(监听类)
       <bean id="messageListeners" class="com.thinkgem.jeesite.common.utils.RocketMq.RocketMqConsumer"></bean>

	    <!-- 配置消费者 -->
	    <bean id="rocketmqConsumer" class="com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer" init-method="start" destroy-method="shutdown">
	        <property name="consumerGroup" value="PushConsumer2"/>//订阅组名
	        <property name="namesrvAddr" value="${rocketMQ.address}"/>//mq地址
	        <property name="messageListener" ref="messageListeners"/>
	        <property name="subscription">
	            <map>
	                <entry key="PushTopic">//组名
	                    <value>*</value>
	                </entry>
	            </map>
	        </property>
	    </bean>
	    
	    //生产者配置
	    <bean id="rocketMqProducer" class="com.thinkgem.jeesite.common.utils.RocketMq.RocketMqProducer" init-method="init" destroy-method="destroy">
	        <property name="producerGroup" value="PushConsumer"/>
	        <property name="namesrvAddr" value="${rocketMQ.address}"/>
	    </bean>
       
</beans>

此处有几个坑没有注意,记录一下以防止重复犯错:

1、启动SpringMVC后生产者、消费者均没有进行初始化

原因是因为XML声明是多加了:  default-lazy-init="true"  删除即可

2、生产者发送消息后,监听者没有监听到消息,管理后台查询无订阅组:

原因是因为生产者、消费者的Group Value重复了,导致冲突。名称分别区分即可解决

三、配置生产者、消费者管理类

import java.io.UnsupportedEncodingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.common.message.Message;

public class RocketMqProducer {
    private final static Logger logger = LoggerFactory.getLogger(RocketMqProducer.class);
   
    private static DefaultMQProducer defaultMQProducer;
    private String producerGroup;
    private String namesrvAddr;
    
    /**
     * Spring bean init-method
     */
    public void init() throws MQClientException {
        // 参数信息
        logger.info("DefaultMQProducer initialize!");
        logger.info(producerGroup);
        logger.info(namesrvAddr);
        // 初始化
        defaultMQProducer = new DefaultMQProducer(producerGroup);
        defaultMQProducer.setNamesrvAddr(namesrvAddr);
        defaultMQProducer.setInstanceName(String.valueOf(System.currentTimeMillis()));
        defaultMQProducer.start();
        logger.info("DefaultMQProudcer start success!");
 
    }
 
    /**
     * Spring bean destroy-method
     */
    public void destroy() {
        defaultMQProducer.shutdown();
    }
    public DefaultMQProducer getDefaultMQProducer() {
        return defaultMQProducer;
    }
    // ---------------setter -----------------
 
    public void setProducerGroup(String producerGroup) {
        this.producerGroup = producerGroup;
    }
 
    public void setNamesrvAddr(String namesrvAddr) {
        this.namesrvAddr = namesrvAddr;
    }
   
    /**
     * rocketmq发送消息方法
     *
     * @param topic 组名
     * @param tagName 同一个topic下的不同 分支,同一个消费者只能取一个组的下的不同的tag分支
     * @param key 保持唯一
     * @param msgBody消息体
     * @return
     */
    public static void sendMsgIntime(String topic, String tagName, String key, String msgBody) {
        Message msg = null;
        try {
            msg = new Message(topic,tagName,key,msgBody.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            String result = defaultMQProducer.send(msg).toString();
            logger.info("send rockmq topic:" + topic + " " + result);
        } catch (Exception e) {
            logger.error("send rockmq error topic:" + topic + new String(msgBody), e);
        }
    }
}

package com.thinkgem.jeesite.common.utils.RocketMq;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

public class RocketMqConsumer implements MessageListenerConcurrently{

    private static final Logger log = LoggerFactory.getLogger(RocketMqConsumer.class);
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        for (MessageExt messageExt : msgs) {
            log.info("# {}", messageExt);
            try {
                String body = new String(messageExt.getBody(), "UTF-8");
                log.info("# {}", body);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            //System.out.println(messageExt.toString());
            //System.out.println(new String(messageExt.getBody()));
        }
        log.info("# getDelayLevelWhenNextConsume={} , getMessageQueue={} , getDelayLevelWhenNextConsume={}", context.getDelayLevelWhenNextConsume(), context.getMessageQueue(), context.getDelayLevelWhenNextConsume());
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}
注:MQ发送中文会出现乱码的问题,使用msgBody.getBytes("UTF-8")即可解决

四、测试调试类:

import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.thinkgem.jeesite.common.utils.RocketMq.RocketMqProducer;

@Controller
@RequestMapping(value = "${frontPath}/mq")
public class TestMqController {
    private static Logger logger = LoggerFactory.getLogger(TestMqController.class);
    
    @Autowired
    private RocketMqProducer rocketMqProducer;
 
    @RequestMapping("/getLoginfo")
    public String helloWord(){
        String consumerStr =  "666";
        logger.info("消费信息:" +consumerStr);
 
        //发送消息
        Map<String, Object> msg = new HashMap<>();
        msg.put("carNum", "浙A888888");
        msg.put("code", "778882222");
        RocketMqProducer.sendMsgIntime("PushTopic",
                "push",
                "",
                JSON.toJSONString(msg));
        return "消费信息:" +consumerStr;
    }
}

调用:/f/mq/getLoginfo 成功接收消息

2021-05-22 19:18:53,233 DEBUG [jeesite.modules.sys.interceptor.LogInterceptor] - 开始计时: 07:18:53.233  URI: /f/mq/getLoginfo
2021-05-22 19:18:53,247 INFO  [modules.cms.web.front.TestMqController] - 消费信息:666
2021-05-22 19:18:53,257 INFO  [jeesite.common.utils.RocketMq.RocketMqProducer] - send rockmq topic:PushTopic SendResult [sendStatus=SEND_OK, msgId=A9FEC16200002A9F000000000000044C, messageQueue=MessageQueue [topic=PushTopic, brokerName=PC-20180613WXLB, queueId=0], queueOffset=3]
2021-05-22 19:18:53,262 INFO  [jeesite.common.utils.RocketMq.RocketMqConsumer] - # MessageExt [queueId=0, storeSize=185, queueOffset=3, sysFlag=0, bornTimestamp=1621682333251, bornHost=/169.254.193.98:59821, storeTimestamp=1621682333254, storeHost=/169.254.193.98:10911, msgId=A9FEC16200002A9F000000000000044C, commitLogOffset=1100, bodyCRC=974590328, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message [topic=PushTopic, flag=0, properties={CLUSTER=DefaultCluster, TAGS=push, WAIT=true, MAX_OFFSET=4, MIN_OFFSET=0}, body=42]]
2021-05-22 19:18:53,262 INFO  [jeesite.common.utils.RocketMq.RocketMqConsumer] - # {"carNum":"浙A888888","code":"778882222"}
2021-05-22 19:18:53,262 INFO  [jeesite.common.utils.RocketMq.RocketMqConsumer] - # getDelayLevelWhenNextConsume=0 , getMessageQueue=MessageQueue [topic=PushTopic, brokerName=PC-20180613WXLB, queueId=0] , getDelayLevelWhenNextConsume=0
2021-05-22 19:18:53,270 INFO  [jeesite.modules.sys.interceptor.LogInterceptor] - ViewName: 消费信息:666
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值