此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

性能

在性能方面没有灵丹妙药。许多因素 影响它,包括消息的大小和数量,是否应用程序 方法执行需要阻塞的工作,以及外部因素 (例如网络速度和其他问题)。本节的目标是提供 可用配置选项的概述以及一些想法 关于如何推理缩放。spring-doc.cadn.net.cn

在消息传递应用程序中,消息通过异步通道传递 由线程池支持的执行。配置此类应用程序需要 对渠道和消息流有很好的了解。因此,它是 建议查看消息流spring-doc.cadn.net.cn

显而易见的起点是配置支持clientInboundChannelclientOutboundChannel.默认情况下,两个 配置为可用处理器数量的两倍。spring-doc.cadn.net.cn

如果注释方法中消息的处理主要是受 CPU 限制的,则 线程数clientInboundChannel应保持接近 处理器数。如果他们所做的工作更受 IO 限制并且需要阻塞 或等待数据库或其他外部系统,线程池大小 可能需要增加。spring-doc.cadn.net.cn

ThreadPoolExecutor具有三个重要属性:核心线程池大小, 最大线程池大小,以及队列要存储的容量 没有可用线程的任务。spring-doc.cadn.net.cn

一个常见的混淆点是配置核心池大小(例如,10) 最大池大小(例如,20)将产生具有 10 到 20 个线程的线程池。 事实上,如果容量保留为默认值 Integer.MAX_VALUE, 线程池永远不会增加超过核心池大小,因为 所有其他任务都排队。spring-doc.cadn.net.cn

请参阅ThreadPoolExecutor了解这些属性的工作原理,以及 了解各种排队策略。spring-doc.cadn.net.cn

clientOutboundChannel这方面,都是关于向 WebSocket 发送消息 客户。如果客户端在快速网络上,则线程数应 保持接近可用处理器的数量。如果它们很慢或开启 低带宽,它们需要更长的时间来消耗消息并给 线程池。因此,增加线程池大小变得必要。spring-doc.cadn.net.cn

虽然clientInboundChannel可以预测——毕竟,它是基于应用程序所做的事情——如何配置 “clientOutboundChannel”更难,因为它基于超出 应用程序的控制。因此,另外两个 属性与消息的发送有关:sendTimeLimitsendBufferSizeLimit.您可以使用这些方法来配置 send 允许获取以及发送时可以缓冲多少数据 消息发送给客户端。spring-doc.cadn.net.cn

总体思路是,在任何给定时间,只能使用单个线程 发送给客户端。同时,所有其他消息都会被缓冲,并且您 可以使用这些属性来决定允许发送消息多长时间 获取以及在此期间可以缓冲多少数据。请参阅 javadoc 和 XML 模式的文档,了解重要的其他详细信息。spring-doc.cadn.net.cn

以下示例显示了可能的配置:spring-doc.cadn.net.cn

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	@Override
	public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
		registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024);
	}

	// ...

}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {

	override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
		registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024)
	}

	// ...
}
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:websocket="http://www.springframework.org/schema/websocket"
	   xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/websocket
		https://www.springframework.org/schema/websocket/spring-websocket.xsd">

	<websocket:message-broker>
		<websocket:transport send-timeout="15000" send-buffer-size="524288" />
		<!-- ... -->
	</websocket:message-broker>

</beans>

您还可以使用前面显示的 WebSocket 传输配置来配置 传入 STOMP 消息的最大允许大小。理论上,WebSocket 消息的大小几乎可以无限。在实践中,WebSocket 服务器强加 限制 — 例如,Tomcat 上的 8K 和 Jetty 上的 64K。因此,STOMP 客户端 如stomp-js/stompjs而其他人则分裂得更大 STOMP 消息在 16K 边界上发送,并将它们作为多个 WebSocket 消息发送, 这需要服务器缓冲和重新组装。spring-doc.cadn.net.cn

Spring 的 STOMP-over-WebSocket 支持可以做到这一点,因此应用程序可以配置 STOMP 消息的最大大小,与特定于 WebSocket 服务器的消息无关 大小。请记住,WebSocket 消息大小是自动的 如有必要,请进行调整,以确保它们可以在 最低。spring-doc.cadn.net.cn

以下示例显示了一种可能的配置:spring-doc.cadn.net.cn

@Configuration
@EnableWebSocketMessageBroker
public class MessageSizeLimitWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	@Override
	public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
		registration.setMessageSizeLimit(128 * 1024);
	}

	// ...

}
@Configuration
@EnableWebSocketMessageBroker
class MessageSizeLimitWebSocketConfiguration : WebSocketMessageBrokerConfigurer {

	override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
		registration.setMessageSizeLimit(128 * 1024)
	}

	// ...
}
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:websocket="http://www.springframework.org/schema/websocket"
	   xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/websocket
		https://www.springframework.org/schema/websocket/spring-websocket.xsd">

	<websocket:message-broker>
		<websocket:transport message-size="131072" />
		<!-- ... -->
	</websocket:message-broker>

</beans>

关于扩展的一个重要点涉及使用多个应用程序实例。 目前,您无法使用简单的经纪人来做到这一点。 但是,当您使用功能齐全的代理(例如 RabbitMQ)时,每个应用程序 实例连接到代理,消息从一个应用程序广播 实例可以通过代理广播到连接的 WebSocket 客户端 通过任何其他应用程序实例。spring-doc.cadn.net.cn