场景描述
- A 域名:Nginx 对外提供 HTTP/1 服务,需要将接口请求代理到 B 域名
- B 域名:Nginx 支持 HTTP/2
- 需求:A 域名的 Nginx 反向代理接口到 B 域名
Nginx 版本与上游 HTTP/2 支持
| Nginx 版本 | 支持的上游协议 | 配置方式 |
|---|---|---|
| >= 1.25.1 | HTTP/2 | proxy_http_version 2.0 |
| < 1.25.1 | HTTP/1.1 | proxy_http_version 1.1 + Connection "" |
proxy_http_version 2.0指令从 Nginx 1.25.1 开始引入,低版本无法使用。
配置示例(Nginx < 1.25.1)
适用于 Nginx 1.23.1 等低于 1.25.1 的版本:
server {
listen 80;
server_name a.example.com;
location /api/ {
proxy_pass https://b.example.com;
# 上游使用 HTTP/1.1 + keep-alive
proxy_http_version 1.1;
proxy_set_header Connection ""; # 清除默认的 Connection: close,启用 keep-alive
# SSL 相关
proxy_ssl_server_name on; # 发送 SNI,多域名共享 IP 时必须
proxy_ssl_verify on; # 验证上游证书
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
# 转发请求头
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
关键配置说明
proxy_http_version 1.1:指定代理到上游时使用 HTTP/1.1 协议proxy_set_header Connection "":清除默认的Connection: close头,使代理连接保持 keep-alive,减少 TCP/TLS 握手开销proxy_ssl_server_name on:代理到 HTTPS 上游时发送 SNI(Server Name Indication),确保上游返回正确的 SSL 证书proxy_ssl_verify on:验证上游 SSL 证书的有效性
配置示例(Nginx >= 1.25.1)
如果 Nginx 版本 >= 1.25.1,可以直接使用 HTTP/2 连接上游:
server {
listen 80;
server_name a.example.com;
location /api/ {
proxy_pass https://b.example.com;
# 向上游发起 HTTP/2 连接
proxy_http_version 2.0;
proxy_ssl_server_name on;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
常见问题
Q: 低版本 Nginx 用 HTTP/1.1 代理到支持 HTTP/2 的上游,功能会受影响吗?
不会。B 域名的 Nginx 同时兼容 HTTP/1.1 和 HTTP/2,收到 HTTP/1.1 请求会正常处理,接口功能完全不受影响。唯一的区别是无法利用 HTTP/2 的多路复用特性。
Q: 如果一定需要端到端 HTTP/2 但又不想升级 Nginx,怎么办?
可以考虑使用原生支持 HTTP/2 上游的反向代理:
- Caddy:默认支持 HTTP/2 上下游
- Envoy:高性能代理,完整支持 HTTP/2
Q: 如何查看当前 Nginx 版本?
nginx -v