Java JMS - 如何处理每个目标没有并行性的大量目标

时间:2011-07-18 23:50:57

标签: java-ee jms messaging

我正在寻找有关基于JMS的架构的建议......

我的应用程序需要代表数千个不同的目的地接收JMS消息,然后通过非JMS协议(即这是一个网关)传送到目的地。允许的解决方案适用于最初通过发送到一个JMS队列或每个目标转到一个队列的所有消息。

解决方案需要在大量目的地(以及每秒许多消息)中表现良好。

要求是:

  1. 在将邮件传递到一个目标的过程中,不会为该目标处理其他邮件。
  2. 根据发送到JMS的时间,每个目的地必须发送FIFO消息
  3. 没有可能丢失(JMS事务语义足够)
  4. 交付必须与多个目的地并行进行(除了每个目的地没有并行性)
  5. 在不同的机器上有几个相同的应用程序实例,它们都是一次性运行的。他们可以通过共享缓存或JMS进行通信,但通信应该简单而且极少。
  6. 网关将驻留在J2EE容器中,但不需要使用MDB的
  7. 提前致谢

2 个答案:

答案 0 :(得分:1)

听起来您可以使用每个目标一个队列将来自不同发布者的邮件传递到网关。然后,网关需要是多线程的,每个队列消费者有一个线程。因此,对于发布到n个目的地的x个生产者,网关将需要n个线程,每个目的地一个。此体系结构将为您提供吞吐量,该吞吐量由网关在将消息转发到其最终目标之前对消息执行的处理量以及在网关之前由最终目标处理消息所需的时间来控制可以发送以下信息。

此设计有两个缺点:

  1. 您的应用程序将出现单点故障 - 网关。您将无法对其进行负载平衡,因为消耗顺序对您很重要,因此您不希望2个网关耗尽相同的队列。
  2. 每个队列都可能成为瓶颈,阻塞未经过足够快速处理的消息。
  3. 如果您可以控制发布者,您是否更愿意使用所选择的目标协议将消息直接从发布者传输到最终目的地,而无需通过网关(除了作为一个网关之外似乎没有任何其他目的)性能瓶颈和单点故障)?如果您能够实现这一目标,那么您的下一个任务就是将最终目的地教给多处理请求,尽可能放宽订单约束(要求#2)。

    您的另一个选择是进行批处理。在任何给定的时间点,消费者都会排出队列中的所有可用消息并立即批量处理它们。这意味着您必须执行同步消息使用(Consumer#receive()),而不是使用onMessage进行异步消费。

答案 1 :(得分:1)

@Mesocyclone:基于上述Moe提供的问题和解决方案的输入,我可以推荐您正在寻找的可能解决方案。

您可以在网关应用程序内部为每个目标引入一个队列。示例dest1queue,dest2queue等,只有一个输入队列暴露给接收消息。您可以让一个MDB线程侦听部署在不同服务器上的每个内部队列。 对于例如dest1queue由server1上的MDB(单线程)监听,dest2queue由server2上的MDB(单线程)监听,dest3queue由server3上的MDB(单线程)监听...

所以基本上流程是: -

  

在网关应用程序之外公开的单输入队列 - >消息由MDB的1个或多个实例接收,其唯一目的是将传入消息路由到内部队列 - >内部队列(每个目标一个)仅由1个MDB线程监听(因为您不需要一个目标的并行性),它处理消息并与目标进行通信。

以上设计的好处是: -

  1. 您可以让MDB线程在不同服务器上侦听每个内部队列,以便每个MDB线程获得最长的处理时间。
  2. 在任何时候,您都可以更改侦听一个目的地的线程数,而不会影响其他目的地。
  3. 但是,上述设计要求您为每个内部队列备份MDB服务器以避免SPOF。可能是您部署应用程序的服务器提供某种故障转移功能。