在本节中将会讨论影响性能的流控制行为(请参见客户端运行时环境配置)。这些行为可配置为连接工厂受管理对象的属性。有关设置连接工厂属性的信息,请参见第 8 章,管理受管理对象。
客户端收发的消息(有效负荷消息)以及 Message Queue 控制消息通过同一客户端-代理连接传递。如果控制消息(例如代理确认)被有效负荷消息的传送阻挡,则控制消息的传送会发生延迟。为防止此类拥塞,Message Queue 会度量通过连接进行的有效负荷消息流。
有效负荷消息是成批的(由连接工厂属性 imqConnectionFlowCount 指定),以便只传送数目设定的一组消息。传送完一批后,将暂停有效负荷消息的传送,而只传送暂挂的控制消息。当另一批有效负荷消息传送后,接着又传送暂挂的控制消息,如此循环往复。
如果客户端执行的是需要代理作出大量响应的操作,则 imqConnectionFlowCount 应保持较低的值:例如,当客户端使用的是 CLIENT_ACKNOWLEDGE 或 AUTO_ACKNOWLEDGE 模式、持久性消息、事务或队列浏览器,或者正在添加或删除使用方时。从另一方面来说,如果客户端仅在使用 DUPS_OK_ACKNOWLEDGE 模式的连接上有简单的使用方,则可以增大 imqConnectionFlowCount 而不会降低性能。
在遇到本地资源(例如内存)限制之前,存在 Message Queue 客户端运行时环境可以处理的有效负荷消息数限制。如果达到了此限制,性能将受影响。因此,Message Queue 允许您限制每个使用方(或每个连接)能够通过连接传送和能够在客户端运行时环境中缓冲以等待使用的消息数。
当传送到客户端运行时环境的有效负荷消息数超过任意使用方的 imqConsumerFlowLimit 值时,将停止传送该使用方的消息。仅当该使用方的未使用消息数下降至低于 imqConsumerFlowThreshold 设置的值时才会恢复消息传送。
下例说明了如何使用这些限制,以主题使用方的默认设置为例:
imqConsumerFlowLimit=1000 imqConsumerFlowThreshold=50
创建使用方后,代理将向此使用方传送第一批 1000 条消息(前提是有这么多),中间不会暂停。发送 1000 条消息后,代理将停止传送,除非客户端运行时环境要求更多消息。客户端运行将保存这些消息,直到应用程序处理它们为止。在要求代理发送下一批消息之前,客户端运行时环境会允许应用程序使用至少 50% (imqConsumerFlowThreshold) 的消息缓冲区容量(即 500 条消息)。
在同等情况下,如果阈值为 10%,则客户端运行时环境会等待应用程序使用至少 900 条消息,然后才会要求发送下一批消息。
下一批消息的大小按如下计算:
imqConsumerFlowLimit - (缓冲区中当前暂挂的消息数)
因此,如果 imqConsumerFlowThreshold 为 50%,则下一批的大小会在 500 和 1000 之间波动,这取决于应用程序处理消息的速度。
如果 imqConsumerFlowThreshold 设置得过高(接近 100%),代理就会发送较小的分批消息,这样会降低消息的吞吐量。如果该值设置过低(接近 0%),则客户端可以在代理传送下一组消息之前处理完剩余的缓冲消息,从而再次导致消息吞吐量下降。通常,除非您有特别的性能或可靠性考虑,否则不需要更改 imqConsumerFlowThreshold 属性的默认值。
基于使用方的流控制(特别是 imqConsumerFlowLimit)是管理客户端运行时环境中的内存的最好方法。通常,根据客户端应用程序的不同,您应该知道在任意连接上需要支持的使用方数、消息的大小以及可用于客户端运行时环境的内存总量。
但是在某些客户端应用程序中,使用方数量可能是不确定的,这取决于最终用户所作的选择。在这些情况下,您仍可以使用连接级流限制来管理内存。
连接级流控制可以限制针对一个连接上的所有使用方而缓冲的消息总数。如果该数目超过了 imqConnectionFlowLimit 的值,则通过该连接进行的消息传送将停止,直到消息总数降到连接限制以下为止。(只有当 imqConnectionFlowLimitEnabled 设置为 true 时,imqConnectionFlowLimit 属性才会启用。)
在会话中排队的消息数是使用该会话的消息使用方数量以及每个使用方的消息负载的函数。如果客户端在生成或使用消息时表现出延迟,您通常可以通过下列操作来提高性能:重新设计应用程序,以便在更大数量的会话之间分布消息生成方和使用方,或者在更大数量的连接之间分布会话。