1. 事务完成

使用 Apache ActiveMQ Artemis 提交或回滚事务时,提交或回滚的请求将发送到服务器,并且该调用将阻塞在客户端,直到从服务器收到关于提交或回滚已执行的响应。

当服务器收到提交或回滚时,它将被提交到日志,并且根据参数 journal-sync-transactional 的值,服务器将确保提交或回滚在将响应发送回客户端之前持久存储到存储中。如果此参数的值为 false,则提交或回滚可能不会真正持久存储到存储中,直到在将响应发送回客户端后的某个时间。如果服务器发生故障,这可能意味着提交或回滚永远不会持久存储到存储中。此参数的默认值为 true,因此客户端可以确保所有事务提交或回滚在提交或回滚调用返回时已持久存储到存储中。

将此参数设置为 false 可以提高性能,但会牺牲一些事务持久性。

此参数在 broker.xml 中设置。

2. 非事务性消息发送

如果您使用非事务性会话将消息发送到服务器,则可以配置 Apache ActiveMQ Artemis 以阻塞发送调用,直到消息肯定到达服务器,并且响应已发送回客户端。这可以针对持久消息和非持久消息分别进行配置,并且由以下两个 URL 参数决定

blockOnDurableSend

如果将其设置为 true,则所有针对非事务性会话上的持久消息的发送调用将阻塞,直到消息到达服务器,并且响应已发送回。默认值为 true

blockOnNonDurableSend

如果将其设置为 true,则所有针对非事务性会话上的非持久消息的发送调用将阻塞,直到消息到达服务器,并且响应已发送回。默认值为 false

将发送阻塞设置为 true 会降低性能,因为每次发送都需要网络往返才能执行下一个发送。这意味着发送消息的性能将受到网络的网络往返时间 (RTT) 的限制,而不是网络的带宽。为了获得更好的性能,我们建议您将许多消息发送一起批处理到事务中,因为使用事务性会话,只有提交/回滚会阻塞,而不是每次发送都会阻塞,或者使用 Apache ActiveMQ Artemis 的高级异步发送确认功能,如异步发送确认中所述。

当服务器收到从非事务性会话发送的消息时,如果该消息是持久消息,并且该消息被路由到至少一个持久队列,则服务器将该消息持久存储到永久存储中。如果日志参数 journal-sync-non-transactional 设置为 true,则服务器将不会在消息被持久存储并服务器保证数据已持久存储到磁盘之前将响应发送回客户端。此参数的默认值为 true

3. 非事务性确认

如果您使用非事务性会话在客户端侧确认消息传递,则可以配置 Apache ActiveMQ Artemis 以阻塞确认调用,直到确认肯定到达服务器,并且响应已发送回客户端。这由参数 BlockOnAcknowledge 配置。如果将其设置为 true,则所有针对非事务性会话的确认调用将阻塞,直到确认到达服务器,并且响应已发送回。如果您想实施严格的最多一次传递策略,则可能希望将其设置为 true。默认值为 false

4. 异步发送确认

如果您使用非事务性会话,但希望保证发送到服务器的每条消息都已到达服务器,那么,正如非事务性消息发送保证中所述,您可以配置 Apache ActiveMQ Artemis 以阻塞发送调用,直到服务器收到消息、将其持久存储并发送回响应。这工作得很好,但性能损失很大 - 每次发送调用都需要阻塞至少网络往返时间 (RTT) - 因此发送的性能受到网络延迟的限制,而不是网络带宽的限制。

让我们做一些简单的数学运算来看看这个问题有多严重。我们将考虑一个标准的 1Gib 以太网网络,服务器和客户端之间的网络往返时间为 0.25 毫秒。

在 RTT 为 0.25 毫秒的情况下,如果客户端阻塞在每次消息发送上,则客户端每秒最多可以发送 1000 / 0.25 = 4000 条消息。

如果每条消息小于 1500 字节,并且网络使用标准的 1500 字节 MTU(最大传输单元)大小,那么 1GiB 网络在理论上每秒有 (1024 * 1024 * 1024 / 8) / 1500 = 89478 条消息的上限,如果消息是发送而不阻塞的!这些数字并不完全是科学,但您可以清楚地看到,受到网络 RTT 的限制会对性能产生严重影响。

为了解决这个问题,Apache ActiveMQ Artemis 提供了一种称为异步发送确认的先进新功能。使用此功能,可以配置 Apache ActiveMQ Artemis 在一个方向上不阻塞地发送消息,并在单独的流中异步从服务器获取消息已接收的确认。通过将发送与发送确认解耦,系统不再受到网络 RTT 的限制,而是受到网络带宽的限制。因此,可以实现比使用阻塞方法所能实现的更高的吞吐量,同时还可以绝对保证消息已成功到达服务器。

发送确认的窗口大小由连接工厂或客户端会话工厂上的确认窗口大小参数确定。有关此方面的更多信息,请参阅客户端故障转移中的客户端故障转移。

要使用核心 API 使用该功能,您需要实现接口 org.apache.activemq.artemis.api.core.client.SendAcknowledgementHandler 并在您的 ClientSession 上设置处理程序实例。

然后,您只需使用您的 ClientSession 按正常方式发送消息,当消息到达服务器时,服务器将异步发送回发送确认,一段时间后,Apache ActiveMQ Artemis 通过调用您的处理程序的 sendAcknowledged(ClientMessage message) 方法来通知您,并传递发送的已发送消息的引用。

要启用异步发送确认,您必须确保 confirmationWindowSize 设置为正整数,例如 10MiB。

有关完整的示例,请参阅示例章节中的示例。