在Cloud Run部署启用HTTP2(H2)的NodeJS应用遇问题求助
我尝试部署一个已启用HTTP2(H2)的简易NodeJS应用,该应用在本地运行正常。以下是我的NodeJS代码:
const spdy = require('spdy') const express = require('express') const path = require('path') const fs = require('fs') const port = 8080 const CERT_DIR = `${__dirname}/cert`; const app = express() app.get('*', (req, res) => { res .status(200) .json({message: 'Welcome to node HTTP2'}) }) const options = { key: fs.readFileSync(`${CERT_DIR}/server.key`), cert: fs.readFileSync(`${CERT_DIR}/server.crt`) } spdy .createServer(options, app) .listen(port, (error) => { if (error) { console.error(error) } else { console.log('Listening on port: ' + port + '.') } })
我使用openssl命令生成了自签名证书和密钥,本地浏览器可正常访问该应用。但将其部署到Cloud Run并启用「端到端使用HTTP/2」后,请求失败,Cloud Run日志提示:
The request failed because either the HTTP response was malformed or connection to the instance had an error.
我启用HTTP2是为了突破Cloud Run中HTTP/1的32MB请求大小限制,请问是否可以在Cloud Run部署启用HTTP2的NodeJS应用?若可以,我哪里操作有误?
可以在Cloud Run部署启用HTTP/2的Node.js应用,你的代码存在两个关键问题:
Cloud Run与实例的通信不需要自签名证书
Cloud Run会处理外部到服务的TLS终止,它和应用实例之间的通信是明文HTTP/2(h2c),无需在代码中配置SSL证书。你当前用spdy.createServer加载自签名证书,导致Cloud Run无法和实例建立正确连接,这是日志报错的核心原因。需要切换为支持明文HTTP/2的服务配置
无需使用spdy库,Node.js原生从v8.4.0开始支持HTTP/2,推荐直接使用原生模块。要适配Cloud Run的通信方式,需创建明文HTTP/2服务器(h2c),或让服务器同时兼容HTTP/1和HTTP/2的明文连接。
修改后的示例代码:
const http2 = require('http2'); const express = require('express'); const port = process.env.PORT || 8080; const app = express(); app.get('*', (req, res) => { res.status(200).json({message: 'Welcome to node HTTP2'}); }); // 创建支持h2c的服务器,兼容Cloud Run的通信方式 const server = http2.createServer({}, app); server.listen(port, (error) => { if (error) { console.error(error); } else { console.log(`Listening on port: ${port}.`); } });
另外,关于请求大小限制:Cloud Run的HTTP/2确实支持更大的请求体(最大可达10GB),但需确保应用正确处理大请求,比如在Express中配置express.json()或express.raw()时设置合适的limit参数。
内容的提问来源于stack exchange,提问作者Umamaheswararao Meka

