JMS的好处是什么?
我正在寻找(简单的)JMS是一个很好的解决scheme的问题的例子,也是为什么JMS在这些情况下是一个好的解决scheme的原因。 在过去,我只是简单地使用数据库作为将消息从A传递给B的手段,而消息不一定要立即由B处理。
这种系统的一个假设例子是,所有新注册的用户都应在注册后的24小时内收到欢迎电子邮件。 为了说明起见,假设数据库不logging每个用户注册的时间,而是将每个新用户的引用(外键)存储在pending_email表中。 电子邮件发件人作业每24小时运行一次,向该表中的所有用户发送电子邮件,然后删除所有pending_emaillogging。
这似乎是JMS应该使用的那种问题,但是我不清楚JMS对于我所描述的方法有什么好处。 DB方法的一个优点是消息是持久的。 我知道JMS消息队列也可以被持久化,但是在这种情况下,JMS和我所描述的“数据库作为消息队列”方法似乎没什么区别?
我错过了什么? – 唐
JMS和消息传递实际上是两个完全不同的东西。
- 发布和订阅(向有兴趣的消费者发送消息 – 有点像发送邮件到邮件列表,发件人不需要知道谁订阅了
- 高性能可靠的负载均衡(消息队列)
查看有关队列如何与主题进行比较的更多信息
你说的是第二种情况,你可以使用数据库表模拟一个消息队列。
主要区别在于JMS消息队列是为高吞吐量而devise的高性能高并发负载均衡器; 您通常可以将数以万计的消息每秒发送给许多进程和线程中的许多并发使用者。 原因是消息队列基本上是高度asynchronous的 – 一个好的JMS提供者会提前将消息stream传送给每个消费者,这样一旦消费者可用,就有数以千计的消息在RAM中被处理。 这导致了大量的吞吐量和非常低的延迟。
想象一下使用数据库表写一个web负载均衡器:)
在使用数据库表时,通常一个线程往往会locking整个表,因此在尝试实现高性能负载均衡器时,您往往会获得非常低的吞吐量。
但是像大多数中间件一样,这取决于你需要的东西; 如果你的系统吞吐量低,每秒只有几条消息 – 可以随意使用数据库表作为队列。 但是如果您需要低延迟和高吞吐量 – 那么强烈推荐使用JMS队列。
在我看来,JMS和其他基于消息的系统旨在解决需要的问题:
- asynchronous通信:应用程序需要通知另一个事件发生,而不需要等待响应。
- 可靠性 。 确保一次又一次的消息传递。 使用数据库方法,您必须“重新发明轮子”,特别是如果您有多个客户端阅读邮件。
- 松散的耦合 。 并非所有的系统都可以使用数据库进行通 所以JMS非常适合用于具有可以在系统边界上通信的解耦系统的异构环境。
JMS实现是“推送”的,因为您不必轮询队列来发现新消息,而是注册一个新消息到达时被调用的callback。
解决原来的评论。 最初描述的是(点到点)JMS的要点。 JMS的好处是:
-
你不需要自己编写代码(并且可能搞砸逻辑,以至于不像你想象的那样持久)。 另外,第三方impl可能比简单的数据库方法更具可扩展性。
-
jms处理发布/订阅,这比你提供的点对点的例子复杂一点
-
你并没有被绑定到一个特定的实现上,如果你的需求在将来发生变化,你可以把它交换出去,而不用把你的java代码搞乱。
JMS的一个优势是可以通过数据库解决scheme来实现asynchronous处理。 但是,以下是JMS相对于数据库解决scheme的其他一些好处
a)消息的消费者可以在远程位置。 公开数据库进行远程访问是危险的。 您可以通过提供额外的服务来读取来自数据库的消息来解决这个问题,这需要更多的努力。
b)在数据库的情况下,消息使用者必须轮询数据库中的消息,当消息到达时JMS提供callback(如sk所述)
c)负载平衡 – 如果有很多消息传入,那么在JMS中容易拥有消息处理器池。
d)一般来说,通过JMS的实现将比数据库路由更简单,花费更less
Guido有完整的定义。 从我的经验来看,所有这些都是非常重要的。
我见过的其中一个用途是在仓库中进行订单分配。 想象一下,一家办公用品公司拥有相当数量的仓库,为大型办公室提供办公用品。 这些订单将进入一个中央位置,然后被批准正确的仓库分发。 在大多数情况下,仓库没有或者不需要高速连接,所以通过拨号调制解调器将订单推送给它们,这就是asynchronous进入的地方。电话线并不是那么重要,要么有一半的订单可能进入这是可靠性很重要的地方。
关键的优势是将不相关的系统解耦,而不是让它们共享数据库或构build自定义服务来传递数据。
银行是一个敏锐的例子,即时消息被用来传递实时数据变化。 源系统很容易将信息“翻墙”; 不利之处在于这些系统之间的契约方式非常有限,而且您通常会在消费者方面看到实施住院治疗的情况。 这几乎太松散耦合。
其他的优势在于支持许多应用程序服务器等开源的JMS,以及所有的工具:持久性,监控,报告和限制。
这里有一些很好的例子: http : //www.winslam.com/laramee/jms/index.html
JMS是用于在两个或更多客户端之间传输消息的API。 它的规格是根据JSR 914定义的。
The major advantage of JMS is the decoupled nature of communicating entities - Sender need not have information about the receivers.Other advantages include the ability to integrate heterogeneous platforms, reduce system bottlenecks, increase scalability, and respond more quickly to change.
JMS只是一种接口/ API,必须实现具体的类。 这些已经由各种组织/供应商实施。 他们被称为JMS提供者。 例子是IBM的FioranoMQ的FioranoMQ ,Apache的HornetQ,OpenMQ等的ActiveMQ。其他使用的术语是pipe理对象(主题,队列,连接因子),JMS生产者/发布者,JMS客户端和消息本身。
所以来到你的问题 – what is JMS good for?
我想举一个实际的例子来说明它的重要性。
日间交易
这个function叫做LVC (Last value cache)
在交易中股价是由出版商定期发布的。 每个共享都有一个关联的主题,它被发布到。 现在,如果你知道一个主题是什么,那么你必须知道消息不像队列一样保存。 消息在发布消息时被活跃地发布给订阅者(例外的是耐用消费者订阅者,它从创build消息的时候就获得了所有的消息,但是我们又不想得到太旧的股票价格,使用它)。 所以如果一个客户想要知道股票价格,他就创build一个订阅者,然后他必须等到下一个股票价格发布(这又不是我们想要的)。 这是LVC进入图片的地方。 每个LVC消息都有一个关联的密钥。 如果消息是使用LVC密钥(特定股票)发送的,然后是具有相同密钥的另一个更新消息,则后者将覆盖前一个消息。 当用户订阅了一个话题(启用LVC)时,用户将获得具有不同LVC密钥的所有消息。 如果我们为每个上市公司保留一个独特的关键,那么当客户订阅它时,它将得到最新的股票价格,并最终获得所有的更新。
当然这也是使JMS如此强大的可靠性,安全性等因素之一。
“作为消息队列的数据库”解决scheme可能对于任务来说很重。 JMS解决scheme不太紧密,因为消息发送者不需要知道接收者的任何信息。 这可以通过在'数据库作为消息队列'中的一些额外的抽象来完成,所以它不是一个巨大的胜利…另外,你可以使用“发布和订阅”方式的队列,这可以方便地取决于什么你正在努力完成。 这也是进一步分离组件的好方法。 如果你的所有通信都在一个系统内,并且/或者让一个应用程序立即可用的日志非常重要,那么你的方法看起来不错。 如果您在不同系统之间进行通信,则JMS是一个不错的select。
JMS结合JTA(Java事务API)和JPA(Java持久性API)可能非常有用。 通过简单的注释,您可以在同一个事务中放置多个数据库操作+消息发送/接收。 所以如果其中一个失败了,所有的回滚都会使用相同的事务机制。