我正在寻找 JMS 是良好解决方案的问题的(简单)示例,以及 JMS 在这些情况下是良好解决方案的原因。过去,当消息不一定能立即被 B 处理时,我只是使用数据库作为将消息从 A 传递到 B 的一种手段。

此类系统的一个假设示例是,应在注册后 24 小时内向所有新注册用户发送欢迎电子邮件。为了便于论证,假设数据库不记录每个用户注册的时间,而是将每个新用户的引用(外键)存储在pending_email 表中。电子邮件发送器作业每 24 小时运行一次,向该表中的所有用户发送一封电子邮件,然后删除所有挂起的电子邮件记录。

这似乎是应该使用 JMS 来解决的问题,但我不清楚 JMS 相对于我所描述的方法有什么好处。DB 方法的优点之一是消息是持久的。我知道JMS消息队列也可以持久化,但在这种情况下,JMS和我描述的“数据库作为消息队列”方法之间似乎没有什么区别?

我缺少什么?- 大学教师

有帮助吗?

解决方案

JMS 和消息传递实际上是两个完全不同的事情。

  • 发布和订阅(向尽可能多的感兴趣的消费者发送消息 - 有点像向邮件列表发送电子邮件,发件人不需要知道谁订阅了
  • 高性能可靠的负载平衡(消息队列)

查看更多信息 队列与主题的比较

您所说的情况是第二种情况,是的,您可以使用数据库表来模拟消息队列。

主要区别是JMS消息队列是一个高性能高并发负载均衡器,专为大吞吐量而设计;您通常可以每秒向许多进程和线程中的许多并发消费者发送数万条消息。原因是消息队列基本上是高度异步的 - 好的 JMS 提供者会提前将消息传输给每个消费者 这样,一旦消费者可用,RAM 中就有数千条消息可供处理。这会带来巨大的吞吐量和非常低的延迟。

例如想象一下使用数据库表编写一个 Web 负载均衡器:)

使用数据库表时,通常一个线程往往会锁定整个表,因此在尝试实现高性能负载均衡器时往往会获得非常低的吞吐量。

但与大多数中间件一样,这一切都取决于您的需求;如果您的系统吞吐量较低,每秒只有几条消息,请随意使用数据库表作为队列。但如果您需要低延迟和高吞吐量 - 那么强烈建议使用 JMS 队列。

其他提示

在我看来,JMS 和其他基于消息的系统旨在解决需要以下的问题:

  • 异步 通讯:一个应用程序需要通知另一个应用程序发生了事件,而无需等待响应。
  • 可靠性. 。确保消息传递一次且仅一次。使用数据库方法,您必须“重新发明轮子”,特别是当您有多个客户端读取消息时。
  • 松耦合. 。并非所有系统都可以使用数据库进行通信。因此,JMS 非常适合在具有可以跨系统边界通信的解耦系统的异构环境中使用。

JMS实现是“推送”,因为您不必轮询队列以发现新消息,但是您注册了一个新消息到达后立即调用的回调。

解决原始评论。最初描述的是(点对点)JMS的要点。然而,JMS的好处是:

  1. 您不需要自己编写代码(并且可能搞砸了逻辑,因此它不像您认为的那样持久)。此外,第三方impl可能比简单的数据库方法更具可扩展性。

  2. jms处理发布/订阅,这比您给出的点对点示例稍微复杂一些

  3. 您不依赖于特定的实现,并且如果您的需求在将来发生变化,可以将其交换出来,而不会使用您的Java代码搞乱。

JMS的一个优点是启用异步处理,这也可以通过数据库解决方案完成。但是,以下是JMS相对于数据库解决方案的其他一些好处

a)消息的消费者可以在远程位置。公开数据库以进行远程访问是危险的。您可以通过提供用于从数据库读取消息的附加服务来解决此问题,这需要更多的努力。

b)在数据库的情况下,消息使用者必须在数据库中轮询消息,其中当消息到达时JMS提供回调(如sk所述)

c)负载平衡 - 如果有大量消息出现,很容易在JMS中拥有消息处理器池。

d)通常,通过JMS实现将比数据库路由更简单,更省力。

JMS是一种用于在两个或多个客户端之间传输消息的API。它的规格是在JSR 914下定义的。

  

JMS的主要优点是通信实体的解耦性质 - 发件人不需要有关接收器的信息。其他优势包括集成异构平台,减少系统瓶颈,提高可扩展性以及更快响应的能力。

JMS只是一种接口/ API,必须实现具体的类。这些已经由各种组织/提供商实施。他们被称为JMS提供商。示例是IBM的 WebSphere FioranoMQ 或Apache,HornetQ,OpenMQ等的ActiveMQ。使用的其他术语是管理对象(主题,队列,ConnectionFactories),JMS生产者/发布者,JMS客户端和消息本身。

所以提出你的问题 - JMS的优点是什么? 我想举一个实际的例子来说明它的重要性。

日间交易

此功能名为 LVC (最后值缓存)

交易中股票价格由出版商定期公布。每个共享都有一个与之关联的主题,并将其发布到该主题。现在,如果您知道主题是什么,那么您必须知道消息不会像队列一样保存。消息在发布时发布给订阅者(Exception是Durables订阅者,它获取从创建时发布的所有消息但是我们再次不希望得到太旧的股票价格,这会丢弃可能性使用它)。因此,如果客户想知道股票价格他创建订户,然后他必须等到下一个股票价格发布(这也不是我们想要的)。这是LVC进入画面的地方。每个LVC消息都有一个关联的密钥。如果使用LVC密钥(对于特定库存)发送消息,然后使用相同密钥发送另一个更新消息,则后者将覆盖前一个消息。当订户订阅主题(启用了LVC)时,订户将获得具有不同LVC密钥的所有消息。如果我们为每个上市公司保留一个独特的密钥,那么当客户订阅它时,它将获得最新的股票价格,并最终获得所有更新。

当然,这是使JMS如此强大的可靠性,安全性等因素之一。

Guido有完整的定义。根据我的经验,所有这些都非常适合。

我见过的其中一个用途是在仓库中进行订单分发。想象一下,办公用品公司拥有相当数量的仓库,为大型办公室提供办公用品。这些订单将进入一个中心位置,然后分批进行正确的仓库分发。在大多数情况下,仓库没有或想要高速连接,因此通过拨号调制解调器将订单推送给他们,这就是异步进入的地方。电话线也不是那么重要,因此订单的一半可能会进入和这是可靠性很重要的地方。

关键优势是解除不相关的系统,而不是让它们共享comon数据库或构建自定义服务来传递数据。

银行是一个敏锐的例子,其中使用日内消息来传递实时数据更改。源系统很容易“在墙上”抛出消息;缺点是这些系统之间的合同方式很少,而且您通常会看到在消费者方面实施住院治疗。它几乎太松散了。

其他优势还包括对许多应用程序服务器等开箱即用的JMS支持以及所有相关工具:持久性,监控,报告和限制。

“数据库作为消息队列”解决方案对于任务来说可能很重要。 JMS解决方案的耦合程度较低,因为消息发送方不需要了解有关接收方的任何信息。这可以通过“数据库中的消息队列”中的一些额外抽象来实现,因此它不是一个巨大的胜利...此外,您可以以“发布和订阅”的方式使用队列,这可以方便,具体取决于什么你想要完成。它也是进一步分离组件的好方法。如果您的所有通信都在一个系统中和/或具有应用程序可立即使用的日志非常重要,那么您的方法似乎很好。如果您在不同的系统之间进行通信,JMS是一个不错的选择。

JMS结合JTA(Java Transaction API)和JPA(Java持久性API)非常有用。使用简单的注释,您可以在同一事务中放置多个数据库操作+消息发送/接收。因此,如果其中一个失败,则使用相同的事务机制回滚所有内容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top