Cloud Run部署HTTP/2 Node.js应用报503连接终止错误排查
问题根因
Cloud Run开启HTTP/2支持时,会自动终止边缘侧的TLS连接,向后端容器发起的是明文HTTP/2(h2c)请求,不会与后端进行TLS握手。
当前配置中webpack-dev-server启用HTTP/2时默认使用spdy模块加载自签名证书,仅监听加密的h2协议端口,拒绝明文h2c连接,导致Cloud Run边缘代理无法与容器建立有效连接,直接返回503连接终止错误。
本地测试时用https://地址加--insecure参数访问成功,恰好证明服务仅支持带TLS的h2,不支持Cloud Run要求的h2c明文协议。
修复步骤
1. 修改webpack devServer配置
替换原有的server: 'spdy'配置,关闭HTTP/2的TLS加密,启用h2c明文支持,修改后的完整配置如下:
var path = require('path'); module.exports = { entry: './main.js', mode: 'development', devServer: { static: { directory: path.join(__dirname, "./") }, historyApiFallback: true, host: '0.0.0.0', port: 8080, http2: true, // 移除原server: 'spdy'配置,新增以下配置启用h2c server: { type: 'http', options: { h2c: true } }, allowedHosts: 'all', }, output: { path: path.resolve(__dirname, 'build'), filename: 'bundle.js' } };
2. 修正Dockerfile冗余错误配置
原Dockerfile存在无效命令和构建顺序问题,修正后如下:
FROM node:14.15.3 WORKDIR /app # 先复制依赖清单再安装,充分利用Docker构建缓存 COPY package*.json ./ RUN npm install RUN npm i -g webpack webpack-dev-server webpack-cli COPY . /app # 移除npm run dev后无效的-y参数,该参数仅对npm install生效 CMD ["npm", "run", "dev"] EXPOSE 8080
3. 本地验证h2c配置
配置修改后本地启动服务,执行以下命令验证h2c支持:
curl -i --http2-prior-knowledge http://localhost:8080
注意这里必须使用http://协议(不是https),不需要加--insecure参数,如果正常返回HTTP/2 200响应,说明h2c配置生效。
4. 重新部署
重新构建镜像推送到容器镜像仓库,更新Cloud Run服务即可正常访问。
注意事项
- 不需要修改容器监听端口为443,Cloud Run会自动转发请求到Dockerfile中EXPOSE声明的端口,与端口数值无关
- webpack-dev-server仅适用于开发场景,生产环境部署建议先执行
npm run build生成静态产物,使用Nginx等静态服务托管,对应配置Nginx启用h2c支持即可
内容的提问来源于stack exchange,提问作者Vibhor Gaur
相关产品推荐
相关产品推荐

