java - 管理 JMS 消息到多个服务器的传递

标签 java spring jms tibco tibco-ems

我们的应用程序将 Spring Boot 和 JMS 消息与 Tibco 结合使用。我们有两个生产服务器同时运行和处理消息。服务器正在监听同一个队列。每个服务器有 10 个并发监听器。我不希望两台服务器同时处理同一条消息。没有什么能阻止我们的队列有重复的消息,就像我们可以在队列中有消息 A 的两个副本一样。如果队列中的消息是:A、A、B、C、D,那么如果第一个 A 被传递到 server1,第二个 A 被传递到 server2,并且两个服务器同时处理 A,那么它们有可能创建重复实体。我想找到一种方法将所有 A 消息仅发送到一个服务器。我不能使用 Message Selector b/c 我们在两台服务器上运行相同的代码库。这是我正在考虑的:

根据消息,在 header 中设置属性。一旦消息被传送到 process() 方法,根据哪个服务器正在处理消息,要么丢弃,简单地返回消息,要么处理消息并确认它。此解决方案的问题在于,由于我们需要动态找出哪个服务器正在处理消息,因此需要对服务器名称进行硬编码,这意味着如果服务器移动,代码就会中断!

其他可能有效的解决方案是 Destination 字段。

https://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/jms.html

Destinations, like ConnectionFactories, are JMS administered objects that can be stored and retrieved in JNDI. When configuring a Spring application context you can use the JNDI factory class JndiObjectFactoryBean / to perform dependency injection on your object’s references to JMS destinations.

这是我以前从未做过的事情。无论如何,配置它选择正确服务器以将消息路由到的目标?意思是,如果 message1 应该传送到 server1,那么它甚至不会传送到 server2 并保留在队列中直到 server1 使用它?

还有哪些其他方法可以实现这一点?

编辑:

我仍然不知道将某些消息仅发送到一台服务器进行处理的最佳方式是什么,但是,接受了使用数据库作为验证的响应,b/c 这是我们考虑避免在处理时创建重复实体的方法数据。

最佳答案

我认为使用 JMS 目标的想法是行不通的,因为 JMS 规范中没有任何内容可以保证目标与代理之间的任何类型的链接。目的地只是对特定于提供者的队列/主题名称的封装。

这里的底线是,您要么需要首先防止重复消息,要么有一些方法来协调消费者在他们被从队列中拉出后处理重复消息。我认为您可以使用数据库等外部系统来执行其中任何一项操作,例如:

  • 在生成消息时,检查数据库是否有消息已发送的指示。如果没有找到任何指示,则将记录写入数据库(将需要使用主键以防止重复)并发送消息。否则不要发送消息。
  • 当使用消息时,检查数据库是否有消息正在(或已经)被使用的指示。如果没有找到任何指示,则将记录写入数据库(将需要使用主键来防止重复)并处理消息。否则只是确认消息而不处理它。

关于java - 管理 JMS 消息到多个服务器的传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51851296/

相关文章:

java - 如何使用 play framework 2.1.0 更改 future 超时

java - 为什么Java中的final常量可以被重写?

java - jackson 根据属性名称反序列化

java - Spring MVC 移动到列表中的下一条记录

html - 保留 <form :input type ="file"> with Spring MVC 的值

java - MessageListener 未监听 Oracle 队列中的消息

java - 为什么在 Hibernate 中需要在 session.delete() 之后调用 session.flush()?

java - 包含 Eureka 时, Autowiring RestTemplate 会导致 "argument type mismatch"

java - 无法在 weblogic、JMS、java 中设置 JMS_IBM_MQMD_MsgId 的属性值

apache-camel - 如何处理 JMS 重新传递到我的 Camel Route,但仍然允许消息删除