性能
性能方面没有万能的解决方案。许多因素都会影响性能,包括消息的大小和数量、应用程序方法是否执行需要阻塞的工作以及外部因素(例如网络速度和其他问题)。本节的目的是概述可用的配置选项,并提供一些关于如何考虑扩展的思路。
在消息应用程序中,消息通过通道传递以进行异步执行,这些异步执行由线程池支持。配置此类应用程序需要充分了解通道和消息流。因此,建议查看消息流。
首先要配置支持clientInboundChannel
和clientOutboundChannel
的线程池。默认情况下,两者都配置为可用处理器数量的两倍。
如果注释方法中的消息处理主要受CPU限制,则clientInboundChannel
的线程数量应保持接近处理器数量。如果它们所做的工作更多的是IO绑定,并且需要阻塞或等待数据库或其他外部系统,则可能需要增加线程池大小。
一个常见的误解是,配置核心池大小(例如,10)和最大池大小(例如,20)会导致一个具有10到20个线程的线程池。实际上,如果容量保留其默认值Integer.MAX_VALUE,则线程池永远不会超过核心池大小,因为所有其他任务都会排队。 请参阅 |
在clientOutboundChannel
方面,它完全是关于向WebSocket客户端发送消息。如果客户端位于快速网络上,则线程数量应保持接近可用处理器数量。如果它们速度慢或带宽低,则它们需要更长时间来使用消息并给线程池带来负担。因此,需要增加线程池大小。
虽然可以预测clientInboundChannel
的工作负载——毕竟,它是基于应用程序的工作——但如何配置“clientOutboundChannel”则比较困难,因为它基于应用程序无法控制的因素。因此,另外两个属性与消息的发送有关:sendTimeLimit
和sendBufferSizeLimit
。您可以使用这些方法配置发送允许花费多长时间以及在向客户端发送消息时可以缓冲多少数据。
总体思路是,在任何给定时间,只能使用单个线程向客户端发送消息。同时,所有其他消息都会被缓冲,您可以使用这些属性来决定发送消息允许花费多长时间以及在此期间可以缓冲多少数据。请参阅javadoc和XML模式文档以获取重要的其他详细信息。
以下示例显示了可能的配置
-
Java
-
Kotlin
-
Xml
@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-js/stompjs
之类的STOMP客户端会将较大的STOMP消息拆分为16K边界,并将其作为多个WebSocket消息发送,这需要服务器进行缓冲和重新组装。
Spring的STOMP-over-WebSocket支持会执行此操作,因此应用程序可以配置STOMP消息的最大大小,而与WebSocket服务器特定的消息大小无关。请记住,如果需要,WebSocket消息大小会自动调整,以确保它们至少可以携带16K的WebSocket消息。
以下示例显示了一种可能的配置
-
Java
-
Kotlin
-
Xml
@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客户端。