其实上图中的五个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(); } }
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.1 持久化消息
这是ActiveMQ的默认传送方式,此模式保证这些消息制备传送一次和成功使用一次,对于这些消息,可靠性是优先考虑的,可靠性的另一个重要的另一个方面是确保持久性消息传至目标后,消息服务在向消费者传送他们之前不会丢失这些消息。
这意味着在持久性消息传至目标时,消息服务将其放入持久性数据存储,如果消息服务由于某种原因导致失败,它可以恢复次消息并将此消息传送至相应的消费者。虽然增加了消息传送的开销,但是却增加了可靠性。
5.2 非持久化消息
保证这些消息最多被传送一次,对于这些消息,可靠性并不是主要的考虑因素。并不要求持久性的存储数据,也不保证消息服务由于某种原因导致失败后消息不会丢失。
有两种方法制定传送模式
使用setDeliveryMode方法,这样所有的消息都采用此种传送模式,例如:
//设置持久化消息, 默认是非持久化
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
也可以使用send()方法为每一条消息设置传送模式,例如:
messageProducer.send(textMessage, DeliveryMode.PERSISTENT,20,20);