*应用方案
针对回调接口通知客户,目前想到了两种方案,本项目采用第二种方案。
方案一:采用ActiveMq的重发机制,配置好重发次数,间隔时间即可。但是,间隔时间只能一次性获取,也就是说如果设置重发次数6次,间隔1小时,那么在6小时内就会重发6次。不能达到支付宝微信他们的回调机制的效果,有待改进。
方案二:创建多个生产者以及对应的消费者和监听器,生产者1即时请求消费者1,消费者处理数据,调用客户接口,如果客户返回成功,那么就结束。如果客户返回失败,消费者1就去调用生产者2,生产者2根据配置好的延时时间,延时请求消费者2,消费者2处理数据,如果成功则结束,失败则调用生产者3,以此类推,知道最后一个生产者。
一.spring整合activeMQ
1.项目结构(maven项目,整合Spring 和ActiveMq)
2.首先在pom.xml里引入jar包
<!-- activemq -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>${activeMQ.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>${activeMQ.version}</version>
</dependency>
3.在spring-context-service.xml配置文件里引入ActiveMq的配置文件
4.配置spring-activemq.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!--<bean id="propertyConfigurer"-->
<!--class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">-->
<!--<property name="location" value="classpath:mq_config.properties" />-->
<!--</bean>-->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<!-- ActiveMQ服务地址 -->
<property name="brokerURL" value="${mq.brokerURL}" />
<property name="userName" value="${mq.userName}"></property>
<property name="password" value="${mq.password}"></property>
</bean>
<!--
ActiveMQ为我们提供了一个PooledConnectionFactory,通过往里面注入一个ActiveMQConnectionFactory
可以用来将Connection、Session和MessageProducer池化,这样可以大大的减少我们的资源消耗。
要依赖于 activemq-pool包
-->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="targetConnectionFactory" />
<property name="maxConnections" value="20" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
</bean>
<!--这个是队列目的地-->
<bean id="queueDestination1" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字,多队列在这里用逗号分隔配置 -->
<constructor-arg>
<value>backMessage1</value>
</constructor-arg>
</bean>
<bean id="queueDestination2" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字,多队列在这里用逗号分隔配置 -->
<constructor-arg>
<value>backMessage2</value>
</constructor-arg>
</bean>
<bean id="queueDestination3" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 设置消息队列的名字,多队列在这里用逗号分隔配置 -->
<constructor-arg>
<value>backMessage3</value>
</constructor-arg>
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate1" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${back.message1}"></property>
</bean>
<bean id="jmsTemplate2" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${back.message2}"></property>
</bean>
<bean id="jmsTemplate3" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestinationName" value="${back.message3}"></property>
</bean>
<!-- 配置消息队列监听者(Queue) -->
<bean id="queueMessageListener1" class="com.fast.pay.sync.mq.MessageListener1" />
<!-- 配置消息队列监听者(Queue) -->
<bean id="queueMessageListener2" class="com.fast.pay.sync.mq.MessageListener2" />
<!-- 配置消息队列监听者(Queue) -->
<bean id="queueMessageListener3" class="com.fast.pay.sync.mq.MessageListener3" />
<!-- 显示注入消息监听容器(Queue),配置连接工厂,queueDestination,监听器是上面定义的监听器 -->
<bean id="queueListenerContainer1"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueDestination1" />
<property name="messageListener" ref="queueMessageListener1" />
</bean>
<!-- 显示注入消息监听容器(Queue),配置连接工厂,queueDestination,监听器是上面定义的监听器 -->
<bean id="queueListenerContainer2"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueDestination2" />
<property name="messageListener" ref="queueMessageListener2" />
</bean>
<!-- 显示注入消息监听容器(Queue),配置连接工厂,queueDestination,监听器是上面定义的监听器 -->
<bean id="queueListenerContainer3"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueDestination3" />
<property name="messageListener" ref="queueMessageListener3" />
</bean>
</beans>
5.程序中使用消息队列
该消息队列应用在用户支付成功后,支付结果回调通知业务平台。
(1)把activemq.xml配置的消息队列目的地注入进来
(2)第一次发送消息
@Override
public void sendBackMessage1(Destination destination1, final String msg){
System.out.println(Thread.currentThread().getName()+" 向队列"+destination1.toString()+"发送消息---------------------->"+msg);
jmsTemplate1.send(destination1, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
TextMessage message = session.createTextMessage(msg);
/*long time = 60 * 1000;// 延时1min
long period = 10 * 1000;// 每隔10s
int repeat = 1;// 到达延时时间发送成功后,再发送6次
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);//延迟投递的时间
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);//重复投递的时间间隔
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);//重复投递次数*/
System.out.println("发送消息:" + "ActiveMQ ---------------sendBackMessage1" + msg.toString());
return message;
}
});
}
(3)消息监听器1接收消息并处理
6.设置消息延时发送
*根据项目需要,第一次发送消息后,如果业务平台接收失败,第二次需要延时半小时发送,第三次需要延时两小时发送
(1)首先在进入activemq的安装目录下的conf目录下
(2)编辑activemq.xml,设置为延时发送机制
(2)程序中开启延时发送
*第二次发送消息延迟半小时后发送
(3)使用相应的监听器处理消息
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181219145707809.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzk0NTk4Mw==,size_16,color_FFFFFF,t_70
。
。
。
*觉得有用可以关注博主哦,如果再不能相遇,祝你早午晚都安。。。