ActiveMQ学习笔记(4)----JMS的API结构和开发步骤
1. JMS的API结构
其实上图中的五个API在第一节中我们都已经使用到了。本节将会讲非持久化和持久化topic的使用。
2. JMS的基本开发步骤
1. 创建一个JMS工厂, ConnectionFactory
2. 通过Connection Factory来创建JMS的Connection
3. 启动JMS connection
4. 通过JMS connection来创建JMS Session
5. 创建JMS destination
6. 创建JMS producer或JMS Message,并设置destination
7. 创建一个JMS consumer或注册一个JMS message listener
8. 发送或接受JMS message(s);
9. 关闭所有JMS资源(connection,session,producer,consumer)
3. 非持久的topic消息实例
1. 非持久化topic消息的发送。
基本跟第一节中的发送队列消息一致,只需要将创建Destination的地方由创建queue(队列)改为创建Topic即可。例如:
Topic topic = session.createTopic("myTopic");
2. 非持久化的topic消息的接收
1). 接收方必须要在线,因为消息不会存储起来,然后客户端在发送消息,接收方才能收到消息。
2) 同样将创建Destination的地方由创建queue替换成创建Topic
3) 使用while循环接受消息
完整代码如下:
生产者
package com.wangx.activemq.topic; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class NoPersistenceSender { /** * 默认访问路径 */ private static final String DEFAULT_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; /** * 默认用户名 */ private static final String DEFAULT_USER = ActiveMQConnectionFactory.DEFAULT_USER; /** * 默认密码 */ private static final String DEFAULT_PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD; private Session getSession() throws JMSException { ConnectionFactory factory = new ActiveMQConnectionFactory(DEFAULT_USER, DEFAULT_PASSWORD, DEFAULT_URL); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); return session; } public void send() throws JMSException { Session session = getSession(); //创建topic Topic topic = session.createTopic("myTopic"); MessageProducer messageProducer = session.createProducer(topic); for (int i = 0; i < 9; i++) { TextMessage textMessage = session.createTextMessage("Message NoPersistence" + i); messageProducer.send(textMessage); System.out.println("发送者发送的消息" + textMessage.getText()); } session.commit(); session.close(); } public static void main(String[] args) throws JMSException { NoPersistenceSender sender = new NoPersistenceSender(); sender.send(); } }
消费者
package com.wangx.activemq.topic; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class NoPersistenceReceiver { /** * 默认访问路径 */ private static final String DEFAULT_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; /** * 默认用户名 */ private static final String DEFAULT_USER = ActiveMQConnectionFactory.DEFAULT_USER; /** * 默认密码 */ private static final String DEFAULT_PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD; private Session getSession() throws JMSException { ConnectionFactory factory = new ActiveMQConnectionFactory(DEFAULT_USER, DEFAULT_PASSWORD, DEFAULT_URL); Connection connection = factory.createConnection(); connection.start(); Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); return session; } public void receive() throws JMSException { Session session = getSession(); //创建非持久化的topic Destination destination = session.createTopic("myTopic"); MessageConsumer messageConsumer = session.createConsumer(destination); Message message = messageConsumer.receive(); //使用while接受消息 while (message != null) { TextMessage textMessage = (TextMessage) message; System.out.println("接收者接受到的消息:" + textMessage.getText()); message = messageConsumer.receive();
session.commit();
}
session.close();
}
public static void main(String[] args) throws JMSException { NoPersistenceReceiver receiver = new NoPersistenceReceiver(); receiver.receive(); } }
4. 持久化Topic实例
1. 持久化消息发送
它与非持久化消息发送的示例区别主要有以下两点
1)必须要设置使用MessageProducer.setDeliveryMode()方法设置持久化,它默认是不持久化的。
例如:
//设置持久化消息 messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
2)connection的start()方法必须放在持久化设置之后。
2. 持久化消息的接收
跟非持久化相比, 主要注意一下四点:
1. 需要在连接上设置消费者客户端id,用来识别消费者
2. 需要创建TopicSubscriber来订阅
3. 需要设置好了TopicSubscriber和客户端id后才调用connection.start()方法
4. 一定要先运行一次,等于想像消息中间件注册这个消费者,然后再运行生产者发送消息,这个时候,无论消费者是否在线,都将会受到消息,不在线的话,下次连接的时候,会把没有收到过的消息都接收下来。
完整代码如下
生产者:
package com.wangx.activemq.topic; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class PersistenceSender { /** * 默认访问路径 */ private static final String DEFAULT_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; /** * 默认用户名 */ private static final String DEFAULT_USER = ActiveMQConnectionFactory.DEFAULT_USER; /** * 默认密码 */ private static final String DEFAULT_PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD; public void send() throws JMSException { ConnectionFactory factory = new ActiveMQConnectionFactory(DEFAULT_USER, DEFAULT_PASSWORD, DEFAULT_URL); Connection connection = factory.createConnection(); Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); //创建topic Destination destination = session.createTopic("myTopic2"); MessageProducer messageProducer = session.createProducer(destination); //设置持久化消息, 默认是非持久化 messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT); //start()放在设置持久化之后 connection.start(); for (int i = 0; i < 9; i++) { TextMessage textMessage = session.createTextMessage("Message Persistence" + i); messageProducer.send(textMessage); System.out.println("发送者发送的消息" + textMessage.getText()); } session.commit(); session.close(); connection.close(); } public static void main(String[] args) throws JMSException { PersistenceSender sender = new PersistenceSender(); sender.send(); } }
消费者:
package com.wangx.activemq.topic; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class PersistenceReceiver { /** * 默认访问路径 */ private static final String DEFAULT_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; /** * 默认用户名 */ private static final String DEFAULT_USER = ActiveMQConnectionFactory.DEFAULT_USER; /** * 默认密码 */ private static final String DEFAULT_PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD; public void receive() throws JMSException { ConnectionFactory factory = new ActiveMQConnectionFactory(DEFAULT_USER, DEFAULT_PASSWORD, DEFAULT_URL); Connection connection = factory.createConnection(); //注册客户端id connection.setClientID("wangx1"); connection.start(); Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); //创建topic Topic topic = session.createTopic("myTopic2"); //创建topicSubscriber TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "wangx1"); //启动connection connection.start(); Message message = topicSubscriber.receive(); while (message != null) { TextMessage textMessage = (TextMessage) message; System.out.println("接收者接受到的消息:" + textMessage.getText()); message = topicSubscriber.receive(); session.commit(); } session.close(); connection.close(); } public static void main(String[] args) throws JMSException { PersistenceReceiver receiver = new PersistenceReceiver(); receiver.receive(); } }
5. 关于持久化和非持久化消息
5.1 持久化消息
这是ActiveMQ的默认传送方式,此模式保证这些消息制备传送一次和成功使用一次,对于这些消息,可靠性是优先考虑的,可靠性的另一个重要的另一个方面是确保持久性消息传至目标后,消息服务在向消费者传送他们之前不会丢失这些消息。
这意味着在持久性消息传至目标时,消息服务将其放入持久性数据存储,如果消息服务由于某种原因导致失败,它可以恢复次消息并将此消息传送至相应的消费者。虽然增加了消息传送的开销,但是却增加了可靠性。
5.2 非持久化消息
保证这些消息最多被传送一次,对于这些消息,可靠性并不是主要的考虑因素。并不要求持久性的存储数据,也不保证消息服务由于某种原因导致失败后消息不会丢失。
有两种方法制定传送模式
使用setDeliveryMode方法,这样所有的消息都采用此种传送模式,例如:
//设置持久化消息, 默认是非持久化 messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
也可以使用send()方法为每一条消息设置传送模式,例如:
messageProducer.send(textMessage, DeliveryMode.PERSISTENT,20,20);