配置server对应的域名
<font style="color:rgb(53, 148, 247);">server name</font>为虚拟服务器的识别路径。因此不同的域名会通过请求头中的HOST字段,匹配到特定的server块,转发到对应的应用服务器中去。<font style="color:rgb(53, 148, 247);">server_name</font>匹配规则:后面可以跟多个域名,第1个是主域名。
精确匹配
如下Nginx配置。
请求结果
server{listen 8080;server_name test1.com;location / {return 200 "I am test1!\n";}}server {listen 8080;server_name my.test.com;location / {return 200 "I am mytest!\n";}}
curl http://my.test.com:8080 返回:I am mytest!curl http://test1.com:8080 返回:I am test1!
正则表达式
- 以
*通配符开始的最长字符串,如下示例
server {listen 8080;server_name test1.*;location / {return 200 "I am test1!\n";}}
- 以
*通配符结束的最长字符串
通配符名字只可以在名字的起始处或结尾处包含一个星号,并且星号与其他字符之间用点分隔。所以,“my.*.com“都是非法的。 例如:
server{listen 8080;server_name *.test.com;location / {return 200 "I am mytest!\n";}}
<font style="color:rgb(53, 148, 247);">server_name my.*.com;</font> 报以下错误:
nginx: [emerg] invalid server name or wildcard "my.*.com" on 0.0.0.0:8080
- 匹配正则表达式
server {listen 8080;server_name ~^my(?<serno>.+).mydomain.com$;location / {return 200 $serno;}}
解释说明
~:表示大小写敏感的正则;^:匹配字符串的开始;{.+}:换行符以外的任意自读重复一次或更多次;():分组与取值;?:表示转义;serno:设置提取的变量;$:匹配字符串的结束;
请求结果
curl http://my02.mydomain.com:8080 返回:02%curl http://my03.mydomain.com:8080 返回:03%
- server_name的配置顺序是怎样的呢?按照如下顺序匹配:匹配顺序-> ->精确匹配 ->在前的域名 ->在后的域名 ->按文件中的顺序匹配 ->default server:第一个,listen指定default
配置location
Location 匹配规则:仅匹配URI,忽略参数
location [=|~|~*|^~] /uri/ { … }
匹配的正则符号如下:
- = 严格匹配。如果请求匹配这个location,那么将停止搜索并立即处理此请求
- ~ 区分大小写匹配(可用正则表达式)
- ~* 不区分大小写匹配(可用正则表达式)
- !~ 区分大小写不匹配
- !~* 不区分大小写不匹配
- ^~ 如果把这个前缀用于一个常规字符串,那么告诉Nginx 如果路径匹配那么不测试正则表达式
举例
1、匹配任意请求location [=|~|~*|^~] /uri/ { … }2、不区分大小写匹配以js、php结尾的请求location ~* .(js|php)$ { … }3、区分大小写匹配以.txt结尾的请求location ~ ^.+\.txt$
匹配顺序如下图

location = /documents {return 200 'configuration A'}location /documents {return 200 'configuration B'}location /documents/txt1 {return 200 'configuration C'}location ^~ /documents/ {return 200 'configuration D'}location ~* /documents/(\w+)$ {return 200 'configuration E'}location ~ /documents/$ {return 200 'configuration F'}
curl http://test1.com:8080/documents%EF%BC%8C%E7%B2%BE%E7%A1%AE%E5%8C%B9%E9%85%8D%E8%BF%94%E5%9B%9Econfiguration Acurl http://test1.com:8080/documents/^~匹配上后不在匹配,返回 configuration Dcurl http://test1.com:8080/documents/txt1走到了正则匹配,不会走到/documents/txt1(正则没走完) 返回configuration Ecurl http://test1.com:8080/documents/txt1/,%E8%BF%94%E5%9B%9EconfigurationC,因为正则都不匹配
如何debug正则呢?
编译的时候加上 --with-debug选项,例如<font style="color:rgb(53, 148, 247);">./configure --with-debug conf</font>文件加上要debug的host,<font style="color:rgb(53, 148, 247);">debug_connection</font>对应要debug的连接。
events {worker_connections 1024;debug_connection 192.168.1.3;debug_connection 127.0.0.1;}
error.log查看debug日志,图中test location就是正则匹配的过程。

配置rewrite
语法如下:
指令语法:rewrite regex replacement[flag];默认值:none应用位置:server、location、ifrewrite是实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到replacement,结尾是flag标记.
| flag标记 | 说明 |
|---|---|
| last | 本条规则匹配完成后继续向下匹配新的location URI规则 |
| break | 本条规则匹配完成后终止,不在匹配任务规则 |
| redirect | 返回302临时重定向 |
| permanent | 返回301永久重定向 |
重定向
<font style="color:rgb(53, 148, 247);">return</font>三种code,code url和url。返回状态码:444表示关闭连接 301表示http1。0中永久重定向,302表示临时重定向,进制缓存。http1.1后,303表示临时重定向,允许改变方法,进制缓存,307表示临时重定向,不允许改变方法,禁止被缓存,308表示永久重定向,不允许改变方法。
- 返回code
location / {return 301 https://www.xxxx.com$request_uri;}
- 通过
$request_uri变量匹配所有的URI。
rewrite ^ https://www.xxxx.com$request_uri? permanent;
- 通过正则匹配所有的URI后再去掉开头第一个/(反斜线)。
rewrite ^/(.*)$ https://www.xxxx.com/$1;
- 与if指令结合
server {listen 80;server_name test1.net test2.net;if ($host != 'test1.net' ) {rewrite ^/(.*)$ http://www.baidu.net/$1 permanent;}}
如何查看rewrite日志
打开日志开关<font style="color:rgb(53, 148, 247);">rewrite_log on;</font> 可以配置到http,server,location和if上下文中。
示例:<font style="color:rgb(53, 148, 247);">curl test1.com:8080/first/2.txt</font>。
效果图如下:
location /first {rewrite_log on;rewrite /first(.*) /second$1 last;}

配置 proxy
对上游服务使用<font style="color:rgb(53, 148, 247);">http/https</font>协议进行反向代理。<font style="color:rgb(53, 148, 247);">proxy_pass</font>后面跟 url,可以仿造 location,if in location和<font style="color:rgb(53, 148, 247);">limit_except</font>上下文中。
这个功能是默认编译到Nginx中的。本文重点讨论http proxy。
url参数规则
- url必须以http或者https开头,接下来是域名、ip、unix socket或者upstream名字,都可以就端口。后面是可选的uri
<font style="color:rgb(53, 148, 247);">proxy_pass http://localhost:8000/uri/;</font> 。
UNIX域套接字路径来定义示例:<font style="color:rgb(53, 148, 247);">proxy_pass http://unix:/tmp/backend.socket:/uri/;</font>
+ url中是否携带uri,结果也不一样,如果在<font style="color:rgb(89, 89, 89);">proxy_pass</font>后面的url加/,相当于是绝对根路径,则Nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分给代理走。 目录结构如下
Nginx配置如下
├── first│ └── index.html├── index.html└── second└── index.html
不带
server {listen 8081;server_name my.test.com;}server {listen 8082;# 第一种情况location /first {proxy_pass http://my.test.com:8081;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 第二种情况location /first {proxy_pass http://my.test.com:8081/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
<font style="color:rgb(53, 148, 247);">/</font>,然后<font style="color:rgb(53, 148, 247);">curl http://127.0.0.1:8082/first/index.html</font>直接返回index.html。
带<font style="color:rgb(53, 148, 247);">/</font>,然后 curl <font style="color:rgb(53, 148, 247);">http://127.0.0.1:8082/first/index.html</font>返回first下的index.html。
- Url参数中可以携带变量
proxy_pass http://$host$uri; - 可以配合rewrite break语句
location /nameb/ {rewrite /nameb/([^/]+) /test?nameb=$1 break;proxy_pass http://127.0.0.1:8801/;}
小结
配置Nginx的路由,有多种方式,域名可以用<font style="color:rgb(53, 148, 247);">server_name</font>配置,uri可以用location配置,复杂的可以加rewrite配置修改请求。还有就是配置proxy代理,在代理中转发id等。本文开头的几个问题,同端口不同域名使用<font style="color:rgb(53, 148, 247);">server_name</font>配置就可以,可以放到不同的server中;location的匹配顺序可以参考文中的那张流程图;重定向的情况下客户端拿到302和url就会去请求这个url指定的资源,proxy不会,因此在Nginx+Tomcat的场景下,proxy更适合。
