JMS Architecture
一般将ConnectionFactory和Destination绑定到JNDI上,然后Client查找JNDI来获取。对于ActiveMQ可以直接构造ConnectionFactory和Destination。
Connection和Destination就是这里的Administed Objects。
JMS有两种形式:
1. 点到点(Point to Point)
2. 发布/订阅(Publish/Subscribe)
它们的Destination分别是Queue和Topic。
消息消费者可以同步也可以异步的消费消息,同步consumer.receive(),异步通过MessageListener。
JMS API
1. 通过ConnectionFactory来创建Connection。
2.Connection创建Session,可以指定clientID,实现durable的消息,另外start()开始消息传输。
3. 创建或获取Destination
4.通过Session和Destination来创建Producer和MessageConsumer,指定Session的LocalTransaction和Acknowlege信息,Session管理LocalTransaction,创建durable的subscriber,还可以通过Session来创建消息。
5. Producer发送消息,Consumer消费消息。
细节概念
1. Persisent
2. Expiration
3. Acknowledgment
4. Durable
5. Local Transaction
6. Redelivery
Persistent
传输模式(DeliveryMode),默认是Persistent。如果是非Persistent的,Server当掉,消息也就丢失啦。
API调用:
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Expiration
消息的存活时间,默认消息永不过期。
API调用: producer.setTimeToLive()
Acknowledgment
消息收到的确认方式,三种,分别是
Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE和Session.DUPS_OK_ACKNOWLEDGE。
AUTO_ACKNOWLEDGE
一次只有一次
对于MessageListener,当onMessage()方法结束后,自动发送确认信息。
CLIENT_ACKNOWLEDGE
Client代码来维护,通过调用message.acknowledge(),确认了此Session中所有收到的消息。
对于非Queue和DurableSubscription,消息随着Session的关闭而被drop掉。而对于Queue和DurableSubscription,Server会保留这些信息,重新发送给consumer。
对于事务的Session来说,伴随事务的提交,Acknowledgment发生。
Durable
Durable是针对Subscription来说的,DurableSubscription在特性上和Queue相同。
Durable Subscription通过Client ID和subscriptionname来区分,某一时刻,只有一个Client ID的连接,因此只能有一个Client ID下的subscription。
利用JConsole通过JMX可见监控ActiveMQ:
图片中显示出Subscription的结构,Subscription->Durable目录下的nesta_client_id和nesta_faint就是ClientID,叶子节点是两个与Client ID同名的subscription name。
Durable表示在Subscriber停掉的情况下,还可以收到在down掉这段时间内的消息。
从图上可以看出,如果没有Durable的Subscription,Message M2,M4和M5将被丢失。
session.createDurableSubscriber()
session.unsubscribe()
Local Transaction
消息发送事务,对于同一Session的多消息发送和多消息接收,作为一个事务。
发送消息和接收消息的两个客户端,拥有各自的Connection和Session,所以是两个事务,不是一个事务。
Redelivery
对于参与事务的消费者,它可以session.rollback(),这是server就会重发消息。在ActiveMQ中设置RedeliveryPolicy,ActiveMQ最大重新传输次数为6。