仅使用JMS主题一次

时间:2013-09-09 00:14:38

标签: database jms message-queue jms-topic

我有一个产生独特消息的JMS 主题

我在 n 计算机(客户端)上部署了一个简单的Web应用程序,它所做的就是将消耗的消息传递到另一个系统(目标系统)。

注意:

  • NOT 对JMS有控制权。
  • DO 可以控制客户端。
  • NOT 可以控制客户端收到消息的目标系统。

我的问题是:

如何确保消息由其中一个客户端写入(进入目标系统)并且永远不会被另一个客户端再次写入(就好像JMS是一个不是主题的队列),知道每个msg都有uniqueId?

我在想两个解决方案:

  1. 创建另一个消耗该主题的JMS队列,这个队列将被其中一个 n 客户端用于每个消息。

  2. 有某种共享位置(memcache)具有消耗的消息ID消息,并且在客户端将消耗的消息发送到目标系统之前,我将不得不检查共享存储(memcache)之前有此ID,如果没有,则发送到目标系统。

  3. 您怎么看?

    更新

    最终收到消息的系统不是RDBMS,甚至不在我的控制之下。我只是将一些msg从一个系统发送到另一个系统。 (实际上它是Apache Flume by不受我的控制)

2 个答案:

答案 0 :(得分:1)

  • 使用另一个队列可能导致另一个问题:您的 n 计算机中只有一个必须侦听该主题。如果你必须确保没有消息丢失,你必须以某种方式同步订阅者。添加单独的订户会增加系统复杂性。

  • 添加另一个存储(共享内存群集,内存缓存,...)会增加系统复杂性(并且您已经拥有一个通用存储)。

所以最好的事情是使用队列而不是主题。你不能改变这个,因此我建议这个选项:

  • 所有JMS消息都具有唯一的消息ID。您可以将此ID与该列上的唯一索引一起存储在数据库中。所以你可以插入(并忽略一个唯一的约束违规错误)。不太好,但它在集群中工作,并不会增加系统复杂性。如果消息已存在于数据库中,则变更是在之前检查。

答案 1 :(得分:0)

如果可能,我不会部署 n 客户端来监听该主题。因为客户端完成的工作是每次发布消息时只将一个消息副本转发到另一个组件或数据库。相反,我会去创建一个持久订阅,只有一个客户端监听该订阅。此客户端将消息转发到数据库。如果客户端未运行,则消息提供程序将保留消息,并在客户端再次运行时传递。