我有一对 JBoss 5.1 服务器集群在一起充当容错 JMS 服务器。
我将它们配置为使用 MySQL 数据存储(在 mysql-persistence-service.xml 中启用了集群设置),我通过定义在 destinations-service.xml 中创建了一个主题 mbean:
<mbean code="org.jboss.jms.server.destination.TopicService" name="jboss.messaging.destination:service=Topic,name=ECM-PRM-Topic" xmbean-dd="xmdesc/Topic-xmbean.xml">
<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
<depends>jboss.messaging:service=PostOffice</depends>
<attribute name="Clustered">true</attribute>
<attribute name="SecurityConfig">
<security>
<role name="ecm-role" write="true" />
<role name="prm-role" read="true" create="true" />
</security>
</attribute>
我的客户端(J2SE!)正在使用以下方式连接到此 JMS 服务器:
// Step 1. Create an initial context to perform the JNDI lookup.
initialContext = new InitialContext(p);
// Step 3. Perform a lookup on the Connection Factory
ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ClusteredConnectionFactory");
// Step 2. Perfom a lookup on the queue
Destination target = (Destination)initialContext.lookup("/topic/ECM-PRM-Topic");
当发生以下事件序列时:
- Node1 已启动,Node2 已关闭。
- 客户端连接到 JMS 并在主题“ECM-PRM-Topic”上创建一个持久订阅者。
- 客户端断开连接,离开持久订阅。
- 其他一些客户端发布有关“ECM-PRM-Topic”主题的消息。
- 节点 1 宕机。
- Node2 上升。
- 其他一些客户端再次发布关于“ECM-PRM-Topic”主题的消息。
- 客户端再次连接到持久订阅。
- 客户端断开连接
- 节点 1 上升。
- 客户端再次连接到持久订阅。
第 4 步中发布的消息存储在数据库中,正在等待(我可以在 MySQL 中看到)客户端重新连接。(没关系)
在步骤 6 中启动的节点不知道关于该主题的任何持久订阅。(为什么??)
步骤 7 中发布的消息立即消失。(因为没有已知的持久性或任何连接的客户端)
当客户端在第 8 步连接时,它会创建一个新的持久化对象,并且不会向其传递任何消息(但 MySQL 中仍有消息)。
在步骤 10 中,客户端接收到来自持久性的所有消息,不包括来自步骤 7 的消息完全丢失。
我希望 100% 保证不会丢失任何消息。所有消息都应存储在持久数据库和 MySQL 数据库中,直到客户端使用。
有什么建议有什么问题吗?
有没有办法在 XML 文件中配置 JBoss 中的持久订阅(在任何客户端创建 DurableSubscriber 之前)?
我使用的完整客户端代码在这里