java怎么使用mq通信_JavaWeb之使用ActiveMQ实现JMS消息通信服务

本文介绍了如何在Java中使用ActiveMQ进行点对点(PTP)和发布订阅(Pub/Sub)模型的消息通信。在PTP模型中,创建了消息生产者和消费者,通过消息队列进行通信。在发布订阅模型中,创建了消息发布者和多个订阅者,消息可以被多个订阅者接收。示例代码展示了如何设置连接、创建会话、目的地以及生产者和消费者。
摘要由CSDN通过智能技术生成

PTP(点对点的消息模型)

在点对点模型中,相当于两个人打电话,两个人独享一条通信线路。一方发送消息,一方接收消息。

623b001aa3dac407fa72efbbb23be132.png

在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者。

1、建立项目

建立一个java项目,导入jar包,将apache-activemq-5.11.1-bin.zip解压缩后里面的activemq-all-5.11.1.jar包加入到classpath下面,这个包包含了所有JMS接口API的实现。

8bb92800a624e211a49f0ea0c7f6e7f3.png

点对点的消息模型,只需要一个消息生成者和消息消费者。

编写生产者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSProducer {//默认连接用户名

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 = 10;public static voidmain(String[] args) {//连接工厂

ConnectionFactory connectionFactory;//连接

Connection connection = null;//会话 接受或者发送消息的线程

Session session;//消息的目的地

Destination destination;//消息生产者

MessageProducer messageProducer;//实例化连接工厂

connectionFactory = newActiveMQConnectionFactory(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 voidsendMessage(Session session,MessageProducer messageProducer) throws Exception{for (int i = 0; i < JMSProducer.SENDNUM; i++) {//创建一条文本消息

TextMessage message = session.createTextMessage("ActiveMQ 发送消息" +i);

System.out.println("发送消息:Activemq 发送消息" +i);//通过消息生产者发出消息

messageProducer.send(message);

}

}

}

View Code

编写消费者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSConsumer {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 voidmain(String[] args) {

ConnectionFactory connectionFactory;//连接工厂

Connection connection = null;//连接

Session session;//会话 接受或者发送消息的线程

Destination destination;//消息的目的地

MessageConsumer messageConsumer;//消息的消费者//实例化连接工厂

connectionFactory = newActiveMQConnectionFactory(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(100000);if(textMessage != null){

System.out.println("收到的消息:" +textMessage.getText());

}else{break;

}

}

}catch(JMSException e) {

e.printStackTrace();

}

}

}

View Code

2、测试

1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。

2)运行发送者JMSProducer,Eclipse控制台输出,如下图:

76180a77b75aae9ae27d946c49635b0c.png

生产者生产10条消息。

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

d264a836458a83238fa7005aae783e23.png

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

e8c74c88e0fcafe545a6c90cf5168e1a.png

如果这些队列中的消息,被删除,消费者则无法消费。

3)继续运行消费者JMSConsumer,eclipse控制台打印消息,如下:

d5ff2eff7f2218609601c587d0cd54e6.png

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

cf8c54f3c884807af2aea68ac4516109.png

可以看到HelloWorld的消息队列发生变化,多一个消息者,队列中的10条消息被消费了,点击Browse查看,已经为空了。

点击Active Consumers,我们可以看到这个消费者的详细信息:

fb5db3badfb713e59abd4c25c2603046.png

3、总结

点对点消息的传播,生产者向特定的消息队列传播消息,一个消费者从该队列读取消息。生产者不需要在接收者接收消息时处于运行,消费者也不需要生产者在发送消息时处于运行状态,队列相当于一个中间的仓库,生产者发送消息,立即返回状态发送成功。等消费者上线时 ,才接受消息。

Pub/Sub(发布订阅模型)

就像订阅报纸。我们可以选择一份或者多份报纸,比如:北京日报、人民日报。这些报纸就相当于发布订阅模型中的topic。如果有很多人订阅了相同的报纸,那我们就在同一个topic中注册,对于报纸发行方,它就和所有的订阅者形成了一对多的关系。如下:

6379a7fa33b31302255aeed7c7180ca8.png

1、建立项目

建立一个java项目,导入jar包。

编写发布者(这里和点对点的不同就是不再是创建消息队列,而是创建topic。而且也不是消息生产者而是发布者)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSProducer {//默认连接用户名

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 = 10;public static voidmain(String[] args){

ConnectionFactory factory ;//连接工厂

Connection connection = null ; //连接

Session session ; //会话,接收或者发送消息的线程

Destination destination; //消息的目的地

MessageProducer messageProducer; //消息生产者//实例化连接工厂

factory = newActiveMQConnectionFactory(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 voidsendMessage(Session session, MessageProducer mp) throws JMSException{for(int i = 0;i

TextMessage message= session.createTextMessage("ActiveMq 发布的消息" +i);

System.out.println("发布消息:" + "ActiveMq 发布的消息" +i);

mp.send(message);

}

}

}

View Code

编写订阅者1

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSConsumer1 implements MessageListener {public voidonMessage(Message message) {if(message instanceof TextMessage) {

TextMessage txtMsg=(TextMessage) message;try{

System.out.println("订阅者一接收到了消息:" +txtMsg.getText());

}catch(JMSException e) {

e.printStackTrace();

}

}

}public voidreceive() {//消费者的主要流程

Connection connection = null;try{//1.初始化connection工厂

ConnectionFactory connectionFactory = newActiveMQConnectionFactory();//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(newJMSConsumer1());

}catch(JMSException e) {

e.printStackTrace();

}

}public static voidmain(String[] args) {newJMSConsumer1().receive();

}

}

View Code

编写订阅者2

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSConsumer2 implements MessageListener {public voidonMessage(Message message) {if(message instanceof TextMessage) {

TextMessage txtMsg=(TextMessage) message;try{

System.out.println("订阅者二接收到了消息:" +txtMsg.getText());

}catch(JMSException e) {

e.printStackTrace();

}

}

}public voidreceive() {//消费者的主要流程

Connection connection = null;try{//1.初始化connection工厂

ConnectionFactory connectionFactory = newActiveMQConnectionFactory();//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(newJMSConsumer1());

}catch(JMSException e) {

e.printStackTrace();

}

}public static voidmain(String[] args) {newJMSConsumer2().receive();

}

}

View Code

2、测试

1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。

2)发布订阅模型,要先启动订阅者,订阅者先订阅topic,再发布消息。

启动订阅者,这里我启动两个,可以看到在topic中注册了两个消费者:

108d348f65e1a9d1dc09da32bb64026e.png

3)启动发布者,如下:

ee3c12ed590f605f82ac59e1e842cd6b.png

9920ab0baf722a3e0775248ab88d1e2e.png

发布者发布了10条数据,但是出队的有20条,因为有两个订阅者。

3、总结

发布者向一个特定的消息主题发布消息,0或者多个订阅者可能接收到来自特定消息主题的消息感兴趣。其中发布者和订阅者不知道对方的存在。

配置消息是否持久化

1、建立项目

//配置消息是否持久化,DeliverMode有2种方式

/*

* 1 不持久化:服务器重启之后,消息销毁

* 2 持久化:服务器重启之后,该消息仍存在

*/

messageProducer.setDeliveryMode(2);

编写发布者

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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 classJMSProducer {//默认连接用户名

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 = 10;public static voidmain(String[] args){

ConnectionFactory factory ;//连接工厂

Connection connection = null ; //连接

Session session ; //会话,接收或者发送消息的线程

Destination destination; //消息的目的地

MessageProducer messageProducer; //消息生产者//实例化连接工厂

factory = newActiveMQConnectionFactory(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(2);//发送消息

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 voidsendMessage(Session session, MessageProducer mp) throws JMSException{for(int i = 0;i

TextMessage message= session.createTextMessage("ActiveMq 发布的消息" +i);

System.out.println("发布消息:" + "ActiveMq 发布的消息" +i);

mp.send(message);

}

}

}

View Code

2、测试

1)首先,启动ActiveMQ,在浏览器中输入:http://localhost:8161/admin/,然后开始执行程序。

2)先2个启动订阅者,再启动发布者,如下:

9d1e532e63bf0d36804b9c6d74044456.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值