在Web服务器管理中,URL重写是每个运维人员必须掌握的技能。Nginx的rewrite模块就像一位熟练的翻译官,能够将用户请求的URL按照我们设定的规则进行转换。这种能力在实际业务场景中发挥着关键作用:
我管理过日均PV超百万的电商平台,通过合理配置rewrite规则,不仅解决了历史遗留的404问题,还使核心页面的搜索引擎排名提升了30%。下面分享这些实战经验。
Nginx的rewrite指令遵循以下语法格式:
nginx复制rewrite regex replacement [flag];
典型配置示例:
nginx复制location /products {
rewrite ^/products/(.*)$ /item.php?id=$1 last;
}
这个规则会将/products/123转换为/item.php?id=123,其中:
^/products/(.*)$ 是匹配模式的正则表达式/item.php?id=$1 是替换模板last 标志控制处理流程掌握正则表达式是写好rewrite规则的前提。这些特殊字符需要特别注意:
| 字符 | 作用 | 示例说明 |
|---|---|---|
| ^ | 匹配字符串开始 | ^/admin 只匹配以/admin开头的路径 |
| $ | 匹配字符串结束 | .php$ 匹配所有.php结尾的URL |
| . | 匹配任意单个字符 | ^/user. 匹配/user1 /userA等 |
| * | 匹配前一个字符0次或多次 | .* 匹配任意长度字符串 |
| + | 匹配前一个字符1次或多次 | \d+ 匹配连续数字 |
| ? | 匹配前一个字符0次或1次 | https? 匹配http或https |
| \d | 匹配数字 | ^\d+$ 匹配纯数字URL |
| () | 捕获分组用于后续引用 | (.*)捕获的内容用$1引用 |
提示:复杂的正则建议先用在线工具(如regex101.com)测试,避免直接在线上环境调试
现代网站安全必备配置:
nginx复制server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
这个规则通过301永久重定向:
$host变量保留原始域名$request_uri保持完整请求路径电商平台常见需求:
nginx复制rewrite ^/item/(\d+).html$ /item.php?id=$1 last;
效果对比:
code复制原始URL:/item.php?id=123
美化后:/item/123.html
SEO优势:
集团官网常见场景:
nginx复制server {
listen 80;
server_name example.com www.example.com;
if ($host != 'www.example.com') {
rewrite ^(.*)$ https://www.example.com$1 permanent;
}
}
这个配置实现了:
开发环境建议这样调试:
nginx复制rewrite_log on;
error_log /var/log/nginx/rewrite.log notice;
查看日志定位问题:
bash复制tail -f /var/log/nginx/rewrite.log
日志会显示:
高并发场景下的注意事项:
避免过多正则回溯:
^(.*)/(.*)/(.*)/(.*)$^/category/(\w+)/product/(\d+)$慎用if条件判断:
nginx复制# 不推荐写法
if ($request_uri ~* "/old/") {
rewrite ^/old/(.*)$ /new/$1 permanent;
}
# 推荐写法
location /old/ {
rewrite ^/old/(.*)$ /new/$1 permanent;
}
合理使用flag控制流程:
| flag | 作用范围 | 性能影响 |
|---|---|---|
| last | 当前server块 | 中等 |
| break | 当前location块 | 最低 |
| redirect | 客户端跳转 | 最高 |
| permanent | 永久重定向 | 高 |
典型错误配置:
nginx复制location / {
rewrite ^/(.*)$ https://example.com/$1 permanent;
}
症状:浏览器报错"ERR_TOO_MANY_REDIRECTS"
解决方案:
nginx复制location / {
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
# 其他配置...
}
关键点:通过$scheme变量判断当前协议,避免无限循环
错误现象:CSS/JS文件被重写导致404
防护方案:
nginx复制location ~* \.(css|js|png|jpg)$ {
break;
}
location / {
rewrite ^/(.*)$ /index.php?path=$1 last;
}
原始配置:
nginx复制rewrite ^/search/(.*)$ /search.php?keyword=$1 last;
问题:原始URL的查询参数会被丢弃
改进方案:
nginx复制rewrite ^/search/(.*)$ /search.php?keyword=$1&$args last;
通过$args变量保留原始查询参数
支持中英文路径自动识别:
nginx复制map $uri $lang {
~^/en/ en;
~^/zh/ zh;
default en;
}
server {
rewrite ^/(en|zh)/(.*)$ /$2?lang=$1 last;
}
实现效果:
code复制/en/about → /about?lang=en
/zh/about → /about?lang=zh
灰度迁移配置示例:
nginx复制set $new_system 0;
if ($request_uri ~* "^/products/") {
set $new_system 1;
}
location / {
if ($new_system = 1) {
rewrite ^/(.*)$ http://new-system/$1 break;
}
proxy_pass http://old-system;
}
这个方案实现了:
识别设备类型跳转:
nginx复制map $http_user_agent $mobile {
default 0;
~*(android|iphone|ipod) 1;
}
server {
if ($mobile = 1) {
rewrite ^(.*)$ https://m.example.com$1 redirect;
}
}
注意事项:
过滤恶意请求:
nginx复制location / {
if ($query_string ~* "union.*select.*\(") {
return 403;
}
if ($request_uri ~* "(<|%3C).*script.*(>|%3E)") {
return 403;
}
}
阻断非法路径访问:
nginx复制rewrite ^/(.*)/\.\./ /$1 permanent;
if ($request_uri ~* "\.\.") {
return 403;
}
保护配置文件:
nginx复制location ~ /\.(env|git|ht) {
deny all;
return 404;
}
推荐工具:
常用变量列表:
| 变量名 | 说明 |
|---|---|
| $request_uri | 包含查询参数的完整请求URI |
| $uri | 规范化后的请求URI(无参数) |
| $args | 查询字符串(问号后的内容) |
| $host | 请求头中的host值 |
| $scheme | 请求协议(http/https) |
关键运维命令:
bash复制# 测试配置语法
nginx -t
# 热重载配置
nginx -s reload
# 查看完整配置(包括继承关系)
nginx -T
经过多年实战,我总结出这些黄金准则:
测试先行原则:
rewrite_log调试性能优先策略:
SEO友好设计:
安全防护意识:
文档维护建议:
在最近一次全球购物节中,我们通过优化rewrite规则,使服务器QPS处理能力提升了15%,错误请求率下降至0.02%以下。这再次证明,精心设计的重写规则不仅能改善用户体验,还能显著提升系统性能。