Beego v2.x 必须启用 HTTPS(合法 TLS 证书+私钥)才能运行 HTTP/2,纯 HTTP 端口不支持;需正确配置 HTTPSPort、HTTPSCertFile、HTTPSKeyFile,且避免反向代理终止 TLS 导致降级。

Beego v2.x 默认不启用 HTTP/2,需手动配置 TLS 并满足证书条件
Beego v2 不像 Gin 或 Echo 那样自动协商 HTTP/2;它依赖 Go 标准库的 http.Server 行为,而后者只在启用 TLS 且客户端支持时才升级到 HTTP/2。也就是说:**没有 HTTPS,就不可能有 HTTP/2**。你不能在纯 HTTP 端口上“开启 HTTP/2”,那是协议层面不合法的。
常见错误现象:curl -I --http2 http://localhost:8080 返回 HTTP/1.1 200 OK,或浏览器 DevTools 显示 Protocol 为 h1;netstat -tuln 看不到 ALPN 协商痕迹。
- 必须使用
adapter.BConfig.Listen.HTTPSCertFile和adapter.BConfig.Listen.HTTPSKeyFile指向合法 PEM 文件(非 PKCS#8 私钥,不含密码) - 证书链必须完整:cert.pem 要包含服务器证书 + 中间 CA,否则 Go 的
crypto/tls会静默降级回 HTTP/1.1 - 私钥权限必须是
600(Linux/macOS),否则启动时无报错但 HTTP/2 不生效 - 不要设
adapter.BConfig.Listen.EnableHTTP = true同时监听 HTTP/HTTPS —— 若未配HTTPToHTTPS = true,HTTP 端口仍走 HTTP/1.1,且可能干扰 ALPN 探测
如何验证 Beego 是否真正运行在 HTTP/2 上
不能只看日志或端口监听,得从协议栈和客户端双向确认。Beego 自身不暴露 ALPN 或 http2.Server 实例,一切依赖底层 http.Server.ServeTLS 的行为。
- 用
curl -v --http2 https://localhost:8443/ 2>&1 | grep ALPN,应看到ALPN, offering h2和ALPN, server accepted to use h2 - 浏览器访问
https://localhost:8443后打开 DevTools → Network → 刷新 → 点击任意请求 → Headers → 查看Protocol字段是否为h2 - 服务端加一行日志:
logs.Info("Server started with TLS config: %+v", adapter.BeeApp.Server.TLSConfig),确认TLSConfig.NextProtos包含"h2" - 若用 Wireshark 抓包,过滤
tls.handshake.type == 1(ClientHello),检查 Extension 里是否有application_layer_protocol_negotiation (16),且内容含h2
Beego v2 中 HTTP/2 与配置项的耦合细节
HTTP/2 不是开关式配置,它由多个参数隐式触发。漏掉任一环节,都会 fallback 到 HTTP/1.1,且 Beego 不报错、不警告。
-
adapter.BConfig.Listen.HTTPSPort必须显式设置(如8443),不能留空或为0—— 否则adapter.Run()不启动 TLS listener -
adapter.BConfig.Listen.HTTPSCertFile和adapter.BConfig.Listen.HTTPSKeyFile必须是**绝对路径**或相对于当前工作目录的**可读路径**;相对路径在bee pack打包后常失效 - 若同时启用
HTTPToHTTPS = true,HTTP 端口(如8080)仅做 301 重定向,本身仍是 HTTP/1.1,不参与 HTTP/2 协商 - Beego v2 不支持 HTTP/2 的 Server Push,也未暴露
http2.Server的MaxConcurrentStreams等调优参数,所有底层控制需通过替换adapter.BeeApp.Server实例实现(高阶用法,易出错)
部署时 HTTP/2 容易被忽略的三个实际问题
本地能跑 HTTP/2,上线就退化成 HTTP/1.1,90% 出在这三处。
- 反向代理(Nginx / Traefik)终止了 TLS:此时 Beego 收到的是明文 HTTP 请求,
adapter根本不会进入 TLS 分支,HTTP/2 彻底失效。解决方案是让代理透传 ALPN(如 Nginx 的proxy_http_version 2.0+proxy_ssl_protocols TLSv1.2 TLSv1.3) - 云平台(如阿里云 SLB、AWS ALB)只支持 TLS 终止,不支持 ALPN 透传:这种情况下 Beego 只能跑 HTTP/1.1,别挣扎,改用代理层做 HTTP/2 终结
- 证书不是由可信 CA 签发(如自签名或 Let’s Encrypt staging 环境):某些客户端(尤其是 iOS Safari)会拒绝协商 h2,即使证书校验通过。生产环境务必用正式 Let’s Encrypt 或商业证书
HTTP/2 的生效与否,不在 Beego 代码里写几行就能决定;它卡在证书链完整性、TLS 握手流程、反向代理配置三层之间。任何一层断开,都看不到 h2。











