用map预定义$scheme映射可避免每次请求重复判断:map在http块中启动时编译为O(1)查表,$redirect_to_https值初始化即确定,return直接使用无需if解析,消除字符串比对开销。

直接用 map 指令预定义 $scheme 对应的协议前缀,可跳过 Nginx 在每次请求中动态判断是否需要重定向的逻辑,从而避免重复的 301 计算开销。
为什么 $scheme 会触发冗余重定向判断
Nginx 默认不缓存重定向决策。当配置中存在类似 if ($scheme = http) { return 301 https://...; } 的写法时,Nginx 必须在每个请求到达时解析 $scheme、比对字符串、执行条件分支——即使该变量值在本次连接生命周期内恒定不变。高频请求下,这部分 CPU 开销会累积显现。
用 map 提前映射协议类型到目标 URL
把协议判断逻辑从运行时移至配置加载阶段,用 map 构建静态映射表:
map $scheme $redirect_to_https {
http "https://$host$request_uri";
https "";
}这样,$redirect_to_https 在请求处理初期就已确定值:HTTP 请求得到完整 HTTPS 地址,HTTPS 请求为空字符串。后续只需一次变量判空即可决定是否跳转,无需字符串比较或条件块解析。
配合 return 实现零开销跳转
在 server 块中直接使用映射结果:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">if ($redirect_to_https) {
return 301 $redirect_to_https;
}
# 正常处理逻辑...}
更优写法是省略 if(因 return 在非匹配上下文中不生效):
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">return 301 $redirect_to_https;}
只要 $redirect_to_https 非空就跳转;为空则继续走默认流程(此时需确保该 server 块只处理 HTTP 流量,避免误跳)。
注意 map 的作用域与初始化时机
-
map必须定义在http块内,不能放在server或location中 - 映射关系在 Nginx 启动时编译完成,不随请求变化,无运行时性能损耗
- 确保
$host和$request_uri在return中被安全引用(它们在 server 上下文可用)


















