【问题标题】:WMQ/JMS no lost and duplicated messages principleWMQ/JMS 无丢失和重复消息原理
【发布时间】:2014-04-21 16:06:35
【问题描述】:

如果 JMS 客户端应用程序要求不会丢失任何消息,也不会发送重复消息进行处理,并且每条消息都与其他消息无关(无批处理),那么哪种组合可以满足这些要求: - 持久性+自动确认会话模式(异步消费者) - 持久性+客户端确认会话模式 - 持久性 + 交易会话 - 任何其他? 我已经阅读了有关事务处理会话和确认模式的信息(例如这里的http://docs.oracle.com/javaee/1.4/tutorial/doc/JMS6.html 和这里的http://wso2.com/library/articles/2013/01/jms-message-delivery-reliability-acknowledgement-patterns/),在我看来这三种可能性都是可以接受的。你同意?使用事务性会话或更高级的可靠性概念有什么好处?

提前致谢!

【问题讨论】:

  • 是的,所有这三个组合都可以处理“不丢失消息”(因为所有三个组合都有持久消息)。这三者还应确保消息只写入一次(因此没有重复)。我建议事务会话提供最佳解决方案,因为事务会话可用于包装事务中的其他活动。当然,如果您需要 JMS,那么确认会话更容易处理。

标签: java jms ibm-mq mq


【解决方案1】:

如果您通过网络与任何 JMS 传输提供者通信,请使用事务处理会话并确保应用检测到并妥善处理欺骗消息。为什么?查看 4.4.13 消息的重复生成 部分中的 JMS 1.1 specification,其中指出:

如果在客户端提交其工作期间发生故障 Session和commit方法返回,客户端无法判断是否 事务已提交或回滚。一样的暧昧 当在一个非事务性发送之间发生故障时存在 PERSISTENT 消息和从发送方法返回。

由 JMS 应用程序来处理这种歧义。在一些 在这种情况下,这可能会导致客户端产生功能上的重复 消息。

由于会话恢复而重新传递的消息不是 视为重复消息。

考虑一个通过网络发出COMMIT 的应用程序。如果应用程序收到一个错误,表明连接已断开,它如何知道是在 API 调用到达传输提供商之前还是之后发生的?如果应用程序正在发送消息,唯一安全的做法是假设 COMMIT 失败并重新发送消息。收到消息的东西会再次看到它。

同样,如果应用程序接收到在 COMMIT 上出现错误的消息,那么如果它实际上已回滚,它将再次看到该消息。但是,应用程序不能假定它已回滚并丢弃它刚刚收到的消息,因为这可能会导致消息丢失。

因此,WMQ 或任何其他 JMS 传输提供程序不得提供欺骗,但由于网络引入的模糊性,应用程序可能会收到欺骗。这是假设一个事务会话并且应用程序优雅地处理欺骗的最佳情况。最坏的情况是在事务会话之外,歧义可能导致应用丢弃消息。

【讨论】:

    猜你喜欢
    • 2023-01-31
    • 2012-06-21
    • 2017-01-28
    • 2017-10-23
    • 2021-10-18
    • 2016-06-24
    • 2020-01-14
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多