业务场景:A系统通过MQ推送数据到B系统。通过发布订阅的消息传送模型。由于涉及到的数据比较重要:比如是关于资金、交易、股票价格的信息。要保证B系统一定收到A系统发送的消息,考虑B系统会断电重启之类异常,故设置持久订阅模式。可以保证在B订阅A主题后,因为断电,订阅者状态变为不活动的。在B系统重启后,依然可以收到消息。(刚才的逻辑完全可以使用点对点的消息传送模型实现,但是我这个场景的前提是使用发布订阅模式,所以就不考虑那种情况了。)
代码方面,与普通的发布订阅模式一样,主要的不同是必须设置唯一的客户端ID和订阅者ID。
connection = factory.createConnection();
connection.setClientID("hi man");//设置客户端ID
connection.start();
// 创建一个会话实例 , 该会话不使用事务 , 采用自动确认消息的机制
// 如果设置为客户端确认,需要手动确认!
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("queue2");
javax.jms.TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic, "sub2");//第二个参数是订阅者ID。
注意:很多情况下,持久化订阅非常有用,但有的时候并非如此。虽然使用持久还是非持久通常由业务决定。但是,我们还必须考虑消息消耗的存储容量。比如有一个持久订阅者长期处于不活动的状态,那么jms服务器就必须为这个订阅者存储数以千计、万计的无用信息,浪费JMS数据仓库的宝贵空间。因为,我们必须得考虑这个问题。