Spring Boot 3 开启 HTTP/2:h2 和 h2c 到底该选哪个?
目录
写在前面#
想给你的 Spring Boot API 提提速?开启 HTTP/2 (H2) 可能是成本最低、收益最高的方式之一。比起老掉牙的 HTTP/1.1,H2 靠着多路复用、头部压缩这些黑科技,能让你的请求跑得更快、更稳。
但在 Spring Boot 3 里动手前,你得先搞清楚两个概念:h2 和 h2c。别看只差一个字母,用法可是天差地别。
h2 vs. h2c:穿衣服还是“裸奔”?#
简单来说,这两者的区别就在于有没有 TLS(加密):
- h2 = HTTP/2 Over TLS(穿了防弹衣,安全,生产环境标配)
- h2c = HTTP/2 Cleartext(“裸奔”,明文传输,主打一个快)
1. 核心大比拼#
| 特性 | h2 (HTTP/2) | h2c (HTTP/2 Cleartext) |
|---|---|---|
| 安不安全? | 非常安全 (TLS) | 不安全 (明文) |
| 浏览器理你吗? | 所有现代浏览器都支持 | 浏览器基本都不支持 |
| 用在哪? | 公网、APP 接口 | 微服务内网、K8s 集群、gRPC |
| 配置难吗? | 需要 SSL 证书 | Spring Boot 3.5 以后一行配置搞定 |
2. 怎么配 h2?(带加密模式)#
这是我们最常见的模式,毕竟为了安全,Chrome、Firefox 这些浏览器只认带加密的 HTTP/2。
- 怎么配:你需要个 KeyStore 证书,然后在
application.properties里写上:server.port=8443 server.ssl.enabled=true server.ssl.key-store=classpath:keystore.p12 server.http2.enabled=true
3. 怎么配 h2c?(明文模式)#
如果你是在 K8s 集群内部通信,或者有像 Nginx/Envoy 这样的网关帮你挡在前面处理加密,那微服务自己跑 h2c 就很香了——省去了加密的 CPU 损耗,还能享受 H2 的并发红利。
- 划重点:在 Spring Boot 3.5+ 里,配 h2c 已经简单到离谱了。只要不配 SSL 且开启 H2,它就默认支持 h2c:
server.port=8080 server.http2.enabled=true # 只要不写 server.ssl.* 相关的配置就行
为什么浏览器不支持 h2c?#
其实这就是业界在“逼”大家用 HTTPS。一方面是为了安全;另一方面,明文的 HTTP/2 协议太复杂,很多旧的路由器、防火墙看不懂,容易把连接搞崩。所以浏览器干脆规定:想用高性能的 H2?行,先给我把加密加上!
到底怎么选?给你的建议#
- 直接给用户用的接口:别犹豫,用 h2。虽然配证书麻烦点,但这是唯一的选择。
- 微服务内网互相调用:推荐试试 h2c。在自己家的内网里,安全性有保障,性能还更好。
- 如果你用了 Service Mesh (如 Istio):那简直是“爽歪歪”。Mesh 会通过 mTLS 自动帮你搞定 Pod 之间的通信加密,你的应用只需要开启
h2c跑明文就行,加密的重任交给侧车(Sidecar)去扛。这种方案能让你零成本享受到 H2 的性能和全链路的安全。 - 前面有网关(SSL Termination):这是目前最流行的做法。网关(Nginx/Envoy)对外扛着 SSL 证书走
h2,对内跟 Spring Boot 走h2c,既安全又高效。
测一测:怎么知道配置成功了?#
配完之后,别只用浏览器看,浏览器看 h2c 永远是 HTTP/1.1。我们要用命令行工具 curl:
1. 直接强行连接 (Prior Knowledge)#
这种方式最快,不废话,直接按 H2 格式发包:
curl -v --http2-prior-knowledge http://localhost:8080/actuator
如果你看到 * [HTTP/2] [1] OPENED stream,说明配置稳了。
2. 优雅升级 (Upgrade)#
先发 HTTP/1.1 探探路,问问服务器能不能升级到 H2:
curl -v --http2 http://localhost:8080/actuator
看到 * Received 101, Switching to HTTP/2,说明服务器很配合。
总结一下#
HTTP/2 是好东西,在 Spring Boot 3 里开启它并不难。关键是根据你的环境选对 h2 或 h2c。如果是 3.5 之前的版本,配 h2c 可能还得写点 Java 代码,但现在真的是“一行配置走天下”了。
赶紧去给你的微服务升个级吧!