其实我对activeMQ 一点都不了解,也没用过,而且最近的项目里也不会使用。因为之前听同学说他们正在用,就搞出来看看是什么东西。顺便玩玩。
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
首先是下载部署,常用的目录结构如下
+bin (windows下面的bat和unix/linux下面的sh) +conf (activeMQ配置目录,包含最基本的activeMQ配置文件) +data (默认是空的) +docs (index,replease版本里面没有文档,-.-b不知道为啥不带) +example (几个例子 +lib (activemMQ使用到的lib) -apache-activemq-4.1-incubator.jar (ActiveMQ的binary) -LICENSE.txt -NOTICE.txt -README.txt -user-guide.html
然后是部署项目,example里面有现成的程序,放到本地跑跑。
补充一个红薯的文档。
http://www.oschina.net/question/12_19665
关于JMS的东西我在补充些资料,下面是JMS的主要接口
ConnectionFactory 接口(连接工厂) 用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。
Connection 接口(连接) 连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。
Destination 接口(目标) 目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。
MessageConsumer 接口(消息消费者) 由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
MessageProducer 接口(消息生产者) 由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
Message 接口(消息) 是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分: 消息头(必须):包含用于识别和为消息寻找路由的操作设置。 一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。 一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。 消息接口非常灵活,并提供了许多方式来定制消息的内容。
Session 接口(会话) 表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。下面是一个JMS的流程图
下面是一个测试的代码
public class MyActiveMqTest { public static void main(String[] args) { Receiver receiver=new Receiver(); Sender sender =new Sender(); try { sender.send(); receiver.receive(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } static class Receiver { public static void receive() throws Exception { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); Connection connection = connectionFactory.createConnection(); connection.start(); final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createQueue("my-queue"); MessageConsumer consumer = session.createConsumer(destination); /* * //listener 方式 consumer.setMessageListener(new MessageListener() { * * public void onMessage(Message msg) { MapMessage message = * (MapMessage) msg; //TODO something.... System.out.println("收到消息:" * + new Date(message.getLong("count"))); session.commit(); } * * }); Thread.sleep(30000); */ int i = 0; while (i < 3) { i++; MapMessage message = (MapMessage) consumer.receive(); session.commit(); // TODO something.... System.out .println("收到消息:" + new Date(message.getLong("count"))); } session.close(); connection.close(); } } static class Sender { public static void send() throws Exception { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); Connection connection = connectionFactory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); Destination destination = session.createQueue("my-queue"); MessageProducer producer = session.createProducer(destination); for (int i = 0; i < 3; i++) { MapMessage message = session.createMapMessage(); message.setLong("count", new Date().getTime()); Thread.sleep(1000); // 通过消息生产者发出消息 System.out.println("发送消息"+i+new Date()); producer.send(message); } session.commit(); session.close(); connection.close(); } } }
下面是打印的结果
发送消息0Fri Jun 08 19:41:45 CST 2012 发送消息1Fri Jun 08 19:41:52 CST 2012 发送消息2Fri Jun 08 19:41:55 CST 2012 收到消息:Fri Jun 08 19:41:40 CST 2012 收到消息:Fri Jun 08 19:41:50 CST 2012 收到消息:Fri Jun 08 19:41:53 CST 2012
根据红薯的列子,我还应该试下和spring的结合,搭项目的spring环境。
先贴代码:
public class MyActiveMqSpringTest { public static void main(String[] args) { Receiver receiver = new Receiver(); Sender sender = new Sender(); try { sender.send(); receiver.receive(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } static class Receiver { public static void receive() throws Exception { ApplicationContext ctx = new FileSystemXmlApplicationContext( "classpath:app*.xml"); JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate"); jmsTemplate.send(new MessageCreator() { public Message createMessage(Session session) throws JMSException { MapMessage mm = session.createMapMessage(); mm.setLong("count", new Date().getTime()); return mm; } }); } } static class Sender { public static void send() throws Exception { ApplicationContext ctx = new FileSystemXmlApplicationContext( "classpath:app*.xml"); JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate"); while (true) { Map<String, Object> mm = (Map<String, Object>) jmsTemplate .receiveAndConvert(); System.out.println("收到消息:" + new Date((Long) mm.get("count"))); } } } }
下面是spring的配置
<?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-2.5.xsd"> <!-- 在非 web / ejb 容器中使用 pool 时,要手动 stop,spring 不会为你执行 destroy-method 的方法 --> <!-- <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> <property name="connectionFactory"> <bean class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> </property> </bean> --> <bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="jmsFactory" /> <property name="defaultDestination" ref="destination" /> <property name="messageConverter"> <bean class="org.springframework.jms.support.converter.SimpleMessageConverter" /> </property> </bean> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="my-queue" /> </bean> </beans>
失败了。。没有结果输出。有时间再搞吧。
总结一下,今天主要就是熟悉了下JMS的模型,还知道有个activeMQ的东西,简单的搭建了一下环境,能跑出个helloWorld。ActiveMq和Spring结合那块没有成功,有空再搞搞。