【问题标题】:JMS AlternativeJMS 替代方案
【发布时间】:2011-06-24 13:24:02
【问题描述】:

我正在阅读一篇博客,其中一点是在 JMS 的上下文中“如果您使用队列,那么您就搞砸了”。

我在想,我们还需要 JMS 吗?一个简单的替代方案是,如果您需要异步执行某些操作,为什么不将作业请求放在某个表中,并让一些进程每隔 X 时间单位轮询数据库以寻找新作业?

这种方法比 JMS 更简单,易于理解,并且基本上消除了应用程序的依赖关系。

如果我使用我描述的替代方案,我会失去什么?也许人们失去了使用 JMX 来管理事物的可能性,但是如果您的工作“队列”是从表中获取的,那么您可以编写一些简单的代码来“管理”处理。

【问题讨论】:

  • 这种方法听起来并不比 JMS 简单。
  • @kaleb,嗯,也许吧。将 JMS 方法的所有部分与替代方法并排放置可能是值得的......
  • 某处的表与 JMS 一样是依赖项

标签: java jakarta-ee jms


【解决方案1】:

我正在阅读一篇博客,其中一个 要点是'如果你使用队列, 在 JMS 的上下文中,你搞砸了。

这是完全错误的。

在不合适的情况下选择使用队列可能会搞砸,但如果是 JMS,则是一个不错的选择。

如果我是你,我会对我在互联网上阅读的内容更加挑剔。在我看来,作者喜欢发表煽动性的言论来为他的博客增添趣味并提升他的谷歌分析统计数据。这是一个人的意见,仅此而已。

在我看来,轮询解决方案更复杂,浪费 CPU 周期,而且不是实时的。

如果您想要异步处理,可以使用 Executor 或 FutureTask。如果您只需要异步,那么这些将是队列的合理替代方案。

【讨论】:

  • @duffymo,我只是在考虑替代方案。我还没有接受单行声明作为设计系统时使用的新范式。我看不出轮询解决方案如何更复杂。它是一个 sql 查找。它可能比所有 jms 机器浪费更少的 cpu 周期。
  • 如果您整天每 5 分钟轮询一次,但没有任何可显示的内容,那么如果 JMS 机器仅在消息进入队列时才开始工作,怎么能浪费更少的 CPU 周期呢?听起来您正在寻找一个轮询而不是使用 JMS 的借口。请继续这样做。
  • @duffymo,一点也不。我只是想通过这种方法的所有优点/缺点来思考。我认为您的第一个想法是“这是一个愚蠢的想法”,然后从那里开始就只想对辨别力和找借口发表讽刺言论。相信我,当作者说“如果你使用队列你搞砸了”时,我的第一反应是“whaaaaaaaat?” -- 然后我想给这个想法一个机会。
  • 指出这听起来像是在为投票找借口并不是讽刺。
  • 我没有忽略这个问题——我给出了答案。你过于关注你认为是轻视的东西。老实说,我不在乎你的动机或你的所作所为。我只是不同意 JMS 没用。就这样。放手吧。
【解决方案2】:

我真的很想知道你在哪里读到的。 JMS 是一种经过验证的技术,但与所有解决方案一样,您也可以滥用它。如果需要调度任务,可以使用众多任务调度库之一。 这是一个概述:http://java-source.net/open-source/job-schedulers

【讨论】:

  • Ted 试图在任何消费者/生产者问题上强加 JMS 肯定是有道理的。如果您需要做的只是安排任务,那么您确实不需要 JMS。但说“队列是邪恶的”只是挑衅。
  • @jocen,是的,在这篇文章中,他不太善于分析 'teddziuba.com/2010/12/…' 搜索队列(错误语言警报)
【解决方案3】:

对于仅异步处理的非常简单的要求,您可以使用 java.util.concurrent 包中的任何合适的类。

如果您需要事务或保证作业必须在提交后成功完成,即使在系统故障(软件甚至硬件崩溃)的情况下,或者您希望将作业处理卸载到另一个进程,您需要一些其他解决方案。

JMS 方法可以以相对较少的工作量提供非常复杂的解决方案。

Messaging(或JMS)是一种非常标准的集成解决方案,可以解决作业提交异步和任务提交与实际处理脱钩的问题。通过增加侦听作业队列的“作业处理器”线程的数量,可以轻松扩展基于消息的解决方案。流量将自动进行负载平衡。消息系统还可以提供事务支持,即如果作业处理失败,则自动将消息放回队列,以便重试。

许多企业集成模式都基于消息系统(面向消息的中间件)。这本关于Enterprise Integration Patterns by Gregor Hohpe 的书介绍了如何在应用程序中使用消息传递的最流行模式。

数据库方法需要另一个进程

1) 轮询表中的“新作业”,在处理应用程序开始处理作业时更新行的状态,并最终将作业的行状态更新为“完成”(或从桌子)。 2)如果在作业处理过程中出现问题,应将作业状态更改回表上的“新”,以便“轮询”机制可以重新拾取作业。此外,需要在系统启动时编写一些“恢复线程”,以找出可能处于不一致状态的作业并将它们重新置于“新”状态以再次开始处理。

底线是,构建基于数据库的集成解决方案需要付出很多努力。它还将“作业提交者”和“作业处理器”应用程序与打破数据库封装的数据库模式紧密结合。如果您的“作业处理器”有多个线程(如果您想扩展,您可能需要这些线程),那么您需要确保只有一个线程接手工作并更新“那个”行。

JMS 解决方案可以非常轻松地解决这个问题,而无需手动编写所有这些逻辑。

当然,如果您使用队列,您不会搞砸。但是您应该有一些有效的用例来引入消息传递中间件。

【讨论】:

    【解决方案4】:

    这种方法比 JMS 更简单,易于理解,并且基本上消除了应用程序的依赖关系。

    嗯,只有当您来自数据库背景时,这才是正确的。我认为没有什么比为每个状态更改发送消息并“忘记它”更容易的了。

    面向消息的中间件(例如 JMS)的一个优势是更高的性能 - 您可以拥有 100 万条消息/秒的速率 - 但更大的优势通常是更简洁的架构:插入多个组件的消息总线。现在您可以进行一对一的通信,但在 2 年内您可能想要记录该流量,在 3 年后您可能想要监控错误,在 4 年后您可能想要自动记录、回放和测试它。 .

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 2012-10-05
      • 2010-09-10
      • 2012-12-05
      • 2013-11-22
      • 2020-11-23
      • 2013-08-07
      相关资源
      最近更新 更多