Spring Boot STOMP/WebSocket适配Jetty 10:解决连接超时问题
解决方案:Spring Boot STOMP WebSocket 在 Jetty 10 中保持长连接(恢复2分钟心跳)
问题核心
Jetty 10 将WebSocket默认空闲超时从5分钟缩短至30秒,而Spring提供的ServletServerContainerFactoryBean仅适配Tomcat,无法配置Jetty的WebSocket会话超时;修改Jetty全局jetty.ssl.idleTimeout、jetty.http.idleTimeout参数无效,因为Spring WebSocket的Jetty适配层会覆盖全局配置,导致原120秒的STOMP心跳无法维持连接,每30秒触发一次断开。
可行方案
方案1:自定义Jetty WebSocket容器配置(推荐)
Spring Boot 2.7.x 对Jetty 10的WebSocket支持需通过JettyWebSocketServletWebServerCustomizer实现会话参数配置,替代Tomcat专用的ServletServerContainerFactoryBean:
- 移除原代码中的
ServletServerContainerFactoryBeanBean - 添加Jetty专属自定义配置类:
@Configuration @RequiredArgsConstructor public class JettyWebSocketCustomizer implements WebServerFactoryCustomizer<JettyServletWebServerFactory> { private static final long WEBSOCKETS_SESSION_TIMEOUT = 120_000; // 2分钟,与心跳间隔匹配 private static final int WEBSOCKETS_BUFFER_MAX_SIZE = 65536; @Override public void customize(JettyServletWebServerFactory factory) { factory.addWebSocketServletInitializer(servletContext -> { WebSocketPolicy policy = WebSocketPolicy.newServerPolicy(); // 配置会话空闲超时,需大于等于心跳间隔 policy.setIdleTimeout(WEBSOCKETS_SESSION_TIMEOUT); policy.setMaxTextMessageBufferSize(WEBSOCKETS_BUFFER_MAX_SIZE); policy.setMaxBinaryMessageBufferSize(WEBSOCKETS_BUFFER_MAX_SIZE); JettyWebSocketServerContainer container = new JettyWebSocketServerContainer(policy); servletContext.setAttribute(JettyWebSocketServerContainer.class.getName(), container); }); } }
- 保持
WebSocketConfig中心跳配置不变:
private static final long[] HEARTBEAT = {120_000, 120_000}; // Broker与客户端心跳间隔均为120秒
方案2:调整STOMP心跳间隔(临时兼容)
若暂时无法修改容器配置,可将心跳间隔设为Jetty空闲超时的一半以内(如25秒),避免连接断开:
private static final long[] HEARTBEAT = {25_000, 25_000};
注:此为临时方案,推荐用方案1恢复2分钟心跳。
方案3:对齐Spring与Jetty依赖版本
Spring Boot 2.7.5 默认依赖Jetty 9.4.x,部署到Jetty 10时需强制升级Jetty依赖至兼容版本,在pom.xml中添加:
<properties> <jetty.version>10.0.15</jetty.version> <!-- 与Jetty服务器版本保持一致 --> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-bom</artifactId> <version>${jetty.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
验证方式
- 部署后查看Jetty日志,确认不再出现
WebSocketTimeoutException - 通过浏览器开发者工具Network标签,检查WebSocket帧,确认每120秒出现STOMP的
PING/PONG心跳帧
内容的提问来源于stack exchange,提问作者Jenny A-T
相关产品推荐
相关产品推荐

