activeMQ 特点、实战

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

主要特点:

1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP

2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)

3. 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性

4. 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上

5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA

6. 支持通过JDBC和journal提供高速的消息持久化

7. 从设计上保证了高性能的集群,客户端-服务器,点对点

8. 支持Ajax

9. 支持与Axis的整合

10. 可以很容易得调用内嵌JMS provider,进行测试


task_dest为发送端的消息队列,接收端监听执行后将执行结果反回给defaultResponseQueue,发送端接收后根据参数保存数据库。两个项目的交互

applicationContext-jms.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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"
	default-lazy-init="true">


	<bean id="jmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
		<property name="connectionFactory">
			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
				<property name="brokerURL" value="tcp://192.168.1.100:61616" />
				<property name="closeTimeout" value="60000" />
				<!--<property name="userName" value="admin" /> -->
				<!--<property name="password" value="admin" /> -->
				<!--<property name="optimizeAcknowledge" value="true" /> -->
			</bean>
		</property>
	</bean>

	<!-- Spring JMS Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory">
			<ref bean="jmsConnectionFactory" />
		</property>
	</bean>


	<!--视频通道:发送消息目的地 -->
	<bean id="task_dest" name="task_dest" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg index="0">
			<value>task_dest</value>
		</constructor-arg>
	</bean>
	
<!-- 	<bean id="messageConverter" class="com.eciyuanjie.task.jms.converter.ObjectMessageConverter"/> -->
	
	<!--queue通道:消息回复目的地 -->
	<bean id="defaultResponseQueue" name="defaultResponseQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg index="0">
			<value>defaultResponseQueue</value>
		</constructor-arg>
	</bean>
	
	<!-- 消息回复监听器 -->  
	<bean id="defaultResponseListener" class="com.eciyuanjie.task.jms.listener.ResponseListener"/> 
	
	<!-- 消息回复监听容器 -->
	<bean id="responseListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="jmsConnectionFactory" />
		<property name="destination" ref="defaultResponseQueue" />
		<property name="messageListener" ref="defaultResponseListener" />
	</bean>
	
	<bean id="jmsServiceImpl" class="com.eciyuanjie.task.jms.service.impl.JmsServiceImpl"></bean>
</beans>
一端只需配置一个发送目的地标签,回复是接收别的项目的回复信息

ResponseListener

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.springframework.beans.factory.annotation.Autowired;

import com.eciyuanjie.task.service.TaskLogService;

public class ResponseListener implements MessageListener {
	
	@Autowired
	private TaskLogService taskLogService;
	
	@Override
	public void onMessage(Message message) {
		
		if(message instanceof TextMessage){
			TextMessage msg = (TextMessage)message;
			try {
				
				System.out.println("返回内容:-----------"+msg.getText());
				String []args = msg.getText().split("_");
				taskLogService.update(Integer.parseInt(args[2]));
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

发送代码

((JmsService) ApplicationContextHolder.getBean("jmsServiceImpl")).sendTextMessage(MessageType.task_info, ""+className+"_"+methodName+"_"+taskId);

MessageType是自己定义的枚举

public enum MessageType {
task_info
}

发送方法接口

import java.io.Serializable;
import java.util.Map;

import javax.jms.BytesMessage;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.eciyuanjie.task.constants.MessageType;
import com.eciyuanjie.task.jms.service.JmsService;

/**
 * @ClassName: JmsServiceImpl
 * @Description: TODO(消息队列服务)
 * @author Wei Xing
 * @date 2014年10月31日 下午2:44:22
 * 
 */
@Component
public class JmsServiceImpl implements JmsService {
	
	private static Log logger = LogFactory.getLog(JmsServiceImpl.class);

	@Autowired
	private JmsTemplate jmsTemplate;
	
	@Autowired
	@Qualifier("task_dest")
	private Destination destinationVideoTask;

	/**
	 * @Title: sendTextMessage
	 * @Description: TODO(发送Text消息)
	 * @author Wei Xing
	 * @param messageType
	 * @param message
	 * @throws
	 * @date 2014年10月31日 下午5:36:48
	 */
	@Override
	public void sendTextMessage(MessageType messageType, final String message) {
		Destination destination = null;
		logger.debug("messageType: " + messageType);
		logger.debug("message: " + message);
//		switch (messageType) {
//		case video_submit_topic:
			destination = this.destinationVideoTask;
//			break;
//		case seo_update_topic:
//			destination = this.destinationSeoTopic;
//			break;
//		}
		logger.debug("destination: " + destination);
		jmsTemplate.send(destination, new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				return session.createTextMessage(message);
			}
		});
	}

	/**
	 * @Title: sendMapMessage
	 * @Description: TODO(发送Map消息)
	 * @author Wei Xing
	 * @param messageType
	 * @param message
	 * @throws
	 * @date 2014年10月31日 下午5:36:48
	 */
	@Override
	public void sendMapMessage(MessageType messageType, final Map<String, Object> message) {
		Destination destination = null;
//		switch (messageType) {
//		case video_submit_topic:
			destination = this.destinationVideoTask;
//			break;
//		case seo_update_topic:
//			destination = this.destinationSeoTopic;
//			break;
//		}
		jmsTemplate.send(destination, new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				MapMessage MapMessage = session.createMapMessage();
				for (Map.Entry<String, Object> entry : message.entrySet()) {
					MapMessage.setObject((String) entry.getKey(), entry.getValue());
				}
				return MapMessage;
			}
		});
	}

	/**
	 * @Title: sendBytesMessage
	 * @Description: TODO(发送Bytes消息)
	 * @author Wei Xing
	 * @param messageType
	 * @param message
	 * @throws
	 * @date 2014年10月31日 下午5:36:48
	 */
	@Override
	public void sendBytesMessage(MessageType messageType, final byte[] message) {
		Destination destination = null;
//		switch (messageType) {
//		case video_submit_topic:
			destination = this.destinationVideoTask;
//			break;
//		case seo_update_topic:
//			destination = this.destinationSeoTopic;
//			break;
//		}
		jmsTemplate.send(destination, new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				BytesMessage bytesMessage = session.createBytesMessage();
				bytesMessage.writeBytes(message);
				return bytesMessage;
			}
		});
	}

	/**
	 * @Title: sendObjectMessage
	 * @Description: TODO(发送Object消息)
	 * @author Wei Xing
	 * @param messageType
	 * @param message
	 * @throws
	 * @date 2014年10月31日 下午5:36:48
	 */
	@Override
	public void sendObjectMessage(MessageType messageType, final Serializable message) {
		Destination destination = null;
//		switch (messageType) {
//		case video_submit_topic:
			destination = this.destinationVideoTask;
//			break;
//		case seo_update_topic:
//			destination = this.destinationSeoTopic;
//			break;
//		}
		jmsTemplate.send(destination, new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				return session.createObjectMessage(message);
			}
		});
	}

接收端application-jms.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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"
	default-lazy-init="true">


	<bean id="jmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
		<property name="connectionFactory">
			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
				<property name="brokerURL" value="tcp://192.168.1.100:61616" />
				<property name="closeTimeout" value="60000" />
				<!--<property name="userName" value="admin" /> -->
				<!--<property name="password" value="admin" /> -->
				<!--<property name="optimizeAcknowledge" value="true" /> -->
			</bean>
		</property>
	</bean>

	<!-- Spring JMS Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory">
			<ref bean="jmsConnectionFactory" />
		</property>
	</bean>
	
	
	<!--视频通道:发送消息目的地 -->
	<bean id="task_dest" name="task_dest" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg index="0">
			<value>task_dest</value>
		</constructor-arg>
	</bean>
	
	<!--queue通道:消息回复目的地 -->
	<bean id="defaultResponseQueue" name="defaultResponseQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg index="0">
			<value>defaultResponseQueue</value>
		</constructor-arg>
	</bean>
	
	<!--计划任务消息接收监听器 --> 
	<bean id="taskMessageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
		<constructor-arg>
			<bean class="com.eciyuanjie.jms.listener.TaskMessageListener" />
		</constructor-arg>
		<property name="defaultListenerMethod" value="receiveMessage"/>
		<property name="defaultResponseDestination" ref="defaultResponseQueue"/>
	</bean>
	
	<!--视频消息接收监听容器,多线程异步接受消息 -->
	<bean id="taskJmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="jmsConnectionFactory" />
		<property name="destination" ref="task_dest"/>
		<property name="messageListener" ref="taskMessageListener" />
		<property name="sessionTransacted" value="false" />
	</bean>
</beans>

task_dest为发送端的消息队列,接收端执行后将执行结果反回给defaultResponseQueue,发送端接收后根据参数保存数据库


import java.lang.reflect.Method;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;

import com.eciyuanjie.data.video.service.VideoService;
import com.eciyuanjie.jms.service.JmsService;
import com.eciyuanjie.utils.ApplicationContextHolder;

/**
 * @ClassName: VideoMessageListener
 * @Description: TODO(视频消息监听器)
 * @author Wei Xing
 * @date 2014年11月3日 下午3:04:57
 * 
 */
public class TaskMessageListener {
	
	@Autowired
	private VideoService videoService;
	
	@Autowired
	private JmsService jmsService;
	
	/**
	 * @Title: handleMessage
	 * @Description: TODO(String)
	 * @author Wei Xing
	 * @param message
	 * @throws
	 * @date 2014年11月3日 下午3:04:57
	 */
	public String receiveMessage(String message) {
			
			String []args = message.split("_");
			
			
			try {
				Class targetClass = Class.forName(args[0]);
				Object object =  ApplicationContextHolder.getApplicationContext().getBean(targetClass);
				
				Method method = targetClass.getMethod(args[1]);
				method.invoke(object, new Object[]{});
			} catch (BeansException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}			
			
	<span style="white-space:pre">		System.out.println("--------------------视频任务已执行-------------------"+message);
<span style="white-space:pre">			</span>return args[0]+"_"+ args[1]+"_"+args[2];</span>}}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值