ActiveMQ除了公共的JMS方式之外,还提供了另外两种方式,一个是点对点队列Queue,一个是发布/订阅Topics/Subscribe。
Queue和Topics/Subscribe都是基于JMS实现的子类。
点对点:(point to point)
发送端将消息发送到ActiveMQ服务器上之后,消息进入了服务器队列中,客户端通过连接上指定的消息源就可以从服务器上的队列中取出消息。这种方式使得发送端发送的消息客户端随时都可以去拿,只要发送端的消息进入队列,客户端在任意时间都可以从服务器上获取到消息。
需要注意的是当发送者将消息的传输模式设置为不可持久化的时候,当activeMQ服务器关闭之后,消息队列里面的数据将会被丢弃,这时候activemq服务器再次启动,数据会清零显示。如果想要在重启activeMQ服务器时数据持久化,那么将消息设置为持久化即可。
点对点模式示意图:
发布/订阅:(Topics/Subscribe)
发布/订阅方式用于多接收客户端的方式.作为发布订阅的方式,可能存在多个接收客户端。
消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscrip-tion),非持久订阅只有当客户端处于激活状态,也就是和JMS Provider 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失。持久订阅时,客户端向JMS 注册一个识别自己身份的ID,当这个客户端处于离线时,JMS Provider 会为这个ID 保存所有发送到主题的消息,当客户再次连接到JMS Provider时,会根据自己的ID 得到所有当自己处于离线时发送到主题的消息。
如果想要创建持久化订阅者,登陆activeMQ服务器控制台,切换到订阅者视图:
输入ClientID,Subscriber Name,Topic Name,JMS Selector,需要注意ClientID要唯一。
发布者/订阅者示意图:
使用Queue:
发送者:
package yzr;
import javax.jms.DeliveryMode;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
//发送消息数量
private static final int SEND_NUMBER = 5;
public static void main(String[] args) {
QueueConnectionFactory connectionFactory;
QueueConnection connection = null;
QueueSession session=null;
Queue queue;
QueueSender sender;
String user=ActiveMQConnection.DEFAULT_USER;//默认用户名是admin
String password=ActiveMQConnection.DEFAULT_PASSWORD;//默认密码是admin
String url="tcp://localhost:61616";//tcp协议连接
connectionFactory = new ActiveMQConnectionFactory(user,password,url);
try {
//得到连接对象
connection = connectionFactory.createQueueConnection();
connection.start();
// 获取操作连接
session=connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
// 指定队列的消息源
queue = session.createQueue("TestQueue");
// 消息发送者对象
sender = session.createSender(queue);
// 设置传说模式为不持久化
sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 发送消息
sendMessage(session, sender);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public static void sendMessage(Session session, QueueSender sender)
throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
// 发送文本消息
TextMessage message = session
.createTextMessage("ActiveMq " + "MessageContent " + i);
//控制台输出发送信息内容
System.out.println("发送消息:" + "ActiveMq " + "MessageContent " + i);
sender.send(message);
}
}
}
接收者:
package yzr;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
public static void main(String[] args) {
QueueConnectionFactory connectionFactory;
QueueConnection connection = null;
QueueSession session=null;
Queue queue;
//消息接收者
QueueReceiver receiver;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection = connectionFactory.createQueueConnection();
connection.start();
session = connection.createQueueSession(Boolean.FALSE,
Session.AUTO_ACKNOWLEDGE);
//队列消息源
queue = session.createQueue("TestQueue");
receiver = session.createReceiver(queue);
/*
while (true) {
//设置接收者接收文本消息的时间
TextMessage message = (TextMessage) receiver.receive(100000);
if (null != message) {
System.out.println("收到消息:" + message.getText());
} else {
break;
}
}
*/
//使用消息监听器
receiver.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
if (msg != null) {
TextMessage message = (TextMessage) msg;
try {
System.out.println(message.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
//此处休眠100秒,让监听器不要被中断连接
Thread.sleep(1000 * 100);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
Topics/Subscribe
发送端:
package yzr;
import javax.jms.DeliveryMode;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
//发送消息数量
private static final int SEND_NUMBER = 5;
public static void main(String[] args) {
TopicConnectionFactory connectionFactory;
TopicConnection connection = null;
TopicSession session=null;
Topic topic;
TopicPublisher publisher;
String user=ActiveMQConnection.DEFAULT_USER;//默认用户名是admin
String password=ActiveMQConnection.DEFAULT_PASSWORD;//默认密码是admin
String url="tcp://localhost:61616";//tcp协议连接
connectionFactory = new ActiveMQConnectionFactory(user,password,url);
try {
//得到连接对象
connection = connectionFactory.createTopicConnection();
connection.start();
// 获取操作连接
session=connection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
// 指定话题的消息源
topic = session.createTopic("TestTopic");
// 消息发送者对象
publisher = session.createPublisher(topic);
// 设置传输模式为不持久化
publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 发送消息
sendMessage(session, publisher);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public static void sendMessage(Session session, TopicPublisher publisher)
throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
// 发送文本消息
TextMessage message = session
.createTextMessage("ActiveMq " + "MessageContent " + i);
//控制台输出发送信息内容
System.out.println("发送消息:" + "ActiveMq " + "MessageContent " + i);
publisher.send(message);
}
}
}
接收端:
package yzr;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
public static void main(String[] args) {
TopicConnectionFactory connectionFactory;
TopicConnection connection = null;
TopicSession session=null;
Topic topic;
//消息接收者
TopicSubscriber subscriber;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection = connectionFactory.createTopicConnection();
connection.setClientID("111");
connection.start();
session = connection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
//队列消息源
topic = session.createTopic("TestTopic");
subscriber = session.createDurableSubscriber(topic, "YZRSubscriber");
/*
while (true) {
//设置接收者接收文本消息的时间
TextMessage message = (TextMessage) receiver.receive(100000);
if (null != message) {
System.out.println("收到消息:" + message.getText());
} else {
break;
}
}
*/
//使用消息监听器
subscriber.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
if (msg != null) {
TextMessage message = (TextMessage) msg;
try {
System.out.println(message.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
//此处休眠100秒,让监听器不要被中断连接
Thread.sleep(1000 * 100);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}