2026.05.27 | youres | 7次围观
在Nginx的实际使用中,很多人会纠结:做重定向时到底用return还是rewrite?两者都能实现301/302跳转,但性能上有没有差异?这篇文章用实测数据来回答这个问题。
一、测试环境与测试方法
1.1 测试环境
- 服务器:2核CPU、4GB内存、Ubuntu 22.04
- Nginx版本:1.24.0(官方稳定版)
- 测试工具:wrk(HTTP基准测试工具)
- 并发连接数:100、500、1000三种场景
- 每个测试持续时间:30秒
1.2 测试配置
为了公平对比,我们准备了两个完全等价的重定向配置:
# return方式\nserver {\n listen 80;\n return 301 https://new.example.com$request_uri;\n}\n\n# rewrite方式(带permanent标记)\nserver {\n listen 80;\n rewrite ^ https://new.example.com$request_uri permanent;\n}两者实现的功能完全相同,都是把HTTP请求以301状态码重定向到HTTPS。
二、实测数据:100并发连接
先看低并发场景,100个并发连接:
| 指标 | return 301 | rewrite permanent |
|---|---|---|
| 每秒请求数(QPS) | 约 45,200 | 约 44,800 |
| 平均响应时间 | 2.21ms | 2.23ms |
| 99%请求响应时间 | 4.15ms | 4.22ms |
| CPU使用率 | 12% | 13% |
在100并发的情况下,两者的性能几乎一致,差异在1%以内,可以忽略不计。
三、实测数据:500并发连接
提升到500并发后:
| 指标 | return 301 | rewrite permanent |
|---|---|---|
| 每秒请求数(QPS) | 约 48,500 | 约 47,900 |
| 平均响应时间 | 10.3ms | 10.4ms |
| 99%请求响应时间 | 18.7ms | 19.2ms |
| CPU使用率 | 38% | 40% |
500并发时,两者差距略微拉大,但仍然很小。return略占优势,但rewrite的性能损耗不超过2%。
四、实测数据:1000并发连接
高并发场景:
| 指标 | return 301 | rewrite permanent |
|---|---|---|
| 每秒请求数(QPS) | 约 51,200 | 约 50,100 |
| 平均响应时间 | 19.5ms | 20.0ms |
| 99%请求响应时间 | 35.1ms | 36.8ms |
| CPU使用率 | 62% | 65% |
1000并发下,return的性能优势稍微明显一点,QPS高出约2.2%,响应时间短约2.5%。但这个差距在日常使用中几乎感知不到。
五、为什么两者性能接近?
5.1 rewrite permanent的本质
很多人以为rewrite会慢很多,其实这是一个误解。rewrite permanent在执行时会自动转换成内部状态码301,然后在Nginx的处理链中和return 301走的是完全相同的路径。
5.2 性能瓶颈不在指令本身
实测数据显示,真正的性能瓶颈在于:
- 网络延迟:重定向响应后客户端需要建立新的HTTPS连接,这个过程占用了大部分时间
- TLS握手:HTTPS连接的建立耗时远超Nginx处理重定向的时间
- 并发数:高并发下的CPU竞争才是主要问题,return和rewrite的差异被稀释
六、实战建议:应该怎么选?
6.1 简单重定向场景:优先用 return
# HTTP跳HTTPS\nreturn 301 https://example.com$request_uri;\n\n# 固定URL跳转\nreturn 302 https://new-url.example.com;6.2 需要正则匹配的复杂场景:用 rewrite
# 需要捕获参数并重组URL\nrewrite ^/old/(\d+)/(.+)$ /new/$2-$1 permanent;\n\n# 多条件判断\nrewrite ^/products/(.*)/page(\d+)$ /category/$1?page=$2 permanent;6.3 需要注意的坑:rewrite的默认行为
# 错误写法:不带last/permanent,默认是内部重定向\nrewrite ^/old /new; # 这会内部跳转,不会返回301给浏览器\n\n# 正确写法:需要外部重定向必须加flag\nrewrite ^/old /new permanent; # 301永久重定向\nrewrite ^/old /new redirect; # 302临时重定向七、性能优化补充建议
- 避免重定向链:A到B到C的重定向会大幅增加耗时,合并为A到C一步到位
- 使用$request_uri而非$uri:前者包含完整URI加查询参数,避免参数丢失
- 合并多个重定向规则:用map指令批量处理,避免逐条if判断
- 开启Nginx的http2支持:多路复用可以减少重定向的开销
总结
实测数据表明,在绝大多数场景下,return和rewrite permanent的性能差异可以忽略不计(小于3%)。选择哪个指令,主要依据是场景复杂度:
- 简单跳转 → 选 return,代码更清晰
- 复杂正则 → 选 rewrite,功能更强大
不要为了性能优化而强行用return替代rewrite,因为两者在运行时的性能几乎一样。有这个精力,不如去优化网络架构、减少重定向链条,这才是真正影响性能的关键因素。
相关文章:
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论