jms 订阅发布 topic持久化是一定要在订阅者先声明需要持久化消息吗

2025-04-30 08:27:46
推荐回答(2个)
回答1:

非持久化订阅持续到它们订阅对象的生命周期。这意味着,客户端只能在订阅者活动
时看到相关主题发布的消息。如果订阅者不活动,它会错过相关主题的消息。
如果花费较大的开销,订阅者可以被定义为durable(持久化的)。持久化的订阅者注
册一个带有JMS保持的唯一标识的持久化订阅(subscription)。带有相同标识的后续订阅
者会再续前一个订阅者的订阅状态。如果持久化订阅没有活动的订阅者,JMS会保持订阅
消息,直到消息被订阅接收或者过期。

看 Jms 规范看得晕(可能被翻译得不好),看下关键代码好理解。
要用持久化订阅,发送消息者要用 DeliveryMode.PERSISTENT 模式发现,在连接之前设定。订阅者要设置客户端名,调用 session.createDurableSubscriber。
Sender:
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic("my-topic");

MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT); //设置保存消息
connection.start(); //设置完了后,才连接
[java] view plaincopy
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic("my-topic");

MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT); //设置保存消息
connection.start(); //设置完了后,才连接
Receiver:
connection.setClientID("client-name");
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Topic topic = session.createTopic("my-topic");
MessageConsumer consumer = session.createDurableSubscriber(topic, "my-sub-name");
connection.start();
[java] view plaincopy
connection.setClientID("client-name");
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Topic topic = session.createTopic("my-topic");
MessageConsumer consumer = session.createDurableSubscriber(topic, "my-sub-name");
connection.start();
最后,先运行 Receiver,目的是注册这个客户端(好让消息中间件服务器为这个客户保存消息),然后关了这个 Receiver, 启动 Sender,发现消息,再启动 Receiver 就可以收到离线消息。

回答2:

不是的,
持久化是不一定要在订阅者先声明需要持久化消息得