Docker中部署Tomcat+WebApp:WebSocket握手失败求助
Docker部署Tomcat后WebSocket连接失败的排查方案
我来帮你定位这个问题,结合你的场景,大概率是这几个环节出了问题,咱们一步步来排查:
1. 先确认Docker端口映射是否正确
这是最容易踩的坑!你本地用8090端口访问,必须保证启动Docker容器时,把容器内Tomcat的默认端口(8080)映射到宿主机的8090。正确的启动命令应该是这样的:
docker run -p 8090:8080 your-tomcat-image-name
你可以用docker ps命令查看容器列表,检查端口列是不是显示0.0.0.0:8090->8080/tcp——如果是8090:8090或者其他格式,那映射肯定错了,WebSocket自然连不上。
2. 验证容器内的WebSocket服务是否正常运行
先进入容器内部,确认Tomcat里的WebSocket端点本身没问题:
- 进入容器:
docker exec -it your-container-id /bin/bash
- 用curl模拟WebSocket握手请求(虽然不能完全建立连接,但能验证端点是否存在):
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost:8080" -H "Sec-WebSocket-Key: test-key" -H "Sec-WebSocket-Version: 13" http://localhost:8080/my-app/chat/my-user
如果返回HTTP/1.1 101 Switching Protocols,说明服务端的WebSocket端点是正常的;如果返回404 Not Found,那要么是你的应用没部署对,要么是路径写错了。
3. 检查应用上下文路径是否匹配
你客户端用的路径是/my-app/chat/my-user,得确认容器内的Tomcat应用上下文是不是my-app:
- 如果你把war包改名为
ROOT.war部署,上下文路径会变成根路径,这时候客户端地址应该改成ws://localhost:8090/chat/my-user; - 如果war包名字是
my-app.war,那上下文路径就是my-app,没问题。
4. 排查宿主机防火墙/安全组
宿主机的防火墙可能会拦截8090端口的入站请求:
- Linux:用
ufw allow 8090或者firewall-cmd --add-port=8090/tcp --permanent && firewall-cmd --reload开放端口; - Windows/Mac:在系统防火墙设置里,添加允许
8090端口的入站规则。
5. 查看Tomcat日志找细节线索
直接看容器内Tomcat的日志,能快速定位异常:
# 进入容器后执行 cat /usr/local/tomcat/logs/catalina.out | grep -i websocket
如果日志里出现No endpoint found for path /my-app/chat/my-user,说明端点注册失败;如果有Connection refused类的错误,可能是Tomcat本身没正常启动。
按照这个顺序排查,90%的情况都能解决问题——最常见的就是端口映射错误或者上下文路径不匹配。
内容的提问来源于stack exchange,提问作者tom




