在Google App Engine部署Node.js(v12) HTTP/2服务器遇问题求助
Let’s break down the issues you’re facing and walk through how to resolve them:
Core Problems Identified
- SSL Termination Conflict: Google App Engine handles HTTPS termination at its load balancer—your app doesn’t need to serve HTTPS directly. Using
http2.createSecureServerwith custom certificates confuses the proxy, which expects plain HTTP traffic on the backend port. - Port Mismatch: You explicitly set
PORT:8080inapp.yaml, but App Engine may override this with its own port (like 8081 in your logs). Your app must listen on the port provided by thePORTenvironment variable, not a hardcoded value. - Protocol Incompatibility: App Engine’s proxy communicates with your app using HTTP/1.1. If your server only speaks HTTP/2 (without enabling HTTP/1 fallback), it can’t interpret the proxy’s requests, leading to the "no valid HTTP/1.0 header" error.
Solution 1: Simplify to Standard Koa HTTP Server (Recommended)
App Engine automatically serves HTTP/2 to clients even if your app uses HTTP/1.1 internally. This is the easiest and most reliable fix:
Update main.js
Remove the HTTP/2 secure server setup and use Koa’s default listen() method:
const app = new (require('koa'))(); const logger = require('koa-logger'); const bodyParser = require('koa-bodyparser'); const json = require('koa-json'); const cors = require('@koa/cors'); const router = require('./router.js'); const { PORT, HOST } = require('./config.js'); app.use(logger()); app.use(bodyParser()); app.use(json()); app.use(cors({ exposeHeaders: 'authorization' })); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(PORT, () => { console.log(`Koa running at http://${HOST}:${PORT}`); });
Update config.js
Ensure it reads the PORT environment variable (App Engine sets this automatically):
module.exports = { PORT: process.env.PORT || 8080, // Fallback to 8080 for local development HOST: process.env.HOST || 'localhost', // Remove KEY and CERT—they’re no longer needed };
Update app.yaml
Remove the PORT, KEY, and CERT entries from env_variables (App Engine manages the port internally):
runtime: nodejs12 service: api handlers: - url: /.* script: auto secure: always redirect_http_response_code: 301 vpc_access_connector: name: [your connector name] env_variables: NODE_ENV: production
Solution 2: Keep Using HTTP/2 Server (If You Need Internal HTTP/2 Features)
If you want to use HTTP/2-specific features (like server push, note that App Engine’s proxy may not pass push frames to clients), use http2.createServer with allowHTTP1: true to handle both HTTP/1.1 (from the proxy) and HTTP/2 requests:
Update main.js
const http2 = require('http2'); const app = new (require('koa'))(); const logger = require('koa-logger'); const bodyParser = require('koa-bodyparser'); const json = require('koa-json'); const cors = require('@koa/cors'); const router = require('./router.js'); const { PORT, HOST } = require('./config.js'); app.use(logger()); app.use(bodyParser()); app.use(json()); app.use(cors({ exposeHeaders: 'authorization' })); app.use(router.routes()); app.use(router.allowedMethods()); // Create HTTP/2 server that accepts HTTP/1.1 requests from the proxy const server = http2.createServer({ allowHTTP1: true }, app.callback()) .listen(PORT, () => { console.log(`Koa HTTP/2 running at http://${HOST}:${PORT}`); });
Use the same config.js and app.yaml changes as in Solution 1.
Why This Works
- No SSL Conflicts: App Engine handles all HTTPS termination, so your app only needs to serve plain HTTP traffic.
- Correct Port Handling: By using
process.env.PORT, your app listens on the exact port App Engine expects, fixing the mismatch in your logs. - Protocol Compatibility: Either the standard Koa server or the HTTP/2 server with
allowHTTP1: trueunderstands the HTTP/1.1 requests from App Engine’s proxy, ensuring valid responses reach clients.
内容的提问来源于stack exchange,提问作者slanden

