JMS 规定了 3 种确认模式
-
AUTO_ACKNOWLEDGE
-
CLIENT_ACKNOWLEDGE
-
DUPS_OK_ACKNOWLEDGE
Apache ActiveMQ Artemis 支持两种额外的模式:PRE_ACKNOWLEDGE
和 INDIVIDUAL_ACKNOWLEDGE
在某些情况下,您可能能够承受在发生故障时丢失消息,因此在将消息传递给客户端之前在服务器上确认消息是有意义的。
此额外模式由 Apache ActiveMQ Artemis 支持,我们将称之为预确认模式。
在服务器上确认消息之前进行确认的缺点是,如果系统在服务器上确认消息之后但在消息传递给客户端之前崩溃,消息将丢失。在这种情况下,消息将丢失,并且在系统重启时不会恢复。
根据您的消息传递情况,preAcknowledgement
模式可以避免额外的网络流量和 CPU 资源,但代价是需要处理消息丢失。
预确认模式的一个用例示例是股票价格更新消息。对于这些消息,在发生崩溃时丢失消息可能是合理的,因为下一个价格更新消息很快就会到达,覆盖之前的价格。
请注意,如果您使用预确认模式,那么您将丢失正在消费的消息的事务语义,因为很明显,它们首先是在服务器上进行确认的,而不是在您提交事务时进行确认的。这可能是一种显而易见的事情,但我们希望在这些问题上保持清晰,以避免混淆! |
1. 使用 PRE_ACKNOWLEDGE
这可以通过将布尔 URL 参数 preAcknowledge
设置为 true
来配置。
或者,在使用 JMS API 时,使用 ActiveMQSession.PRE_ACKNOWLEDGE
常量创建一个 JMS 会话。
// messages will be acknowledge on the server *before* being delivered to the client
Session session = connection.createSession(false, ActiveMQJMSConstants.PRE_ACKNOWLEDGE);
2. 单个确认
单个确认的一个有效用例是,当您需要拥有自己的调度,并且不知道您的消息处理何时完成时。您应该优先使用每个线程工作者一个消费者的模式,但在某些情况下,这可能不可行,具体取决于您的处理流程的复杂程度。为此,您可以使用单个确认。
您基本上通过使用 ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE
确认模式创建会话来设置单个 ACK。单个 ACK 继承了客户端确认的所有语义,唯一的例外是消息是单独进行确认的。
请注意,为了避免在 MDB 处理中造成混淆,单个 ACKNOWLEDGE 不支持通过 MDB(或入站资源适配器)使用。这是因为您必须在 MDB 中完成消息的处理流程。 |