return 比 rewrite 更快,因其是原子操作、不触发重写引擎和 location 重匹配;使用 $host 和 $request_uri 可免正则透传;应在 http server 块统一跳转并添加缓存头。

直接用 return 301 https://$host$request_uri; 强制跳转,是消除正则解析开销最有效的方式——它不进重写引擎、不匹配规则、不二次查找 location,请求一进来就返回响应,零正则计算。
为什么 return 比 rewrite 更快
rewrite 指令会强制 Nginx 进入完整重写流程:正则引擎逐条扫描、捕获变量、重写 URI、再重新匹配 location 块,每一步都消耗 CPU 和内存。而 return 是处理链最前端的终止指令,压根不触发这些环节。
- rewrite redirect 实际等价于“先重写 + 再发 302/301”,隐含一次内部跳转
- return 301 是原子操作:状态码 + Location 头一步到位,无中间态
- 在高并发场景下,单个 rewrite 规则带来的额外延迟可能达 0.3–0.8ms,积少成多即成瓶颈
确保 $host 和 $request_uri 用得准确
这两个变量是免正则透传的关键,但用错会导致跳转失败或参数丢失:
-
$host取自请求头 Host 字段,真实反映用户访问的域名(含端口时慎用) -
$request_uri包含原始路径和完整查询字符串,自动保留编码(如%E4%BD%A0%E5%A5%BD),无需 decode/encode - 避免用
$uri或$args单独拼接:前者不含查询参数,后者不含路径,易漏内容 - 跨协议跳转时,
$scheme比硬写https://更安全——若配置了 HTTP/HTTPS 双 server,可复用同一行
单点收口,禁掉所有 if + rewrite 跳转
很多性能问题来自“看不见的叠加”:CDN 已跳 HTTPS,Nginx 又判 if ($scheme = http) 再跳一次;或多个 location 块里分散写 return,形成链式跳转。
- 只在 HTTP server 块(listen 80)中统一做跳转,HTTPS server 块里完全不写任何 return 或 if
- 删掉所有形如
if ($host ~ ...)+rewrite ... permanent的组合,它们是正则热点 - 用
curl -I http://example.com/test?x=1验证:响应头中 Location 必须直达目标,且只出现一次 301
加缓存头,让浏览器记住跳转结果
301 本身是永久性状态,但默认不带缓存控制,部分客户端仍会重复发起原请求。
- 显式加上:
add_header Cache-Control "public, max-age=31536000"; - 配合
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"(仅 HTTPS server 中) - 这样浏览器下次访问 http:// 时,甚至可能不发请求,直接在本地跳转











