2013-02-04 106 views
0

我有一个正在读消息掀起了JMS持久主题的独立的Java程序并将其提交到线程池进行处理时JVM崩溃的处理。我这样做是出于明显的并发原因,但保持处理这些消息的顺序,我仍然将它们提交给单个线程池。现在,这里是我的关于JVM崩溃的担忧..使用线程池和JMS

├28类事务
我不读,因为它会减慢我的过程中处理事务上下文,我都刻意回避的消息。所以,我正在积累消息在线程池的阻塞队列中。但是如果JVM在线程池中等待处理10条消息时崩溃,我将丢失该数据。

- 交易
我相信,如果我在事务中读取并处理每条消息,如果出现问题,那么消息将在备份时重新传递给进程。

既然是很多人在低延迟系统工作的一个共同的问题,不知道人们如何经验丰富的解决这个问题?谢谢。

+0

我相信JMS模型是每个线程有一个队列订阅者,当它完成处理时,它会提交每条消息。 –

+0

这里的实际问题是什么?是“我应该使用交易还是非交易?” –

+0

是的,我应该使用交易还是非交易?但是与此同时,如果不想使用事务处理,那么有哪些流行的技术可以安全地从任何崩溃中恢复。 – endless

回答

1

彼得据我所知是正确的。解决这个问题的一种方法是,如果该模式适用于您,则使用某种划分来创建不同的队列来将消息分组到不同的队列中。也就是说,这个要求经常发生故障的意思大概是“大家为一个人帐户的邮件必须按顺序进行处理”。所以,如果你有一些与此类似,您可以创建:

  • 一个题目,让每个使用专用的选择(或子课题模式)
  • 多个主题与每一个具有单一用户多个用户。

您的发布商必须确定:

  • 上所发布的消息使校正选择器实现对用户的头部,或
  • 正确的子课题将发布,或
  • 要发布的正确主题

一个易于维护的模式是使用您的业务领域之一(对于前者充足,帐号),并计算一个mod(x)就可以了,其中x是你想分享工作量的用户数量。希望您的业务重点是数字,会给你一个体面的分布,但你总是可以使用一些其他的确定性算法通过反转密钥和/或散列其非数值产生这个号码。另外,您的轮廓还有更多的点到点/ JMS队列的感觉,而不是Pub-Sub/JMS主题之一。你确定要使用主题吗?

如果你绝对不能丢失数据,那么你应该使用事务性消息。如果您使用事务性消息,那么您无法委派给线程池。 JMS消息的事务上下文(这是会话)绑定到接收消息的线程,因此除非启用某个“有趣的业务”将此上下文转移到另一个线程.....

我甚至不知道如何完成这句话。

==== ====更新

现在我想想,如果你可以从并行消息的处理,你可以检索邮件的批次,休闲于一体的交易中获益,并将它们全部委托给一个ExecutorService.invokeAll调用,等待完成并在全部完成时提交事务。如果invokeAll超时,或其中一个任务引发异常,那么您将不得不回滚事务或进行某种补偿操作。

+0

谢谢尼古拉斯,这提供了很多见解。关于队列Vs主题,我没有选择,所以使用主题。它是一个交易客户端,所有相关的消息都是针对一个订单的,所以我不能有多个主题来分流。假设我只有一个主题需要忍受,为了避免数据丢失,看起来像我必须坚持一个线程模式,我猜这会减少通过投入?当我将消息处理移动到另一个线程(如线程池)时,我的事务上下文就消失了。这是正确的理解吗?谢谢。 – endless

+0

你明白了。 JMS中的Transactional Pub/Sub在大多数(所有?)JMS实现中都是最慢的消费者。只有相同,但**耐用**速度较慢。交易吞吐量的最佳选择是检索批量消息,处理它们,然后提交事务。 – Nicholas