0

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

而且我在n台机器(客户端)上部署了一个简单的 webapp,它所做的就是将使用的 msg 放入另一个系统(目标系统)。

笔记:

  • 无法控制 JMS。
  • 确实可以控制客户。
  • 无法控制将由客户端接收消息的目标系统。

我的问题是:

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

我正在考虑两种解决方案:

  1. 创建另一个从该主题消费的 JMS 队列,并且该队列将由n 个客户端之一为每个 msg 消费一次。

  2. 有某种共享位置(memcache),其中包含已使用 msgs 的消息 ID,并且在客户端将已使用 msg 发送到目标系统之前,我必须检查共享存储(memcache)之前是否具有此 ID,如果然后不发送到目标系统。

你怎么看?

更新

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

4

2 回答 2

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

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

所以最好的事情真的是使用队列而不是主题。您无法更改此设置,因此我建议使用此选项:

  • 所有 JMS 消息都有一个唯一的消息 ID。您可以将此 ID 与该列上的唯一索引一起存储在数据库中。所以你可以插入(并忽略一个唯一的约束违规错误)。不是很好,但它可以在集群中工作,并且不会增加系统复杂性。一个变体是在之前检查消息是否已经存在于数据库中。
于 2013-09-09T10:26:28.890 回答
0

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

于 2013-09-10T04:23:33.783 回答