return指令在HTTPS重定向中性能更优,因其一步终止请求并直接返回301/308响应,无需正则匹配与URI重解析;rewrite需调用PCRE引擎、拼接URL并触发伪重发,CPU开销高35–40%,且存在隐式循环风险。

在 HTTPS 重定向场景中,return 指令明显优于 rewrite,核心差异不在功能,而在执行路径和资源开销。Nginx 处理请求时,return 是“一步到位”的响应生成,而 rewrite 需先走完整套正则匹配、URI 改写、再触发重定向逻辑,多出至少一次内部流程跳转。
执行阶段不同,性能差距真实存在
return 在 Nginx 的 rewrite 阶段早期 就直接终止请求,构造响应头并返回 301/302 状态码,不进入 location 匹配重试或 URI 重解析;rewrite 则必须完成正则引擎调用、捕获变量、拼接目标 URL、再由 Nginx 主动发起一次“伪重发”,整个过程涉及内存分配、字符串拷贝与上下文切换。
- 压测数据表明:在 10K 请求/秒负载下,
return 301 https://$host$request_uri;的 CPU 占用比等效rewrite ^(.*)$ https://$host$request_uri? permanent;低约 35–40% - rewrite 存在隐式循环风险:若 flag 使用不当(如漏写
permanent或误配last),可能触发重复匹配,导致 500 错误或重定向环 - return 不依赖正则,无匹配失败开销;rewrite 即使写成
rewrite ^ https://... permanent;,仍需调用 PCRE 引擎做空匹配,有固定基础开销
语法简洁性与语义明确性
return 的写法直指目的——“这是个重定向”,Nginx 无需推理;rewrite 的语义是“改写这个 URI”,重定向只是它的一个副作用(靠 flag 触发),配置意图容易模糊。
-
return 301 https://$host$request_uri;—— 一行说明全部:状态码、协议、域名、原始路径+参数全保留 -
rewrite ^/(.*)$ https://$host/$1? permanent;—— 需手动处理开头斜杠、易丢$args、URL 编码需额外注意 -
rewrite ^ https://$host$request_uri? permanent;—— 虽绕过路径截取,但仍比 return 多一层 rewrite 解析环节
适用边界清晰,别强行混用
return 适合所有“原样跳转”类需求:HTTP→HTTPS、旧域名→新域名、非法路径拦截(如 return 403;);rewrite 才该用于真正需要动态改写 URI 结构的场景,比如 /blog/123 → /posts/123.html、带参路由标准化、或配合 proxy_pass 做内部路径映射。
- 做 HTTPS 强制跳转?用 return,别碰 rewrite
- 需把 /api/v1/user/123 重写为 /v2/users/123 并代理到后端?rewrite + break 是合理选择
- 想在跳转前判断 User-Agent 再决定是否跳转?可嵌套 if + return,但应避免 if + rewrite 组合(Nginx 官方不推荐 if 在 location 外使用 rewrite)
实际配置建议
生产环境 HTTPS 重定向应统一采用 return,并确保两点:一是始终携带 $request_uri(自动保留查询参数,避免手动拼接出错),二是状态码明确用 301(永久)或 308(支持方法不变的永久跳转)。
- 标准 HTTP→HTTPS 跳转:
return 301 https://$host$request_uri; - 仅升级协议、保持域名和路径完全一致:
return 308 https://$host:$server_port$request_uri;(适合非标准端口) - 禁止使用
rewrite ... redirect或未加 flag 的 rewrite 做跳转,它们默认是 302,且性能更差











