ActiveMQ编程

ActiveMQ作用 & 优势

提供标准的产生、发送、接收消息的接口简化企业应用的开发。
 
支持JMS1.1和J2EE 1.4规范的 JMS Provider实现(持久化,XA消息,事务)
对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去
支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
支持通过JDBC和journal提供高速的消息持久化
jboss mq 与jboss,joram与jonas(objectweb组织),ActiveMQ 与Geronimo(ASF APACHE基金组织),而在这3个之间,从网络底层来看,只有ActiveMQ使用了NIO,单从这个角度来看ActiveMQ在性能上会有一定的优势。
 
1、实现JMS1.1规范,支持J2EE1.4以上。
2、可以在任何JVM运行。
3、支持多种语言客户端(java, C, C++, Ajax, ActionScript等等)。
4、支持多种协议(stomp, openwire, REST)。
5、良好的Spring支持。
6、速度很快,比JBossMQ快十倍。
7、与OpenJMS、JBossMQ等开源JMS Provider相比,ActiveMQ有Apache的支持,持续发展的优势明显 。

两种消息通信模型

点到点模型:一个消息只能有一个接收者
点到点模型,消息生产者产生一个消息后,把这个消息发送到一个Queue(队列)中,然后消息接收者再从这个Queue中读取,一旦这个消息被一个接收者读取之后,它就在这个Queue中消失了,所以一个消息只能被一个接收者消费。
 
发布/订阅模型:一个消息可以有多个接收者
与点到点模型不同,发布/订阅模型中,消息生产者产生一个消息后,把这个消息发送到一个Topic中,这个Topic可以同时有多个接收者在监听,当一个消息到达这个Topic之后,所有消息接收者都会收到这个消息。
 

消息堆积问题

Notify在设计思路上与传统的MQ有一定的不同:

1. 为了消息堆积而设计系统

2. 无单点,可自由扩展的设计

 

在Notify的整体设计中,我们最优先考虑的就是消息堆积问题,在目前的设计中我们使用了持久化磁盘的方式,在每次用户发消息到Notify的时候都将消息先落盘,然后再异步的进行消息投递,而没有采用激进的使用内存的方案来加快投递速度。

ActiveMQ常用类

ConnectionFactory 接口(连接工厂)
用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。
Connection 接口(连接)
连接代表了应用程序和消息服务器之间的通信链路
在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。
Destination 接口(目标)
目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。
MessageConsumer 接口(消息消费者)
由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。
MessageProducer 接口(消息生产者)
由会话创建的对象,用于发送消息到目标。
用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
Message 接口(消息)
是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分:消息头(必须):包含用于识别和为消息寻找路由的操作设置。 一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。 一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。 消息接口非常灵活,并提供了许多方式来定制消息的内容。
Session 接口(会话)
表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。
会话的好处是它支持事务。
如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这些消息。
在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。
 
 

消息发送步骤

消息产生者向JMS发送消息
(1)创建连接使用的工厂类JMS ConnectionFactory 
(2)使用管理对象JMS ConnectionFactory建立连接Connection 
(3)使用连接Connection 建立会话Session
(4)使用会话Session和管理对象Destination创建消息生产者MessageSender 
(5)使用消息生产者MessageProducer发送消息
消息消费者从JMS接受消息
(1)创建连接使用的工厂类JMS ConnectionFactory 
(2)使用管理对象JMS ConnectionFactory建立连接Connection 
(3)使用连接Connection 建立会话Session 
(4)使用会话Session和管理对象Destination创建消息消费者MessageReceiver 
(5)使用消息消费者MessageConsumer接受消息
 
 
 

持久订阅设置

PERSISTENT传送模式,为订阅者时使用持久订阅,这样可以保证 Pub/Sub 程序接收所有发布的消息。 
 
消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscription),非持久订阅只有当客户端处于激活状态,也就是和 ActiveMQ 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。
持久订阅时,客户端向ActiveMQ 注册一个识别自己身份的 ID,当这个客户端处于离线时,ActiveMQ会为这个 ID 保存所有发送到主题的消息,当客户端再次连接到ActiveMQ 时, 会根据自己的 ID 得到所有当自己处于离线时发送到主题的消息。
 
持久订阅会增加开销,同一时间在持久订阅中(某一特定ID)只有一个激活的用户。
 
建立持久订阅的步骤: 1. 为连接设置一个客户 ID; 2. 为订阅的主题指定一个订阅名称; 上述组合必须唯一。 
区分消费者,是通过clientID订阅名称来区分的。
 
 

代码中使用持久化订阅

// 创建connection
connection = connectionFactory.createConnection();
connection.setClientID("bbb"); //持久订阅需要设置这个。
connection.start();
 
// 创建session
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
 
// 创建destination
Topic topic = session.createTopic("userSyncTopic"); //Topic名称
 
//MessageConsumer consumer = session.createConsumer(topic); //普通订阅
MessageConsumer consumer = session.createDurableSubscriber(topic,"bbb"); //持久订阅
 
 
还有一点,消息的生产者,发送消息时用使用持久模式MessageProducer producer = ...;producer.setDeliveryMode(DeliveryMode.PERSISTENT);不设置,默认就是持久的
 
使用相同的“clientID”,则认为是同一个消费者。两个程序使用相同的“clientID”,则同时只能有一个连接到activemq,第二个连接的会报错。
 
activemq的设置在conf/activemq.xml中,默认消息是保存在data/kahadb中,重启activemq消息不会丢。
 
可以访问http://localhost:8161/admin/index.jsp:查看当前的队列、Topic和持久订户的信息、发送消息等等,很方便。
 
可以复制activemq-jdbc.xml中的内容过来,修改一下,就可以把消息保存在其它数据库中了。
 
 

 

ActiveMQ与Spring集成

工程需引入activemq-all-5.11.1.jar作为类库文件。
 
 
 

文章&资料

——ActiveMQ - - 博客频道- CSDN.NET:http://blog.csdn.net/zhu_tianwei/article/category/2842669
——ActiveMQ 分析系列(一):http://blog.csdn.net/Yoara/article/details/41046653
——ActiveMQ发消息、收消息、持久化,查询队列剩余消息数、出队数的实现:http://my.oschina.net/jinghaichao/blog/57318
posted @ 2015-07-27 18:29  Uncle_Nucky  阅读(356)  评论(0)    收藏  举报