Skip to content

性能调优

性能优化没有万能药。消息的大小和数量、应用方法是否包含阻塞操作以及外部因素(如网络速度)都会影响性能。本节概述了可用的配置选项。

线程池配置

在消息传递应用中,消息通过频道(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 等全功能代理,这样不同服务器实例上的客户端才能互相通信。

Based on Spring Framework.