You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

httpd代理后的TomEE websocket出现30秒连接超时问题如何解决?

问题根因
  • 核心原因是Apache httpd作为反向代理时,WebSocket代理的默认超时时间为30秒,超时后代理层会主动断开连接,直接连通TomEE时无代理层所以没有这个限制。
  • reconnecting-websocket疯狂创建连接的原因:代理层静默断开连接时没有发送正常的TCP FIN帧或WebSocket关闭帧,浏览器端无法感知旧连接已经失效,重连逻辑触发时旧连接还处于OPEN(101)状态没有被回收,不断累加导致内存耗尽。
  • 该问题和firewalld无关,无需排查防火墙配置。
修复方案

1. 调整Apache httpd虚拟主机WebSocket代理配置

首先确保Apache已加载mod_proxy、mod_proxy_wstunnel、mod_rewrite三个基础模块,修改虚拟主机配置如下:

# 全局模块加载(未配置的话补充到httpd.conf主配置中)
# LoadModule proxy_module modules/mod_proxy.so
# LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
# LoadModule rewrite_module modules/mod_rewrite.so

ProxyPass / ajp://127.0.0.1:8009/ secret=xxxxxxxxxxxx
# 新增WebSocket空闲超时配置,单位为秒,示例设为3600秒(1小时),可按需调整
ProxyWebsocketIdleTimeout 3600
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
# 原有规则补充代理类型、超时参数
RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L,proxy=ws,timeout=3600]

参数说明:

  • ProxyWebsocketIdleTimeout:全局设置WebSocket代理的空闲超时阈值,超过该时间没有数据传输代理会主动断开连接
  • proxy=ws:明确指定该规则的代理类型为WebSocket,避免代理层协议识别异常
  • timeout=3600:该重写规则下的代理超时时间,和全局空闲超时配置配合生效

修改完成后重启Apache httpd服务生效。

2. 补充应用层心跳机制

就算调整了代理超时,长时间空闲的连接也可能被运营商、服务器TCP策略静默断开,必须在应用层加心跳机制避免半开连接残留:

  • 前端WebSocket连接建立后,每15~30秒向服务端发送一个心跳包(比如普通字符串ping)
  • 服务端收到心跳包后立即返回pong响应
  • 前端如果连续3次(约45~90秒)没有收到服务端的pong响应,主动调用close()关闭旧连接,再触发重连

该机制可以从根源解决旧连接无法回收、重连逻辑不断新建连接导致内存溢出的问题。

3. 调整reconnecting-websocket配置(可选)

如果继续使用该重连库,补充以下配置优化重连逻辑:

const ws = new ReconnectingWebSocket(websocketUrl, null, {
  // 重连前强制关闭旧连接
  closeOnReconnect: true,
  // 最大重连间隔设为10秒,避免短时间内频繁重连
  maxReconnectionDelay: 10000,
  // 最大重连次数可按需设置,避免无限重连占用资源
  maxRetries: 50
})

内容的提问来源于stack exchange,提问作者MitchBroadhead

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:24:03