部署在GKE上的NestJS WebSocket连接失败问题排查
问题分析与修复方案
你的404错误根源在于GCE Ingress Controller未配置WebSocket协议支持,且缺少Socket.IO核心路径的路由映射,具体修复如下:
关键问题点
- GCE Ingress默认不支持WebSocket自动升级:需要显式配置会话亲和性(WebSocket要求客户端始终连接到同一Pod),并允许HTTP协议升级到WebSocket。
- 缺少
/socket.io路径转发:Socket.IO客户端会先通过/socket.io路径发起轮询请求(就是你看到的404请求),之后才会切换到WebSocket,你的Ingress当前没有配置该路径的转发规则。
具体修复步骤
1. 创建BackendConfig配置GCE负载均衡的WebSocket支持
创建backendconfig.yaml文件:
apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: nestjs-websocket-config spec: # 启用客户端IP亲和性,确保同一客户端请求路由到同一Pod sessionAffinity: affinityType: "CLIENT_IP" # 配置连接超时,避免WebSocket连接被强制断开 connectionDraining: drainingTimeoutSec: 300 # 允许WebSocket升级所需的请求头 customRequestHeaders: headers: - "Upgrade" - "Connection"
2. 更新NestJS Service关联BackendConfig
修改你的NestJS Service清单,添加BackendConfig注解:
apiVersion: v1 kind: Service metadata: name: nestjs-service annotations: # 关联刚才创建的WebSocket配置 cloud.google.com/backend-config: '{"default": "nestjs-websocket-config"}' spec: ports: - port: 80 targetPort: 8080 # 对应你的NestJS Pod端口 protocol: TCP selector: app: nestjs # 替换成你的NestJS Pod标签
3. 更新Ingress添加/socket.io路径转发
修改Ingress清单,增加/socket.io/*的路由规则,将Socket.IO的请求转发到NestJS服务:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main-ingress annotations: kubernetes.io/ingress.global-static-ip-name: "你的静态IP名称" networking.gke.io/managed-certificates: "你的托管证书名称" kubernetes.io/ingress.class: "gce" spec: rules: - host: dev.domain.com http: paths: # 新增:转发Socket.IO请求到NestJS - path: /socket.io/* pathType: ImplementationSpecific backend: service: name: nestjs-service port: number: 80 # 你的NestJS API路由(根据实际情况调整) - path: /api/* pathType: ImplementationSpecific backend: service: name: nestjs-service port: number: 80 # NextJS的路由 - path: /* pathType: ImplementationSpecific backend: service: name: nextjs-service port: number: 80
4. 客户端连接优化(可选)
为避免路径歧义,客户端连接时可以显式指定Socket.IO路径:
const socket = io('https://dev.domain.com', { path: '/socket.io', transports: ['websocket', 'polling'], namespace: '/chat' });
验证操作
- 应用所有配置:
kubectl apply -f backendconfig.yaml -f nestjs-service.yaml -f ingress.yaml
- 等待GCE Ingress更新完成(通常需要5-10分钟)
- 检查Service与BackendConfig的关联状态:
kubectl describe service nestjs-service
- 测试WebSocket连接,确认浏览器不再出现404错误
内容的提问来源于stack exchange,提问作者Hyeonjun Jeong
相关产品推荐
相关产品推荐

