阿里RocketMQ消息队列与Spring整合+Xml配置

来源:互联网 发布:linux下c语言删除文件 编辑:程序博客网 时间:2024/05/18 22:55

RocketMQ消息队列

一、什么是RocketMQ
RocketMQ是一款分布式、队列模型的消息中间件,具有以下特点:
1、支持严格的消息顺序;
2、支持Topic与Queue两种模式;
3、亿级消息堆积能力;
4、比较友好的分布式特性;
5、同时支持Push与Pull方式消费消息;

二、Spring中的配置
1. producer.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"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- 顺序执行(可分区): 单线程,一个执行完毕继续执行下一个            分区顺序消息中区分不同分区的关键字段,sharding key于普通消息的key是完全不同的概念。           全局顺序消息,该字段可以设置为任意非空字符串。        -->    <bean id="scProducer" class="com.aliyun.openservices.ons.api.bean.OrderProducerBean" init-method="start"          destroy-method="shutdown">        <property name="properties"> <!--生产者配置信息-->            <props>                <prop key="ProducerId">${ProducerId_SC}</prop> <!--请替换为自己的账户信息-->                <prop key="AccessKey">${AccessKey}</prop>                <prop key="SecretKey">${SecretKey}</prop>            </props>        </property>    </bean>    <!-- 普通模式:多线程 先进先出 -->    <bean id="mongoDBProducer" class="com.aliyun.openservices.ons.api.bean.ProducerBean" init-method="start"          destroy-method="shutdown">        <property name="properties"> <!--生产者配置信息-->            <props>                <prop key="ProducerId">${ProducerId_Mongodb}</prop> <!--请替换为自己的账户信息-->                <prop key="AccessKey">${AccessKey}</prop>                <prop key="SecretKey">${SecretKey}</prop>            </props>        </property>    </bean></beans>
  1. consumer.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>    <bean id="consumerSc" class="com.aliyun.openservices.ons.api.bean.OrderConsumerBean"          init-method="start" destroy-method="shutdown">        <property name="properties">            <map>                <entry key="ConsumerId" value="${ConsumerId_SC}"/> <!-- CID,请替换 -->                <entry key="AccessKey" value="${AccessKey}"/> <!-- ACCESS_KEY,请替换 -->                <entry key="SecretKey" value="${SecretKey}"/><!-- SECRET_KEY,请替换 -->                <entry key="ONSAddr" value="${ONSAddr}"/>            </map>        </property>        <property name="subscriptionTable">            <map>                <entry value-ref="messageListenerSc">                    <key>                        <bean class="com.aliyun.openservices.ons.api.bean.Subscription">                            <property name="topic" value="${Topic_SC}"/> <!-- Topic_SMS,请替换 -->                            <property name="expression" value="*"/><!-- MessageType名: 多个messageType 用 “||”分割 -->                        </bean>                    </key>                </entry>            </map>        </property>    </bean>    <bean id="consumerMongoDB" class="com.aliyun.openservices.ons.api.bean.ConsumerBean"          init-method="start" destroy-method="shutdown">        <property name="properties">            <map>                <entry key="ConsumerId" value="${ConsumerId_Mongodb}"/> <!-- CID,请替换 -->                <entry key="AccessKey" value="${AccessKey}"/> <!-- ACCESS_KEY,请替换 -->                <entry key="SecretKey" value="${SecretKey}"/><!-- SECRET_KEY,请替换 -->                <entry key="ONSAddr" value="${ONSAddr}"/>            </map>        </property>        <property name="subscriptionTable">            <map>                <entry value-ref="messageListenerMongoDB">                    <key>                        <bean class="com.aliyun.openservices.ons.api.bean.Subscription">                            <property name="topic" value="${Topic_Mongodb}"/> <!-- Topic_SMS,请替换 -->                            <property name="expression" value="*"/><!-- MessageType名: 多个messageType 用 “||”分割 -->                        </bean>                    </key>                </entry>            </map>        </property>    </bean>   <!-- 消息处理器 mongodb -->    <bean id="messageListenerMongoDB" class="com.ztyijia.erp.task.consumer.listener.MessageListenerMongoDBImpl"/>   <!-- 消息处理器 社交 -->    <bean id="messageListenerSc" class="com.ztyijia.erp.task.consumer.listener.MessageListenerScImpl"/></beans>

三、代码中的应用
1.发送消息 (顺序)

private boolean sendScMsg(OrderProducer producer, Message msg,String userId) {        try {            // 设置代表消息的业务关键属性,请尽可能全局唯一            // 以方便您在无法正常收到消息情况下,可通过MQ 控制台查询消息并补发            // 注意:不设置也不会影响消息正常收发            msg.setKey(getUniqueKey());            // 分区顺序消息中区分不同分区的关键字段,sharding key于普通消息的key是完全不同的概念。            // 全局顺序消息,该字段可以设置为任意非空字符串。            // 以userId分区            SendResult sendResult = producer.send(msg,userId);            assert sendResult != null;            System.out.println("mq send success: " + sendResult.getMessageId());            return true;        } catch (ONSClientException e) {            System.out.println("发送失败");            return false;        }    }
  1. 发送消息(普通)
private boolean sendMsg(Producer producer, Message msg) {        try {            // 设置代表消息的业务关键属性,请尽可能全局唯一            // 以方便您在无法正常收到消息情况下,可通过MQ 控制台查询消息并补发            // 注意:不设置也不会影响消息正常收发            msg.setKey(getUniqueKey());            SendResult sendResult = producer.send(msg);            assert sendResult != null;            System.out.println("mq send success: " + sendResult.getMessageId());            return true;        } catch (ONSClientException e) {            System.out.println("发送失败");            return false;        }    }
  1. 生产消息
 CommentBean commentBean = new CommentBean();        commentBean.setUserId(userId);        commentBean.setCommentId(commentId);        // 将对象序列化        byte[] commentBeanByte = TranscoderUtil.serialize(commentBean, CommentBean.class);        producerMQService.sendSCProducer(RocketMqTags.Comment_Point, commentBeanByte, userId.toString());
  1. 消费消息
package com.ztyijia.erp.task.consumer.listener;/** * mq监听 */public class MessageListenerScImpl implements MessageOrderListener {    @Autowired    @Qualifier(value = "scCommentTask")    private SCCommentTask commentTask;    @Override    public OrderAction consume(Message message, ConsumeOrderContext context) {        System.out.println("SMS Receive: " + message.getMsgID());        try {            String tag = message.getTag();            System.err.println("【当前的TAG】:【" + tag + "】");            // 序列化的消息内容            byte[] body = message.getBody();//            根据类型处理          if (tag.equals(RocketMqTags.Card_Num.toString())) {                // 评论点赞                ErpCard erpCard = TranscoderUtil.deserializeGetObj(body, ErpCard.class);                cardNumService.updateCardNum(erpCard);                return OrderAction.Success;            }            System.err.println("无数据");            return OrderAction.Success;        } catch (Exception e) {            //消费失败            System.err.println("【社交队列】消费出现异常");            e.printStackTrace();            return OrderAction.Suspend;        }    }}