摘要
在部署基于WebSocket的实时通信服务时,我们常常使用Nginx作为反向代理。然而,很多开发者(尤其是像我这样的新手😅)在使用wss://
协议时,常常遇到“间歇性断开连接”的问题。本文将从小白的视角出发,系统性分析这个问题的成因、排查流程与优化策略,并给出完整可行的解决方案。
如果你也被这个问题困扰,希望这篇文章能帮你彻底解决它!
博主 默语带您 Go to New World.
✍ 个人主页—— 默语 的博客👦🏻 优秀内容
《java 面试题大全》
《java 专栏》
《idea技术专区》
《spring boot 技术专区》
《MyBatis从入门到精通》
《23种设计模式》
《经典算法学习》
《spring 学习》
《MYSQL从入门到精通》数据库是开发者必会基础之一~
🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭
🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄之助。苟未尽善尽美,敬请批评指正,以资改进。!💻⌨
默语是谁?
大家好,我是 默语,别名默语博主,擅长的技术领域包括Java、运维和人工智能。我的技术背景扎实,涵盖了从后端开发到前端框架的各个方面,特别是在Java 性能优化、多线程编程、算法优化等领域有深厚造诣。
目前,我活跃在CSDN、掘金、阿里云和 51CTO等平台,全网拥有超过15万的粉丝,总阅读量超过1400 万。统一 IP 名称为 默语 或者 默语博主。我是 CSDN 博客专家、阿里云专家博主和掘金博客专家,曾获博客专家、优秀社区主理人等多项荣誉,并在 2023 年度博客之星评选中名列前 50。我还是 Java 高级工程师、自媒体博主,北京城市开发者社区的主理人,拥有丰富的项目开发经验和产品设计能力。希望通过我的分享,帮助大家更好地了解和使用各类技术产品,在不断的学习过程中,可以帮助到更多的人,结交更多的朋友.
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
默语:您的前沿技术领航员
👋 大家好,我是默语!
📱 全网搜索“默语”,即可纵览我在各大平台的知识足迹。📣 公众号“默语摸鱼”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“Solitudemind”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 6 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
Nginx反向代理WebSocket (wss://) 间歇性断开连接的深度分析
引言:WebSocket、Nginx与WSS是啥?
在开始之前,我们得搞清楚几个基本概念:
什么是WebSocket?
WebSocket是一种持久化双向通信协议,与HTTP不同,WebSocket连接一旦建立,就可以在客户端和服务端之间双向传输数据而无需每次重新建立连接。
它非常适合即时通信、实时推送等场景。
什么是wss://?
wss://
是WebSocket的加密版协议,类似于https://
是http://
的加密版。它依赖于TLS(SSL)加密,保证通信安全。
为什么用Nginx反向代理?
很多时候,我们不直接让用户访问后端服务,而是使用Nginx做一层中转,起到负载均衡、防火墙、SSL终端等作用。这种做法叫做反向代理。
正文内容
一、问题描述
在生产环境中,WebSocket服务运行正常,但是通过wss://
+ Nginx反向代理后,连接出现如下问题:
- 客户端连接后,几分钟或几十分钟后自动断开。
- 后端服务没有任何异常日志。
- 客户端收到1006关闭码(Abnormal Closure)。
这是典型的“间歇性断开”,也是许多开发者掉坑的地方。
二、可能的原因分析
1. Nginx连接超时设置过短
默认情况下,Nginx对空闲连接有超时限制,如果一定时间内没有数据传输,就会自动关闭连接。
相关配置:
proxy_read_timeout 60s; # 默认60秒后无数据将关闭连接
2. WebSocket自身没有心跳机制
WebSocket连接本身不会自动发送“保活数据”,因此长时间不发数据时,Nginx或中间网络设备可能认为连接“已死”。
3. TCP连接被中间网络设备(防火墙/代理)切断
某些公司或云厂商的网络设备会在TCP连接长期无数据时强制中断连接。
4. SSL/TLS握手失败或过期问题
当使用wss://
时,TLS连接可能因为证书问题或者TLS会话超时导致连接中断。
三、如何解决?——实战配置 + 心跳机制
1. 优化Nginx配置
在nginx.conf
或对应的server
块中添加以下配置:
location /ws/ {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s; # 设置更长的超时时间
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;
}
📝 注意:路径
/ws/
仅为示例,请根据你自己的WebSocket路径修改。
2. 服务端添加心跳机制(Python 示例)
以Python中的websockets
库为例:
import asyncio
import websockets
import json
async def heartbeat(ws, interval=30):
while True:
try:
await ws.send(json.dumps({"type": "ping"}))
await asyncio.sleep(interval)
except websockets.ConnectionClosed:
break
async def handler(ws, path):
asyncio.create_task(heartbeat(ws))
async for message in ws:
print("Received:", message)
start_server = websockets.serve(handler, 'localhost', 8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
3. 客户端接收心跳并回应(JavaScript 示例)
const socket = new WebSocket("wss://yourdomain.com/ws/");
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === "ping") {
console.log("收到服务器ping,连接保活");
}
};
4. 检查证书 & TLS 设置
- 确保SSL证书是有效的(没有过期)。
- 避免在TLS握手中使用过时的加密算法。
- 可以使用
ssl_session_timeout
提升TLS会话缓存时间:
ssl_session_timeout 1h;
总结
WebSocket通过Nginx反向代理时出现间歇性断开的常见原因包括:
- Nginx超时配置过短
- WebSocket服务未实现心跳
- 网络设备的TCP超时策略
- SSL配置不当
我们可以通过合理的Nginx配置 + 心跳机制来保证连接的稳定性,避免频繁断开的问题。
只要按照本文的方法,绝大多数wss://
断连问题都能得到解决。
参考资料
如果你也在搞WebSocket、Nginx或者有部署相关的困惑,欢迎加我微信交流,一起成长~ 👇
我的微信:Solitudemind
如对本文内容有任何疑问、建议或意见,请联系作者,作者将尽力回复并改进📓;( 联系微信:Solitudemind )
点击下方名片,加入 IT 技术核心学习团队。一起探索科技的未来,共同成长。
为了让您拥有更好的交互体验,特将这行文字设置为可点击样式:点击下方名片,加入 IT
技术核心学习团队。一起探索科技的未来,共同成长。