此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-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

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

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

虽然clientInboundChannel可以预测 — 毕竟,它基于应用程序的作用 — 如何配置 “clientOutboundChannel” 更难,因为它基于其他因素 应用程序的控制。因此,另外两个 属性与消息的发送有关:sendTimeLimitsendBufferSizeLimit.您可以使用这些方法来配置 send 允许接收以及发送时可以缓冲多少数据 消息。spring-doc.cadn.net.cn

一般的思路是,在任何给定时间,只能使用单个线程 以发送到客户端。同时,所有其他消息都会被缓冲,而您 可以使用这些属性来决定允许发送消息的时间 take 以及在此期间可以缓冲多少数据。请参阅 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 消息,并将其作为多个 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>

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