我正在寻找JMS是一个很好的解决方案的问题的简单例子,也是JMS在这些情况下是一个很好的解决方案的原因.在过去,我只是简单地使用数据库作为将消息从A传递到B的方法,当消息不一定立即被B处理时.
这种系统的一个假设示例是,所有新注册的用户应在注册后24小时内收到欢迎电子邮件.为了便于论证,假设DB不记录每个用户注册的时间,而是将每个新用户的引用(外键)存储在pending_email表中.电子邮件发件人作业每24小时运行一次,向该表中的所有用户发送电子邮件,然后删除所有pending_email记录.
这似乎是应该使用JMS的那种问题,但我不清楚JMS对我所描述的方法有什么好处.DB方法的一个优点是消息是持久的.我知道JMS消息队列也可以保留,但在这种情况下,JMS和我描述的"数据库作为消息队列"方法似乎没什么区别?
我错过了什么? - 唐
JMS和消息传递实际上是两个完全不同的东西.
发布和订阅(向感兴趣的消费者发送消息 - 有点像向邮件列表发送电子邮件,发件人不需要知道谁订阅了
高性能可靠的负载均衡(消息队列)
查看有关队列如何与主题进行比较的更多信息
您正在谈论的情况是第二种情况,是的,您可以使用数据库表来模拟消息队列.
主要区别在于JMS消息队列是一种高性能,高度并发的负载均衡器,专为大吞吐量而设计; 在许多进程和线程中,您通常可以每秒向数个并发消费者发送数万条消息.这样做的原因是消息队列基本上是高度异步的 - 一个好的JMS提供者会提前将消息流传输给每个消费者,这样一旦消费者可用,就有数千条消息可以在RAM中处理.这导致大量的吞吐量和非常低的延迟.
想象一下使用数据库表写一个web负载均衡器:)
使用数据库表时,通常一个线程会锁定整个表,因此在尝试实现高性能负载均衡器时,您往往会获得非常低的吞吐量.
但是像大多数中间件一样,这一切都取决于你需要什么; 如果你的低吞吐量系统每秒只有几条消息 - 可以随意使用数据库表作为队列.但如果您需要低延迟和高吞吐量 - 那么强烈建议使用JMS队列.
在我看来,JMS和其他基于消息的系统旨在解决需要的问题:
异步通信:应用程序需要通知另一个事件已发生而无需等待响应.
可靠性.确保一次只发送一次消息.使用数据库方法,您必须"重新发明轮子",特别是如果您有多个客户端阅读消息.
松耦合.并非所有系统都可以使用数据库进行通信 因此,JMS非常适合在具有可以通过系统边界进行通信的分离系统的异构环境中使用.
JMS实现是"推送",因为您不必轮询队列以发现新消息,但是您注册了一个在新消息到达时立即调用的回调.
解决原始评论.最初描述的是(点对点)JMS的要点.但是,JMS的好处是:
你不需要自己编写代码(并且可能搞砸了逻辑,因此它不像你想象的那样持久).此外,第三方impl可能比简单的数据库方法更具可扩展性.
jms处理发布/订阅,这比您给出的点对点示例稍微复杂一些
你不依赖于具体的实现,如果你的需求在将来发生变化,可以将它交换掉,而不用你的java代码.
JMS的一个优点是启用异步处理,这也可以通过数据库解决方案完成.但是,以下是JMS相对于数据库解决方案的其他一些好处
a)消息的消费者可以在远程位置.公开数据库以进行远程访问是危险的.您可以通过提供用于从数据库读取消息的附加服务来解决此问题,这需要更多工作.
b)在数据库的情况下,消息使用者必须在数据库中轮询消息,其中当消息到达时JMS提供回调(如sk所述)
c)负载平衡 - 如果有大量消息到来,很容易在JMS中拥有消息处理器池.
d)通常,通过JMS实现将比数据库路由更简单,更省力