阿里MQ普通+顺序+延时消息 整合Spring
来源:互联网 发布:梦幻修仙2数据库修改 编辑:程序博客网 时间:2024/05/16 08:23
前言
由于公司项目需要,研究了下AliWareMQ。阿里mq的普通消息和延时消息还是挺简单的。不过在顺序消息的时候出现了一些瓶颈。后来查阅源码和依据demo整理了一版融合Spring的版本。
实例
mq配置文件(Spring)
主要是顺序消息的配置,以及多实例的配置(需要在控制台配置p/c)
<?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-4.2.xsd"> <!--MQ生产者相关开始--> <bean id="producer" class="com.aliyun.openservices.ons.api.bean.ProducerBean" init-method="start" destroy-method="shutdown"> <property name="properties"> <map> <entry key="ProducerId" value="${ProducerId}"/> <!-- PID,请替换 --> <entry key="AccessKey" value="${AccessKey}"/> <!-- ACCESS_KEY,请替换 --> <entry key="SecretKey" value="${SecretKey}"/> <!-- SECRET_KEY,请替换 --> <entry key="ONSAddr" value="${ONSAddr}"/> </map> </property> </bean> <!--顺序消息--> <bean id="mqOrderProducer" class="com.rqbao.mq.listenter.MQOrderProducer" init-method="start" destroy-method="shutdown"> <constructor-arg name="producerProperties"> <props> <prop key="ProducerId">${OrderProducerId}</prop> <prop key="AccessKey">${AccessKey}</prop> <prop key="SecretKey">${SecretKey}</prop> <prop key="ONSAddr">${ONSAddr}</prop> <prop key="ORDER_TOPIC">${ORDER_TOPIC}</prop> <prop key="TAG">1111</prop> </props> </constructor-arg> </bean> <!--MQ生产者相关结束--> <!--MQ消费者相关开始--> <bean id="consumer" class="com.aliyun.openservices.ons.api.bean.ConsumerBean" init-method="start" destroy-method="shutdown"> <property name="properties"> <map> <entry key="ConsumerId" value="${OrderConsumerId}"/> <!-- 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="messageListener"> <key> <bean class="com.aliyun.openservices.ons.api.bean.Subscription"> <property name="topic" value="${topic}"/> <!-- Topic,请替换 --> <property name="expression" value="*"/><!-- MessageType名: 多个messageType 用 “||”分割 --> </bean> </key> </entry> </map> </property> </bean> <!--顺序消息--> <bean id="consumerOrder" class="com.rqbao.mq.listenter.MQOrderConsumer" init-method="start" destroy-method="shutdown"> <constructor-arg name="consumerProperties"> <props> <prop key="ConsumerId">${ConsumerId}</prop> <prop key="AccessKey">${AccessKey}</prop> <prop key="SecretKey">${SecretKey}</prop> <prop key="ONSAddr">${ONSAddr}</prop> <prop key="ORDER_TOPIC">${ORDER_TOPIC}</prop> <prop key="TAG">1111</prop> </props> </constructor-arg> </bean> <!-- 消息处理器 --> <bean id="messageListener" class="com.rqbao.mq.listenter.MQListener"/> <!--顺序--> <!--MQ消费者相关结束--></beans>
顺序生产者
package com.rqbao.mq.listenter;import com.aliyun.openservices.ons.api.ONSFactory;import com.aliyun.openservices.ons.api.order.OrderProducer;import java.util.Properties;/** * Created by ricky on 2017/7/2. */public class MQOrderProducer { private Properties producerProperties = new Properties(); private OrderProducer producer; public MQOrderProducer(Properties producerProperties) { this.producerProperties = producerProperties; producer = ONSFactory.createOrderProducer(producerProperties); } public OrderProducer getOrderProducer(){ return producer; } public void start(){ new MQOrderProducer(producerProperties); producer.start(); } public void shutdown(){ producer.shutdown(); } public Properties getProducerProperties() { return producerProperties; } public void setProducerProperties(Properties producerProperties) { this.producerProperties = producerProperties; } public OrderProducer getProducer() { return producer; } public void setProducer(OrderProducer producer) { this.producer = producer; }}
顺序消费者
package com.rqbao.mq.listenter;import com.aliyun.openservices.ons.api.Message;import com.aliyun.openservices.ons.api.ONSFactory;import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;import com.aliyun.openservices.ons.api.order.MessageOrderListener;import com.aliyun.openservices.ons.api.order.OrderAction;import com.aliyun.openservices.ons.api.order.OrderConsumer;import java.util.Properties;/** * Created by ricky on 2017/7/2. */public class MQOrderConsumer { private Properties consumerProperties = new Properties(); private OrderConsumer consumer; public MQOrderConsumer(Properties consumerProperties) { this.consumerProperties = consumerProperties; consumer = ONSFactory.createOrderedConsumer(consumerProperties); consumer.subscribe(consumerProperties.get("ORDER_TOPIC").toString(), consumerProperties.get("TAG").toString(), new MessageOrderListener() { @Override public OrderAction consume(final Message message, final ConsumeOrderContext context) { System.out.println(message); return OrderAction.Success; } }); } public void start(){ new MQOrderProducer(consumerProperties); consumer.start(); } public void shutdown(){ consumer.shutdown(); } public Properties getConsumerProperties() { return consumerProperties; } public void setConsumerProperties(Properties consumerProperties) { this.consumerProperties = consumerProperties; } public OrderConsumer getConsumer() { return consumer; } public void setConsumer(OrderConsumer consumer) { this.consumer = consumer; }}
参数文件
#ALiMQ相关参数#入钥AccessKey=XXXXXX#秘钥SecretKey=XXXXXXX#阿里云MQ线上地址#PropertyKeyConst.ONSAddr 请根据不同Region进行配置#公网测试: http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet#公有云生产: http://onsaddr-internal.aliyun.com:8080/rocketmq/nsaddr4client-internal#杭州金融云: http://jbponsaddr-internal.aliyun.com:8080/rocketmq/nsaddr4client-internal#深圳金融云: http://mq4finance-sz.addr.aliyun.com:8080/rocketmq/nsaddr4client-internalONSAddr=http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet#主题topic=RICKY_CGBUSINESS_LOCALORDER_TOPIC=RICKY_CGBUSINESS_TEST#生产者IdProducerId=PID_RICKYCG_LOCALOrderProducerId=PID_RICKYCG_TEST#消费者ConsumerId=CID_RICKYCG_LOCALOrderConsumerId=CID_RICKYCG_TEST
顺序消息生产
mport com.aliyun.openservices.ons.api.Message;import com.aliyun.openservices.ons.api.SendResult;import com.aliyun.openservices.ons.api.order.OrderProducer;import com.rqbao.mq.common.config.Global;import org.apache.log4j.Logger;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.Date;import java.util.UUID;/** * Created by ricky on 2017/6/8. *MQ消息生产功能,可能附加一些其他功能 */@Servicepublic class MQOrderService implements InitializingBean{ private static final Logger logger = Logger.getLogger(MQOrderService.class); @Autowired MQOrderProducer mqOrderProducer; /** * 发送顺序MQ消息 * @param TAG 业务tag tag将使用CGUTILS中的存管接口变量 * @param msg 需传递对应接口需要参数,格式待考究 * delayTime 延迟时间 3000--->3s * @return */ public String sendOrderMQMsg(String TAG,String msg){ OrderProducer producer=mqOrderProducer.getOrderProducer(); Message message = new Message(Global.getConfig("ORDER_TOPIC"), TAG,msg.getBytes()); // 设置代表消息的业务关键属性,请尽可能全局唯一。 String orderId = "rqb_" + UUID.randomUUID().toString().replaceAll("-",""); message.setKey(orderId); // 分区顺序消息中区分不同分区的关键字段,sharding key于普通消息的key是完全不同的概念。 // 全局顺序消息,该字段可以设置为任意非空字符串。 String shardingKey = String.valueOf(orderId); SendResult sendResult = producer.send(message, shardingKey); if (sendResult != null) { System.out.println(new Date() + " Send mq message success! Topic is:" + Global.getConfig("topic") + "msgId is: " + sendResult.getMessageId()); } return sendResult.toString(); } @Override public void afterPropertiesSet() throws Exception { }}
顺序消息消费
具体在MQOrderConsumer中写消费处理
关于延时和定时消息
依据官方说明,延时消息必须是无序的topic,切记。
可参阅官方文档
问题
MQ存在重复消费的问题,我这里的解决方案是进行MQ消息记录,比如消息有tag再加上body中相关的业务id,联合组成唯一索引,避免重复消费问题。
附demo地址:
http://git.oschina.net/bgt0314/alimq_demo
交流群
244930845 不懂的欢迎进群咨询。
阅读全文
2 0
- 阿里MQ普通+顺序+延时消息 整合Spring
- MQ发送延时消息
- MQ收发顺序消息
- spring 整合ibm mq 发送和接收消息
- spring整合activemq发送MQ消息[Topic模式]实例,activemqmq
- Spring整合JMS、IBM MQ发送和接收消息
- MQ消息队列--RabbitMQ整合Spring理论及实例讲解
- Spring整合ActiveMQ完成消息队列MQ编程
- Spring 整合 ibm mq
- Spring整合mq
- 阿里RocketMQ消息队列与Spring整合+Xml配置
- MQ与Spring的整合
- springMVC+MQ 消息队列整合(一)
- springMVC+MQ 消息队列整合(二)
- Active MQ延时发送消息的Java示例代码段
- 利用DelayQueue实现延时消息队列(简易版MQ)
- Active MQ延时发送消息的Java示例代码段
- 利用DelayQueue实现延时消息队列(简易版MQ)
- 不忘初心 二次创业
- 平凡浙商人 感动点滴间
- 小灶
- Tomcat项目部署的三种方法
- Codeforces Round #422 (Div. 2) D. My pretty girl Noora(数论)
- 阿里MQ普通+顺序+延时消息 整合Spring
- [Unity]2D&3D物体指向indicator鼠标,技能指示器 基础
- Error creating bean with name 'PictureController': Injection of autowired dependence解决方法
- [Unity]箭头2D图片精灵的Pivot锚点怎么设置
- Android studio中如何将Module依赖到主工程
- GitChat在做什么
- input标签内正则验证
- 关闭chrome浏览器的developer tools
- HTML5 Canvas中 fillText() 和 strokeText() 的区别