ActiveMQ发消息和收消息
来自:http://blog.163.com/chengwei_1104/blog/static/53645274201382315625329/
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
下面详细的解释常用类的作用
ConnectionFactory 接口(连接工厂) 用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。
Connection 接口(连接) 连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。
Destination 接口(目标) 目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。
MessageConsumer 接口(消息消费者) 由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
MessageProducer 接口(消息生产者) 由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
Message 接口(消息) 是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分: 消息头(必须):包含用于识别和为消息寻找路由的操作设置。 一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。 一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。 消息接口非常灵活,并提供了许多方式来定制消息的内容。
Session 接口(会话) 表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。
Session 接口(会话) 表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。
JMS的消息模式有
1.点对点的消息模式(Point to Point Messaging)
2.发布订阅模式(publish – subscribe Mode)
这里基于点对点的消息模式进行ActiveMQ发消息和收消息过程的分析,请看模型图:
点对点的消息发送方式主要建立在 Message Queue,Sender,reciever上,Message Queue 存贮消息,Sneder(客户端A) 发送消息,receive(客户端B)接收消息。具体点就是客户端A发送Message Queue ,而 客户端B从Queue中接收消息和"发送消息已接受"到Quere,确认消息接收。消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在 任何时刻发送信息到Queue,而不需要知道接收客户端是不是在运行 。
package com.activemq.queue; import java.util.Date; 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.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public class ActiveMqTest { private static String queueName = "activemq_queue_"; public static void main(String[] args) {
Receiver receiver=new Receiver();
Sender sender =new Sender();
try {
sender.send();
receiver.receive();
} catch (Exception e) {
e.printStackTrace();
}
} static class Receiver {
public static void receive() throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(Boolean.TRUE,
Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
MessageConsumer consumer = session.createConsumer(destination);
//第一种情况
int i = 0;
while (i < 3) {
i++;
TextMessage message = (TextMessage) consumer.receive();
session.commit();
// TODO something....
System.out
.println("收到消息:" +message.getText());
}
session.close();
connection.close();
//----------------第一种情况结束----------------------
//第二种方式
// consumer.setMessageListener(new MessageListener() {
// public void onMessage(Message arg0) {
// if(arg0 instanceof TextMessage){
// try {
// System.out.println("arg0="+((TextMessage)arg0).getText());
// } catch (JMSException e) {
// e.printStackTrace();
// }
// }
// }
// });
//第三种情况
// while (true) {
//Message msg = consumer.receive(1000);
//TextMessage message = (TextMessage) msg;
//if (null != message) {
//System.out.println("收到消息:" + message.getText());
//}
//}
}
}
static class Sender {
public static void send() throws Exception {
ConnectionFactory connectionFactory = null;
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,"tcp://localhost:61616"); Connection connection = connectionFactory.createConnection();
connection.start(); Session session = connection.createSession(Boolean.TRUE,
Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName); MessageProducer producer = session.createProducer(destination);
for (int i = 0; i < 3; i++) {
TextMessage message = session.createTextMessage("count"+new Date().getTime());
Thread.sleep(1000);
// 通过消息生产者发出消息
System.out.println("发送消息"+i+new Date());
producer.send(message);
}
session.commit();
session.close();
connection.close();
}
}
}
Sender主要的作用是发送消息,Receiver主要的作用是接受消息,并且显示一下接收消息的内容,这里详细的解释接受消息的方法:
(1)第一种方法使用consumer.receive() 或 consumer.receive(int timeout)接受消息,消息的接收者会一直等待下去,直到有消息到达,或者超时。
其实第一种方法和第三种方法接受原理一样,区别是第一种知道要接受消息的条数,接受完消息,手动关系连接。而第三种不知道要接受多少条数据,所以使用while (true) 死循环直接在接受消息。
(2)第二种方法:消息消费者注册一个MessageListener,当有消息到达的时候,会回调它的onMessage()方法。
这里需要注意的是,你注册完成MessageListener,千万不要关闭连接session.close();和connection.close();因为你刚刚注册完成监听器,就把连接关闭,就不会受到消息,所以监听器中也不会有处理。(这个问题可把我整哭了,搞了半天,才弄明白)
请看ActiveMQ 页面上显示队列的信息
name是队列名称
Number Of Pending Messages 是队列中有多少个消息等待出队列
Number Of Consumers 是队列中有多少个消费者
Messages Enqueued 是队列共有多少个信息
Messages Dequeued 是队列中已经出列多少个消息
开发中遇到的异常:
(1)javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused: connect
拒绝连接,原因是activemq服务器没有开启。
解决办方法:开启activemq服务器,请参照《activemq跑起来》
ActiveMQ发消息和收消息的更多相关文章
- activemq的高级特性:消息持久订阅
activemq的高级特性之消息持久订阅 如果采用topic模式发送的时候,mq关闭了或消费者关闭了.在启动的时候,就会收不到mq发送的消息,所以就会出现消息持久订阅. 消息持久订阅:第一:消息要持久 ...
- QQ好友状态,QQ群友状态,究竟是推还是拉? 网页端收消息,究竟是推还是拉?
https://mp.weixin.qq.com/s/KB1zdKcsh4PXXuJh4xb_Zw 网页端收消息,究竟是推还是拉? 原创 58沈剑 架构师之路 2020-12-28 https:/ ...
- ActiveMQ集群下的消息回流功能
------------------------------------------------------------------ "丢失"的消息 如果有broker1和brok ...
- activemq消息生产者与消息消费者简单例子
消息生产者HelloQueueProducer.java package activemq.test; import javax.jms.Connection;import javax.jms.Con ...
- VC里OnPaint几点要注意的地方(没有invalidate,系统认为窗口没有更新的必要,于是就对发来的WM_PAINT消息不理不睬)
写在属于自己的体会,哪怕只是一点点,也是真的懂了.否则有那么多书,如果只是不过脑子的学一遍看一遍,又有谁真的掌握了这些知识呢? 这样你或许就明白了为什么不能直接用SendMessage和PostMes ...
- 解决Springboot整合ActiveMQ发送和接收topic消息的问题
环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</group ...
- 为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点?
面试题 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka.ActiveMQ.RabbitMQ.RocketMQ 都有什么区别,以及适合哪些场景? 面试官心理分析 其实面试官主要是想看看: ...
- ActiveMQ之JMS及保证消息的可靠性<持久化、事务、签收>(三)
1.JAVAEE 是一套使用Java 进行企业级开发的13 个核心规范工业标准 , 包括: JDBC 数据库连接 JNDI Java的命名和目录接口 EJB Enterprise java b ...
- 【C#】分享一个可携带附加消息的增强消息框MessageBoxEx
--------------201507160917更新--------------- 无意中发现标准消息框在Windows7是有声音的,只是在Windows server 2008(R2)无声,而我 ...
随机推荐
- FJOI省队集训 florida
省队成员(大部分)都没来...像我这种沙茶天天写写玄学算法都能排在榜上面...果然正解写挂的人远比暴力拍对的人少啊...陆陆续续会补一些题解.(不过有些题太神了可能补不上题解 有n个物品,两个袋子A和 ...
- 报错问题:InnoDB: Error: log file ./ib_logfile0 is of different size
InnoDB: Error: log file ./ib_logfile0 is of different size bytesInnoDB: than specified in the .cnf f ...
- od破解实例
百度经验: http://jingyan.baidu.com/article/636f38bb4091e4d6b84610a8.html pc6 http://www.pc6.com/edu/6278 ...
- 窗口 - dialog - 概述与基本使用
什么是dialog 对话框是一种特殊的窗口,它在顶部有一个工具栏,在底部有一个按钮栏.默认情况下,对话框(dialog)只有一个显示在头部右侧的关闭工具. 用户可以配置对话框行为来显示其他工具(比如: ...
- 044医疗项目-模块四:采购单模块—采购单保存(Dao,Service,Action三层)
我们上上一篇文章(042医疗项目-模块四:采购单模块-采购单明细添加查询,并且把数据添加到数据库中)做的工作是把数据插入到了数据库,我们这篇文章做的是042医疗项目-模块四:采购单模块-采购单明细添加 ...
- xenserver磁盘扩容扩不大问题解决
http://www.osyunwei.com/archives/7956.html xenserver将磁盘扩大后,fdisk可以看到容量大了 但是df -h确实没大? 解决: fdisk /d ...
- 【转】aspx与aspx.cs的关系
原文地址: http://www.cnblogs.com/axzxs2001/archive/2009/01/19/1378383.html 在vs中,有很多朋友问起,在一个网站项目中的aspx和as ...
- 微软虚拟学院MVA 字幕获取方法
微软虚拟学院(MVA)上有一些不错的视频教程,但是,蛋疼的一点那就是视频要不就慢,要不就卡,总之当你的思维跟着视频深入的时候,duang~,卡一下,说不定就要重头开始,所幸的是提供了视频下载,下载速度 ...
- 《程序设计教学法--以Java程序设计为例》
<程序设计教学法--以Java程序设计为例> 当老师上的第一门课就是<Java程序设计>,工作以来,断断续续上了近十次课了吧.十几年来,教材.课程内容.教学方法.教学手段不断改 ...
- 我这样理解js里的this
关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:k ...