ActiveMQ 是Apache出品,最流行的、功能强大的即时通讯和集成模式的开源服务器。ActiveMQ是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。提供客户端支持跨语言和协议,带有易于在充分支持JMS1.1和1.4使用J2EE企业集成模式和许多先进的功能。
开发环境
System : windows
JDK : 1.8+
IDE:eclipse
apache ActiveMQ 5.8
1.下载
apache-activemq-5.8.0-bin.zip
2.解压apache-activemq-5.8.0.zip即可完成ActiveMQ的安装
3.apache-activemq-5.8.0目录
\bin (windows下面的bat和unix/linux下面的sh) 启动ActiveMQ的启动服务就在这里
\conf (activeMQ配置目录,包含最基本的activeMQ配置文件)
\data (默认是空的)
\docs (index,replease版本里面没有文档)
\example (几个例子)
\lib (activeMQ使用到的lib)
\webapps (系统管理员控制台代码)
\webapps-demo(系统示例代码)
\activemq-all-5.8.0.jar (ActiveMQ的binary)
\user-guide.html (部署指引)
\LICENSE
\NOTICE
\README.txt
4.进入bin目录,使用activemq.bat双击启动(windows用户可以选择系统位数,如果你是linux的话,就用命令行的发送去启动),如果一切顺利,你就会看见类似下面的信息:
5.启动成功就可以访问管理员界面:http://localhost:8161/admin,默认用户名和密码admin/admin。如果你想修改用户名和密码的话,在\conf\jetty-realm.properties中修改即可。
6.关闭
我们暂时不关闭先, 若想关闭可以直接关闭cmd.exe
JMS 公共 | 点对点域 | 发布/订阅域 |
---|---|---|
ConnectFactory | QueueConnectionFactory | TopicConnectionFactory |
Connection | QueueConnection | TopicConnection |
Destination | Queue | Topic |
Session | QueueSession | TopicSession |
MessageProducer | QueueSender | TopicPublisher |
MessageConsumer | QueueReceiver | TopicSubscriber |
1 点对点方式(point-to-point)
点对点的消息发送方式主要建立在 Message Queue,Sender,reciever上,Message Queue 存贮消息,Sneder 发送消息,receive接收消息.具体点就是Sender Client发送Message Queue ,而 receiver Client从Queue中接收消息和”发送消息已接受”到Quere,确认消息接收。消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在任何时刻发送信息到Queue,而不需要知道接收客户端是不是在运行
2 发布/订阅 方式(publish/subscriber Messaging)
发布/订阅方式用于多接收客户端的方式.作为发布订阅的方式,可能存在多个接收客户端,并且接收端客户端与发送客户端存在时间上的依赖。一个接收端只能接收他创建以后发送客户端发送的信息。作为subscriber ,在接收消息时有两种方法,destination的receive方法,和实现message listener 接口的onMessage 方法。
发送方:
(1)、创建连接使用的工厂类JMS ConnectionFactory
(2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动
(3)、使用连接Connection 建立会话Session
(4)、使用会话Session和管理对象Destination创建消息生产者MessageSender
(5)、使用消息生产者MessageSender发送消息
接收方:
(1)、创建连接使用的工厂类JMS ConnectionFactory
(2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动
(3)、使用连接Connection 建立会话Session
(4)、使用会话Session和管理对象Destination创建消息接收者MessageReceiver
(5)、使用消息接收者MessageReceiver接受消息,需要用setMessageListener将MessageListener接口
绑定到MessageReceiver消息接收者必须实现了MessageListener接口,需要定义onMessage事件方法。
此处利用maven管理项目
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lee</groupId>
<artifactId>testJMS</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>testJMS</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
</dependencies>
</project>
//发送者
package com.lee.testJMS;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
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;
//tcp地址
public static final String BROKER_URL = "tcp://localhost:61616";
//目标, 在ActiveMQ管理员控制台点击Queues
public static final String DESTINATION = "FirstQueue";
// 构造消息,此处写死,项目就是参数,或者方法获取
public static void sendMessage(Session session, MessageProducer producer) throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
TextMessage message = session.createTextMessage("ActiveMq 发送的消息" + i);
System.out.println("发送消息:" + "ActiveMq 发送的消息" + i);
producer.send(message);
}
}
public static void run() throws Exception {
Connection connection = null;
Session session = null;
try {
//ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
//Connection :JMS 客户端到JMS Provider 的连接
connection = factory.createConnection();
//启动连接
connection.start();
//创建一个session, 获取操作连接会话
session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//Destination :消息的目的地;消息发送给谁.
Destination destination = session.createQueue(DESTINATION);
//MessageProducer:消息发送者
MessageProducer producer = session.createProducer(destination);
//设置持久化模式
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
sendMessage(session, producer);
//提交会话
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭资源
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
}
}
public static void main(String[] args) throws Exception {
Sender.run();
}
}
//接收者
package com.lee.testJMS;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
//tcp地址
public static final String BROKER_URL = "tcp://localhost:61616";
//目标, 在activeMQ管理员控制台点击Queues
public static final String DESTINATION = "FirstQueue";
public static void run() throws Exception {
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = null;
// Session: 一个发送或接收消息的线程
Session session = null;
try {
//ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
//通过工厂创建一个连接
connection = factory.createConnection();
//启动连接
connection.start();
//创建一个session会话
session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// Destination :消息的目的地;消息发送给谁.
Destination destination = session.createQueue(DESTINATION);
//创建消息消费者(接收者)
MessageConsumer consumer = session.createConsumer(destination);
while (true) {
//// 设置接收者接收消息的时间,为了便于测试,这里设定为100s
Message message = consumer.receive(1000 * 100);
TextMessage text = (TextMessage) message;
if (text != null) {
System.out.println("接收: " + text.getText());
} else {
break;
}
}
//提交会话
session.commit();
} catch (Exception e) {
throw e;
} finally {
//关闭资源
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
}
}
public static void main(String[] args) throws Exception {
Receiver.run();
}
}
测试过程:
发送
http://localhost:8161/admin/
接收
http://localhost:8161/admin/queues.jsp
Pub/Sub模式与P2P模式不同, P2P模式Sender发送后会保存在容器中, 直到Receiver来取走, 消息抛弃; Pub/Sub模式过程如下:
//订阅者
package com.lee.testTopic;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
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 TopicReceiver {
// tcp 地址
public static final String BROKER_URL = "tcp://localhost:61616";
// 目标,在ActiveMQ管理员控制台点击Queues查看
public static final String TARGET = "topic";
public static void run() throws Exception {
TopicConnection connection = null;
TopicSession session = null;
try {
// 创建链接工厂
TopicConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
// 通过工厂创建一个连接
connection = factory.createTopicConnection();
// 启动连接
connection.start();
// 创建一个session会话
session = connection.createTopicSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// 创建一个消息队列
Topic topic = session.createTopic(TARGET);
// 创建订阅者
TopicSubscriber subscriber = session.createSubscriber(topic);
//创建监听器监听发布者
subscriber.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
if (msg != null) {
MapMessage map = (MapMessage) msg;
try {
System.out.println(map.getLong("time") + "接收#" + map.getString("text"));
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
// 休眠100s再关闭, 不然会直接关闭, 无法接收订阅消息
Thread.sleep(1000 * 100);
// 提交会话
session.commit();
} catch (Exception e) {
throw e;
} finally {
// 关闭释放资源
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
}
}
public static void main(String[] args) throws Exception {
TopicReceiver.run();
}
}
//发布者
package com.lee.testTopic;
import javax.jms.DeliveryMode;
import javax.jms.MapMessage;
import javax.jms.Session;
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 TopicSender {
// 发送次数
public static final int SEND_NUM = 5;
// tcp 地址
public static final String BROKER_URL = "tcp://localhost:61616";
// 目标,在ActiveMQ管理员控制台点击Queues查看
public static final String DESTINATION = "topic";
public static void sendMessage(TopicSession session, TopicPublisher publisher) throws Exception {
for (int i = 0; i < SEND_NUM; i++) {
String message = "发送消息第" + (i + 1) + "条";
MapMessage map = session.createMapMessage();
map.setString("text", message);
map.setLong("time", System.currentTimeMillis());
System.out.println(map);
publisher.send(map);
}
}
public static void run() throws Exception {
TopicConnection connection = null;
TopicSession session = null;
try {
// 创建链接工厂, user默认为admin, password默认为admin
TopicConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
// 通过工厂创建一个连接
connection = factory.createTopicConnection();
// 启动连接
connection.start();
// 创建一个session会话
session = connection.createTopicSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// 创建一个消息队列
Topic topic = session.createTopic(DESTINATION);
// 创建消息发布者
TopicPublisher publisher = session.createPublisher(topic);
// 设置持久化模式
publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
sendMessage(session, publisher);
// 提交会话
session.commit();
} catch (Exception e) {
throw e;
} finally {
// 关闭释放资源
if (session != null) {
session.close();
}
if (connection != null) {
connection.close();
}
}
}
public static void main(String[] args) throws Exception {
TopicSender.run();
}
}