我认为使用JMS的很多(在我的情况下是Spring)应用程序可能会遵循这个工作流程:
Database A ===> Producer ===> JMS Queue ===> Consumer ===> Database B
然后可靠性是一个问题。让我们说一下Database A
中的数据记录是否应该始终标记为delivered
,当邮件中包含数据记录的时候是真实消耗的,并将数据保存在Database B
中。然后有问题:
据我所知,目前JMS协议没有定义任何从consumer
向producer
发送确认的功能,但仅限于MOM
,因此实际consumer-to-producer
确认方法因JMS提供程序而异。那么这是否意味着没有办法开发一种可以用于通常所有JMS产品(ActiveMQ,WebSphere MQ和Jboss MQ)的确认机制?
考虑停电的情况,然后它是否会使队列中的消息消失,所以需要重新发送?或者不同的JMS产品可以获取剩余的内容,因为消息是序列化的,因此丢失的消息只能由事务管理或异步/同步配置引起,而不是因为应用程序服务器已关闭?
答案 0 :(得分:4)
JMS保证了消息的本质传递,如果消息被发布,那么无论发生什么,它都会传递给消费者,无论发生什么,MOM都是为了确保这一事实而设计的。无论如何,交付没有必要意味着处理。
通过各种机制确保可靠性:
为了确保两个数据源之间的一致性,您必须至少在生产者端使用XA事务(事务数据库A和JMS队列中至少隐含了2个资源),以保证消息不会出现如果数据库A中的提交失败,则发布到队列,如果队列的发布失败,则不会更新数据库。消息消耗也应该进行处理以确保在回滚的情况下重新传递。
事务边界永远不会同时包含使用者和生产者,因为它与消息传递系统的异步性质相冲突,在消费者处理消息之前,您无法锁定生产者端的资源,因为您无法保证何时会发生。
注意:如果您的数据库不支持XA(或提高性能),并且您在事务(数据库和JMS队列)中只隐含了2个资源,那么您可以查看Logging Last Resource Transaction Optimization < / p>
答案 1 :(得分:2)
1)根据我对队列管理器(MQ Series,ActiveMQ和HornetQ)的经验,我从不需要生产者/消费者之间的这种认可。此外,我曾经处理过的环境,流量在几个队列中每天约有50/60万个对象。队列也都坚持了下来。
2)就我而言,在队列管理器上使用持久性机制完全足以处理中断场景。我在MQ Series和HornetQ上使用了磁盘持久性。
但是,有时为了确定消息量,我们开发了一些机制来比较数据库A和数据库B,以确保消息也被消费。我不知道JMS架构是否应该提供这种机制,因为这样的任务可能会降低性能。
在我的观点中,你必须衡量一下你的系统架构,衡量这些信息的重要性,因为它并不容易保存。
问候。
答案 2 :(得分:1)
如果我理解你的问题,这似乎就是JTA / XA事务的情况(只要你的DB / JMS供应商支持它们)。 Spring TX经理可以帮助使tx管理(更多)供应商不可知。
仅供参考,我使用Apache Camel来实现这种类型的流程,它在生产者/消费者中具有相当好的错误处理能力。