使用ActiveMQ实现JMS消息通信服务
PTP(点对点的消息模型)
在点对点模型中,相当于两个人打电话,两个人独享一条通信线路。一方发送消息,一方接收消息。
在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者。
1、建立项目
建立一个java项目,导入jar包,将apache-activemq-5.11.1-bin.zip解压缩后里面的activemq-all-5.11.1.jar包加入到classpath下面,这个包包含了所有JMS接口API的实现。

点对点的消息模型,只需要一个消息生成者和消息消费者。
- 编写生产者
package com.tgb.activemq; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* 消息的生产者(发送者)
* @author liang
*
*/
public class JMSProducer { //默认连接用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//默认连接密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//默认连接地址
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;
//发送的消息数量
private static final int SENDNUM = ; public static void main(String[] args) {
//连接工厂
ConnectionFactory connectionFactory;
//连接
Connection connection = null;
//会话 接受或者发送消息的线程
Session session;
//消息的目的地
Destination destination;
//消息生产者
MessageProducer messageProducer;
//实例化连接工厂
connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL); try {
//通过连接工厂获取连接
connection = connectionFactory.createConnection();
//启动连接
connection.start();
//创建session
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//创建一个名称为HelloWorld的消息队列
destination = session.createQueue("HelloWorld");
//创建消息生产者
messageProducer = session.createProducer(destination);
//发送消息
sendMessage(session, messageProducer); session.commit(); } catch (Exception e) {
e.printStackTrace();
}finally{
if(connection != null){
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
} }
/**
* 发送消息
* @param session
* @param messageProducer 消息生产者
* @throws Exception
*/
public static void sendMessage(Session session,MessageProducer messageProducer) throws Exception{
for (int i = ; i < JMSProducer.SENDNUM; i++) {
//创建一条文本消息
TextMessage message = session.createTextMessage("ActiveMQ 发送消息" +i);
System.out.println("发送消息:Activemq 发送消息" + i);
//通过消息生产者发出消息
messageProducer.send(message);
} }
}
- 编写消费者
package com.tgb.activemq; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* 消息的消费者(接受者)
* @author liang
*
*/
public class JMSConsumer { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址 public static void main(String[] args) {
ConnectionFactory connectionFactory;//连接工厂
Connection connection = null;//连接 Session session;//会话 接受或者发送消息的线程
Destination destination;//消息的目的地 MessageConsumer messageConsumer;//消息的消费者 //实例化连接工厂
connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL); try {
//通过连接工厂获取连接
connection = connectionFactory.createConnection();
//启动连接
connection.start();
//创建session
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建一个连接HelloWorld的消息队列
destination = session.createQueue("HelloWorld");
//创建消息消费者
messageConsumer = session.createConsumer(destination); while (true) {
TextMessage textMessage = (TextMessage) messageConsumer.receive();
if(textMessage != null){
System.out.println("收到的消息:" + textMessage.getText());
}else {
break;
}
} } catch (JMSException e) {
e.printStackTrace();
} }
}
2、测试
1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。
2)运行发送者JMSProducer,Eclipse控制台输出,如下图:

生产者生产10条消息。
此时,查看ActiveMQ服务器,Queues内容如下:

可以看到创建了一个名称为HelloWorld的消息队列,队列中有10条消息未被消费,我们也可以通过Browse查看是哪些消息,如下图:

如果这些队列中的消息,被删除,消费者则无法消费。
3)继续运行消费者JMSConsumer,eclipse控制台打印消息,如下:

再查看ActiveMQ服务器,Queues内容如下:

可以看到HelloWorld的消息队列发生变化,多一个消息者,队列中的10条消息被消费了,点击Browse查看,已经为空了。
点击Active Consumers,我们可以看到这个消费者的详细信息:

3、总结
点对点消息的传播,生产者向特定的消息队列传播消息,一个消费者从该队列读取消息。生产者不需要在接收者接收消息时处于运行,消费者也不需要生产者在发送消息时处于运行状态,队列相当于一个中间的仓库,生产者发送消息,立即返回状态发送成功。等消费者上线时 ,才接受消息。
Pub/Sub(发布订阅模型)
就像订阅报纸。我们可以选择一份或者多份报纸,比如:北京日报、人民日报。这些报纸就相当于发布订阅模型中的topic。如果有很多人订阅了相同的报纸,那我们就在同一个topic中注册,对于报纸发行方,它就和所有的订阅者形成了一对多的关系。如下:
1、建立项目
建立一个java项目,导入jar包。
- 编写发布者(这里和点对点的不同就是不再是创建消息队列,而是创建topic。而且也不是消息生产者而是发布者)
package com.tgb.activemqTopic; import java.awt.font.TextMeasurer; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; /**
* 消息发布者
* @author xx
*
*/
public class JMSProducer {
//默认连接用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//默认连接密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//默认的连接地址
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;
//发送的消息数量
private static final int SENNUM = ; public static void main(String[] args){
ConnectionFactory factory ; //连接工厂
Connection connection = null ; //连接
Session session ; //会话,接收或者发送消息的线程
Destination destination; //消息的目的地
MessageProducer messageProducer; //消息生产者
//实例化连接工厂
factory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);
//通过连接工厂获取connection
try {
connection = factory.createConnection();
connection.start(); //启动连接
//创建session
session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//创建消息队列
// destination = session.createQueue("FirstQueue"); //创建主题
destination = session.createTopic("topic1");
//创建消息发布者
messageProducer = session.createProducer(destination);
//发送消息
sendMessage(session, messageProducer);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}finally{
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
} /**
* 发送消息
* @param session
* @param mp
* @throws JMSException
*/
public static void sendMessage(Session session, MessageProducer mp) throws JMSException{
for(int i = ;i<JMSProducer.SENNUM;i++){
TextMessage message = session.createTextMessage("ActiveMq 发布的消息" + i);
System.out.println("发布消息:" + "ActiveMq 发布的消息" + i);
mp.send(message);
}
}
}
- 编写订阅者1
package com.tgb.activemqTopic; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory; public class JMSConsumer1 implements MessageListener { public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) message; try {
System.out.println("订阅者一接收到了消息:" + txtMsg.getText());
} catch (JMSException e) {
e.printStackTrace();
} }
} public void receive() {
// 消费者的主要流程
Connection connection = null; try {
// 1.初始化connection工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); // 2.创建Connection
connection = connectionFactory.createConnection(); // 3.打开连接
connection.start(); // 4.创建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建消息目标
Destination destination = session.createTopic("topic1"); // 6.创建消费者
MessageConsumer consumer = session.createConsumer(destination); // 7.配置监听
consumer.setMessageListener(new JMSConsumer1()); } catch (JMSException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
new JMSConsumer1().receive();
} }
- 编写订阅者2
package com.tgb.activemqTopic; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory; public class JMSConsumer2 implements MessageListener { public void onMessage(Message message) {
if (message instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) message; try {
System.out.println("订阅者二接收到了消息:" + txtMsg.getText());
} catch (JMSException e) {
e.printStackTrace();
} }
} public void receive() {
// 消费者的主要流程
Connection connection = null; try {
// 1.初始化connection工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); // 2.创建Connection
connection = connectionFactory.createConnection(); // 3.打开连接
connection.start(); // 4.创建session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 5.创建消息目标
Destination destination = session.createTopic("topic1"); // 6.创建消费者
MessageConsumer consumer = session.createConsumer(destination); // 7.配置监听
consumer.setMessageListener(new JMSConsumer1()); } catch (JMSException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
new JMSConsumer2().receive();
} }
2、测试
1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。
2)发布订阅模型,要先启动订阅者,订阅者先订阅topic,再发布消息。
启动订阅者,这里我启动两个,可以看到在topic中注册了两个消费者:

3)启动发布者,如下:


发布者发布了10条数据,但是出队的有20条,因为有两个订阅者。
3、总结
发布者向一个特定的消息主题发布消息,0或者多个订阅者可能接收到来自特定消息主题的消息感兴趣。其中发布者和订阅者不知道对方的存在。
配置消息是否持久化
1、建立项目
//配置消息是否持久化,DeliverMode有2种方式
/*
* 1 不持久化:服务器重启之后,消息销毁
* 2 持久化:服务器重启之后,该消息仍存在
*/
messageProducer.setDeliveryMode(2);
- 编写发布者
package com.tgb.activemqTopic; import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; /**
* 消息发布者
* @author xx
*
*/
public class JMSProducer {
//默认连接用户名
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
//默认连接密码
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//默认的连接地址
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;
//发送的消息数量
private static final int SENNUM = ; public static void main(String[] args){
ConnectionFactory factory ; //连接工厂
Connection connection = null ; //连接
Session session ; //会话,接收或者发送消息的线程
Destination destination; //消息的目的地
MessageProducer messageProducer; //消息生产者
//实例化连接工厂
factory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);
//通过连接工厂获取connection
try {
connection = factory.createConnection();
connection.start(); //启动连接
//创建session
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//创建主题
destination = session.createTopic("topic1");
//创建消息发布者
messageProducer = session.createProducer(destination); //配置消息是否持久化,DeliverMode有2种方式
/*
* 1 不持久化:服务器重启之后,消息销毁
* 2 持久化:服务器重启之后,该消息仍存在
*/
messageProducer.setDeliveryMode(); //发送消息
sendMessage(session, messageProducer);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}finally{
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
} /**
* 发送消息
* @param session
* @param mp
* @throws JMSException
*/
public static void sendMessage(Session session, MessageProducer mp) throws JMSException{
for(int i = ;i<JMSProducer.SENNUM;i++){
TextMessage message = session.createTextMessage("ActiveMq 发布的消息" + i);
System.out.println("发布消息:" + "ActiveMq 发布的消息" + i);
mp.send(message);
}
}
}
2、测试
1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。
2)先2个启动订阅者,再启动发布者,如下:

使用ActiveMQ实现JMS消息通信服务的更多相关文章
- 使用Tomcat、JNDI与ActiveMQ实现JMS消息通信服务
前言 之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(ActiveMQ.HornetQ等) ...
- JMS消息通信服务
什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...
- ActiveMQ的JMS消息可靠机制
JMS消息可靠机制 ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成 ...
- vscode源码分析【七】主进程启动消息通信服务
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- activemq和jms是种什么关系
JMS是一个用于提供消息服务的技术规范,它制定了在整个消息服务提供过程中的所有数据结构和交互流程. 而activemq则是消息队列服务,是面向消息中间件(MOM)的最终实现,是真正的服务提供者. jm ...
- 消息中间件--ActiveMQ&JMS消息服务
### 消息中间件 ### ---------- **消息中间件** 1. 消息中间件的概述 2. 消息中间件的应用场景 * 异步处理 * 应用解耦 * 流量削峰 * 消息通信 --------- ...
- ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...
- 分布式消息通信ActiveMQ
消息中间件 消息中间件是指利用高效可靠的消息传递机制进行平台无关的数据交流,并且基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,可以在分布式架构下扩展进程之间的通信. 消息中间件能 ...
- 分布式消息通信(ActiveMQ)
分布式消息通信(ActiveMQ) 应用场景 异步通信 应用解耦 流量削峰 # ActiveMQ安装 下载 http://activemq.apache.org/ 压缩包上传到Linux系统 apac ...
随机推荐
- 微信小程序_简单组件使用与数据绑定
简单的数据传值 官方文档:传送门 点击"按钮"测试后,按钮文本改变,下方text文本改变,通过console.log()在输出台中打印按钮文本信息 程序结构 Page({ //页面 ...
- Override和Overload的含义与区别
overload是重载,重载是一种参数多态机制,即代码通过参数的类型或个数不同而实现的多态机制. 是一种静态的绑定机制(在编译时已经知道具体执行的是哪个代码段). override是重写,重写是一种 ...
- 【学习】SpringBoot之简介、特点、缺点、应用场景
Spring Boot 的介绍 SpringBoot的目的在于创建和启动新的基于Spring框架的项目.Spring Boot 会选择最合适的Spring子项目和第三方开源库进行整合.大部分Sprin ...
- 【学习】SpringBoot之全局异常处理器
/** * 全局异常处理器 **/ @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exceptio ...
- Docker入门-Dockerfile的使用
使用Dockerfile定制镜像 镜像的定制实际上就是定制每一层所添加的配置.文件.我们可以把每一层修改.安装.构建.操作的命令都写入一个脚本,这个脚本就是Dockerfile. Dockerfile ...
- TCP定时器 之 TIME_WAIT定时器
概述 在FIN_WAIT_2收到对端发来的FIN,并回复ACK之后,会进入TIME_WAIT状态,此时添加定时器,定时器超时会将tw控制块从ehash和bhash中删除,并且释放tw控制块: 启动定时 ...
- Java期末课程学习汇总。
本学期面向对象与Java程序设计课程已经结束了,给自己学习来个总结. 本学期过的非常快,不得不说这一学期学到的东西很少,感觉自己的进步很小. 而且感觉自己总少了点什么,在写这篇总结前,我认真想了,很多 ...
- DS博客作业--课程总结
1.当初你是如何做出选择计算机专业的决定的? 经过一年学习,你的看法改变了么,为什么? 你觉得计算机是你喜欢的领域吗,它是你擅长的领域吗? 为什么? 刚开始填报志愿的时候,因为我个人是没有什么比较特别 ...
- spark 笔记 10: TaskScheduler相关
任务调度器的接口类.应用程序可以定制自己的调度器来执行.当前spark只实现了一个任务调度器) )))))val createTime = System.currentTimeMillis()clas ...
- wls应用命令部署与卸载
1.查看wls节点运行状态 [root@localhost lib]# jps [root@localhost lib]# ss -tnlp|grep 23705 2.配置wls环境变量 [deplo ...