性能调优
性能优化没有万能药。消息的大小和数量、应用方法是否包含阻塞操作以及外部因素(如网络速度)都会影响性能。本节概述了可用的配置选项。
线程池配置
在消息传递应用中,消息通过频道(Channels)进行异步执行,其底层由线程池支持。
主要的调优对象是 clientInboundChannel(处理客户端来的请求)和 clientOutboundChannel(向客户端推送消息)。默认情况下,它们的线程数配置为可用处理器数量的两倍。
- 入站频道 (
clientInboundChannel):- CPU 密集型: 如果 Controller 逻辑主要是 CPU 运算,线程数应接近核心数。
- IO 密集型: 如果需要等待数据库或第三方 API,应增加线程池大小。
- 出站频道 (
clientOutboundChannel):- 快速网络: 线程数应接近核心数。
- 慢速/低带宽网路: 客户端消费消息慢,会长时间占用线程,此时必须增加线程池大小。
TIP
ThreadPoolExecutor 的核心池大小、最大池大小和队列容量是关键。如果队列容量使用默认的 Integer.MAX_VALUE,那么线程数永远不会超过核心池大小,因为任务会一直在队列中排队。
发送限制
由于无法控制外部网络环境,Spring 提供了两个属性来防止慢客户端拖垮服务器:
sendTimeLimit: 允许单次发送消息的最大耗时(默认 10 秒)。sendBufferSizeLimit: 每个客户端会话允许累积的最大消息缓冲区大小(默认 512KB)。
java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024);
}
}kotlin
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024)
}
}STOMP 消息大小限制
你可以控制接收的最大 STOMP 消息大小。对于超过 16K 的大消息,STOMP 客户端通常会将其拆分,而 Spring 会负责缓冲和重新组装。
java
registration.setMessageSizeLimit(128 * 1024); // 限制为 128KB补充教学
1. 慢客户端 (Slow Clients) 的危害
如果一个粉丝千万的博主发消息,服务器要给几万个低速移动网络的用户推送。如果没有 sendBufferSizeLimit,服务器内存会被这些还没发出去的消息撑爆。配置该限制后,Spring 会主动断开那些处理太慢的连接以保护全局稳定性。
2. 线程池溢出的监控
如果 clientInboundChannel 的任务队列经常排队,说明你的业务逻辑处理太慢。考虑引入 Redis 队列做真正的异步化,或者横向扩展服务器节点。
3. 集群扩展 (Scaling Out)
简单代理(Simple Broker)不支持多机扩展。在需要扩展时,必须切换到 RabbitMQ 等全功能代理,这样不同服务器实例上的客户端才能互相通信。