@adonia
2018-05-25T06:12:15.000000Z
字数 20767
阅读 248
nginx
Nginx配置文件默认是${NGINX_HOME}/conf/nginx.conf.default
,重命名为nginx.conf
。主要内容如下:
main
events {
....
}
http {
....
upstream myproject {
.....
}
server {
....
location {
....
}
}
server {
....
location {
....
}
}
....
}
main
为全局配置
events
为Nginx的工作模式
http
为请求服务配置
upstream
为负载均衡器配置
server
为主机配置
location
为请求路由配置
Nginx的默认全局配置如下:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#worker_rlimit_nofile 1024;
user
是用来指定Nginx Worker进程用户和属组,默认是nobody,也可以在使用源码编译时,通过--user=nginx --group=users
命令指定。
worker_processes
指明了Nginx Worker子进程的个数。可以设置跟CPU的核数一致,每个Nginx进程平均耗费10~12M内存。
error_log
用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、crit。也可以在使用源码编译时,通过--error-log-path=/opt/nginx/log/error.log
指定。
pid
指明了Nginx进程id存储的文件,也可以在使用源码编译时,通过--pid-path=/opt/nginx/conf/nginx.pid
指定。
worker_rlimit_nofile
指定了Nginx可打开的最大文件句柄树,需要和ulimit -n
同步考虑。
如下是worker_processes
设置为2时,查询到的进程情况:
nginx@NKG1000009441:~/conf> pgrep nginx
32847
58111
58112
nginx@NKG1000009441:~/conf> ps -ef | grep 32847
nginx 32847 1 0 May05 ? 00:00:00 nginx: master process nginx
nginx 58111 32847 0 09:30 ? 00:00:00 nginx: worker process
nginx 58112 32847 0 09:30 ? 00:00:00 nginx: worker process
nginx 58878 58020 0 09:42 pts/1 00:00:00 grep 32847
events模块用来设置Nginx的工作模式和连接上限,如下:
events {
use epoll;
worker_connections 1024;
}
use
指明了Nginx的工作模式,即处理客户端连接的方式,包括select、poll、kqueue、epoll、rtsig和/dev/poll。其中,epoll
和kqueue
为高效的处理方式,不同的是epoll
支持Linux系统,而kqueue
支持BSD系统。详见Nginx Connection processing methods
worker_connections
定义了每个Worker进程的最大连接数,即能够处理的最大客户端请求数。那么,Nginx能够处理的最大请求数即为worker_connections * worker_processes
。同样,进程的最大连接数与ulimit -n
的设置有关。
http模块负责了服务器的相关属性配置,包括主机配置和负载均衡。如下:
http{
server_tokens off;
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
#gzip on;
upstream myproject {
.....
}
server {
....
}
}
server_tokens off
可以在错误页面隐藏nginx的版本号,提高安全性。(开源软件都会有每个版本的bug list和release notes)
include
引用了文件的mime类型的定义,mime.types
即指$NGINX_HOME/conf/mime.types
配置文件。
default_type
指明了如果需要解析的文件类型不在上述的mime.types
列表的话,将采用默认的解析方式,此处的application/octet-stream
表示二进制流。
log_format
定义了日志格式,标识为main
,跟access_log
中的main
对应。即access_log
的日志格式将采用log_format
的定义。
sendfile
用于开启高效的文件传输模式,将tcp_nopush
和tcp_nodelay
设置为on
用于防止网络阻塞。
server {
listen 28888;
server_name 10.179.161.233;
root html;
index index.html;
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
#charset utf-8;
#access_log logs/host.access.log main;
}
listen
指明服务端的监听端口。
server_name
用来指明IP或者域名,多个IP或者域名要使用空格
分隔。
假设现在有一系统,提供了两个服务模块---API
和DOCS
,分别提供API查询和在线资料帮助。服务域名为www.adonia.org
。那么正常情况下,访问两个服务的URI会分别为http://www.adonia.org/api
和http://www.adonia.org/docs
。
但是,为了方便区分,想要通过http://api.adonia.org
访问API
系统,通过http://docs.adonia.org
访问DOCS
系统。怎么处理呢?
先来建立模拟服务,在Nginx的安装目录下创建server
目录,作为模拟服务的根目录,其下包括api
和docs
目录,分别表示上述两个服务。如下:
/opt/nginx
|--server
|--api
|--index.html
\--docs
|--index.html
api/index.html
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API</title>
</head>
<body>
<h2>API Page</h2>
</body>
</html>
docs/index.html
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOCS</title>
</head>
<body>
<h2>DOCS Page</h2>
</body>
</html>
在server
目录下启动http-server
,即可通过http://10.179.161.233:8080/api
和http://10.179.161.233:8080/docs
访问两个服务了(10.179.161.233
为测试环境IP,8080
为http-server的默认端口)。
当然,这个结果只是为了测试模拟服务是可用了,那下面看下如何通过Nginx来达到上述的目的。(http-server
可以关闭了)
先看下未加入任何主机的nginx.conf
的配置,如下:
#user nobody;
worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
}
为了方便管理主机,将新增的两个主机配置放到单独的文件中,分别为api.nginx.conf
和docs.nginx.conf
,两者类似。api.nginx.conf
的配置如下:
server {
listen 8080; # 服务端监听端口,由于Nginx不是root用户执行的,无法使用80端口
server_name api.adonia.org; # 服务端监听地址,即预期的服务访问地址
index index.html;
access_log log/api.access.log main; # 访问日志,'main'为日志格式,在'nginx.conf'中定义的
error_log log/api.error.log error; # 错误日志,注意此处的'error'为日志级别
location / {
root server/api; # 请求资源所在的根目录,如果是相对路径,则是相对于Nginx的安装目录
index index.html; # 默认页面
}
}
要使上述配置生效,还需将其引入至nginx.conf
中。将api.nginx.conf
保存在$NGINX_HOME/conf
目录,即与nginx.conf
同目录。在nginx.conf
的http
模块配置中增加如下配置:
include api.nginx.conf;
重启Nginx服务---nginx -s reload
。
由于api.adonia.org
域名是自定的,需要手动增加映射,在Nginx所在机器的/etc/hosts
中增加如下配置:
10.179.161.233 api.adonia.org
10.179.161.233
为Nginx服务器IP。
此处,通过curl api.adonia.org:8080
应该就可以访问到server/api/index.html
资源文件了。
那在Windows端如何测试呢?同样也需要增加域名映射,在C:\Windows\System32\drivers\etc\hosts
中增加:
10.179.161.233 api.adonia.org
在浏览器中输入http://api.adonia.org:8080/api
,应该就可以呈现下面的内容:
API Page
docs.nginx.conf
的配置如下,操作同api
:
server {
listen 8080;
server_name docs.adonia.org; # 服务端监听地址
index index.html;
access_log log/api.access.log main;
error_log log/api.error.log error;
location / {
root server/docs; # 请求资源根路径
index index.html;
}
}
nginx.conf
的最终配置如下:
#user nobody;
worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include api.nginx.conf;
include docs.nginx.conf;
}
注意http
模块的配置即可。
先说下正向代理,即代理,就如同在浏览器中设置的代理服务器。比如客户端(ClientA)要请求服务端(ServerB)的资源,但是ClientA和ServerB的网络不通。这时候,就需要有个代理服务器(ServerC),能够同时与ClientA和ServerB通信。
示例如下:
ClientA ServerB ServerA
| /api | /api |
|--------------->|---------------->|
| Response | Response |
|<---------------|<----------------|
| | |
而反向代理则相反,比如客户端(ClientA)要请求服务端(ServerB)的资源(/api),但是ServerB并没有该资源。于是ServerB就向第三方服务(ServerC)请求,而这一请求动作,ClientA是不感知的。ServerB把从ServerC得到的响应信息转发给ClientA。
基于上面的两个服务(API
和DOCS
),新增服务(www.adonia.org
),访问其下的不同路径,反向代理到上述的两个服务上。如下:
http://www.adonia.org/api ---> http://api.adonia.org
http://www.adonia.org/docs ---> http://docs.adonia.org
在$NGINX_HOME/conf
下增加主机配置adonia.nginx.conf
,内容如下:
server {
listen 8081; # 服务监听端口,为了与上述服务区分,特意设置不一样的端口
server_name www.adonia.org; # 服务监听地址
access_log log/adonia.access.log main;
error_log log/adonia.error.log error;
index index.html;
location /api {
proxy_pass http://api.adonia.org:8080/; # 反向代理服务地址
}
location /docs {
proxy_pass http://docs.adonia.org:8080/;
}
}
在nginx.conf
的http
模块引用上述主机配置:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include api.nginx.conf;
include docs.nginx.conf;
include adonia.nginx.conf;
}
重启Nginx---nginx -s reload
。访问http://www.adonia.org:8081/api
,应该可以得到如下响应:
API Page
注意域名映射。
需要特别说明下反向代理服务地址的配置,如下:
location /api {
proxy_pass http://api.adonia.org:8080/; # 反向代理服务地址
}
我们在定义api
服务时,访问的请求是http://api.adonia.org:8080
,但是配置反向代理时,一定不能遗漏了最后的/
,因为这个表示访问的是API
服务的根路径资源,再根据api.nginx.conf
的配置,请求将加载/api/index.html
。如果不加上/
,Nginx会自动拼接上此处定义的location
信息,最终访问的请求就变成了http://api.adonia.org:8080/api
,将加载的资源则是server/api/api
,就会报404 Not Found
的错误了。
2016/05/18 16:39:11 [error] 83404#0: *39 open() "/opt/nginx/server/api/api" failed (2: No such file or directory), client: 10.179.161.233, server: api.adonia.org, request: "GET /api HTTP/1.0", host: "api.adonia.org:8080"
在集群场景下,需要根据使用的场景来配置不同的请求分发策略,就涉及到负载均衡的配置。
Nginx中的使用upstream
模块来实现负载均衡的配置的,配置样例如下:
upstream servers{
ip_hash;
server 192.168.12.1:80;
server 192.168.12.2:80 down;
server 192.168.12.3:8080 max_fails=3 fail_timeout=20s;
server 192.168.12.4:8080;
}
Note:
servers
为定义的负载均衡器的名称,可以任意指定。
ip_hash
是一种负载均衡算法。
server
则为后端服务器信息。
Nginx的负载均衡模块目前支持4种调度算法:
在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:
注意 当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
现在模拟集群场景,包括两个集群节点---10.179.161.233
和10.135.13.1
,分别使用http-server
加载之前模拟服务的api
和docs
,不过这里要稍作下修改,以便区分是哪个集群节点上的资源。如下:
10.179.161.233/api/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API</title>
</head>
<body>
<h2>API Page In 10.179.161.233</h2>
</body>
</html>
10.135.13.1/api/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API</title>
</head>
<body>
<h2>API Page In 10.135.13.1</h2>
</body>
</html>
分别在两台机器上加载服务,http-server -p 8082
。此处,由于Nginx也运行在10.179.161.233
上,为了防止两者的端口冲突,将模拟服务的端口设置为8082
。此时,访问http://10.179.161.233:8082/api
和http://10.135.13.1:8082/api
,应该都是能够得到对应的响应信息的。
在$NGINX_HOME/conf
下增加负载均衡配置---upstream.nginx.conf
,内容如下:
upstream api{
server 10.135.13.1:8082 weight=1; # 集群节点1
server 10.179.161.233:8082 weight=2; # 集群节点2
}
server{
listen 8080; # 服务监听端口
server_name 10.179.161.233; # 服务监听地址
access_log log/upstream.access.log main;
error_log log/upstream.error.log error;
location / {
proxy_pass http://api; # 请求反向代理至集群列表
proxy_set_header X-Real-IP $remote_addr;
}
}
将负载均衡配置引入至Nginx的http
模块,如下:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include upstream.nginx.conf;
#include api.nginx.conf;
#include docs.nginx.conf;
#include adonia.nginx.conf;
}
重启Nginx服务---nginx -s reload
。访问http://10.179.161.233:8080/api
,持续刷新,响应结果应该会一直在下面两个中切换:
API Page In 10.179.161.233
API Page In 10.135.13.1
而且,API Page In 10.179.161.233
出现的概率为 2/3
。
如果把上述的负载均衡算法设置为ip_hash
的话,配置如下:
upstream api{
ip_hash;
server 10.135.13.1:8082;
server 10.179.161.233:8082;
}
server{
listen 8080;
server_name 10.179.161.233;
access_log log/upstream.access.log main;
error_log log/upstream.error.log error;
location / {
proxy_pass http://api;
proxy_set_header X-Real-IP $remote_addr;
}
}
访问http://10.179.161.233:8080/api/
,持续刷新,会发现响应结果是不变的。注意: 使用ip_hash
算法,就不建议再配置weight
了。
Nginx Rewrite模块负责URL重写,主要用于同一服务器内的资源重定向。语法格式如下:
rewrite regex replacement flag
regex
为资源的正则匹配
replacement
为重定向后的资源路径
flag
为重定向标记
flag
包括:
last
: url重写后,会发起新的请求,重新进入'server'模块,进行location匹配,如果匹配超过10次扔不成功,则报500错误,地址栏url不变。
break
: url重写后,直接使用当前资源,不再执行location余下语句,完成本次请求,地址栏url不变。
redirect
: 返回302临时重定向,url会跳转,爬虫不会更新url。
permanent
: 返回301永久重定向。url会跳转。爬虫会更新url
空值
: URL 不会变,但是内容已经变化,也是永久性的重定向。
在$NGINX_HOME/html
目录下增加文本文件,如下:
/opt/nginx
|--html
|--index.html
\--50x.html
\--file
|--a.txt
html/file/a.txt
为简单文本文件,内容如下:
text a
按照Nginx默认的主机配置的话,访问http://10.179.161.233:8080/file/a.txt
应该就可以显示上述文本内容。
Note:
10.179.161.233
为Nginx测试机器的IP。
现在更改下规则,想要在访问根路径下的资源文件时,能够被重定向至file
目录下。比如访问http://10.179.161.233:8080/a
,实际加载的是html/file/a.txt
文件。
如何配置呢?
在$NGINX_HOME/conf
下新增rewrite.nginx.conf
,内容如下:
server{
listen 8080;
server_name 10.179.161.233;
location / {
root html;
index index.html;
rewrite '^(.+)$' /file/$1.txt break;
}
}
在nginx.conf
的http模块中引入rewrite.nginx.conf
配置,如下:
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include rewrite.nginx.conf;
}
重启Nginx---nginx -s reload
,访问http://10.179.161.233:8080/a
,应该就能得到如下的响应结果:
text a
按照上述的配置,所有以"/"开头的请求就将被重写,包括Nginx的默认首页index.html
,访问http://10.179.161.233:8080
,得到的是404 Not Found
。查看错误日志:
2016/05/19 14:15:49 [error] 44662#0: *33 open() "/opt/nginx/html/file//.txt" failed (2: No such file or directory), client: 10.135.13.1, server: 10.179.161.233, request: "GET / HTTP/1.1", host: "10.179.161.233:8080"
那像这种情况,如果针对指定的uri,不想让请求被重写,而是按照原先的逻辑路由,怎么配置呢?
在server
和location
模块,支持if
判断指令。语法为if(condition){...}
,对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
下面是可以用作if判断的全局变量:
$args
: #这个变量等于请求行中的参数,同$query_string
$content_length
: 请求头中的Content-length字段。
$content_type
: 请求头中的Content-Type字段。
$document_root
: 当前请求在root指令中指定的值。
$host
: 请求主机头字段,否则为服务器名称。
$http_user_agent
: 客户端agent信息
$http_cookie
: 客户端cookie信息
$limit_rate
: 这个变量可以限制连接速率。
$request_method
: 客户端请求的动作,通常为GET或POST。
$remote_addr
: 客户端的IP地址。
$remote_port
: 客户端的端口。
$remote_user
: 已经经过Auth Basic Module验证的用户名。
$request_filename
: 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme
: HTTP方法(如http,https)。
$server_protocol
: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr
: 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name
: 服务器名称。
$server_port
: 请求到达服务器的端口号。
$request_uri
: 包含请求参数的原始URI,不包含主机名,如:"/foo/bar.php?arg=baz"。
$uri
: 不带请求参数的当前URI,$uri不包含主机名,如"/foo/bar.html"。
$document_uri
: 与$uri相同。
那么,针对上述情况,就可以处理为: 如果请求路径是"/",则按照默认的路由规则,被映射到"/index.html",如下:
location =/ {
root html;
index index.html;
}
N.B.: 注意此处的
=
,这里表示路径的精确匹配。
重载Nginx,再试下访问http://10.179.161.233:8080
,发现响应依旧是404 Not Found
,查看错误日志:
2016/05/19 14:17:34 [error] 44789#0: *37 open() "/opt/nginx/html/file//index.html.txt" failed (2: No such file or directory), client: 10.135.13.1, server: 10.179.161.233, request: "GET / HTTP/1.1", host: "10.179.161.233:8080"
原来,请求被location =/
匹配后,uri被映射为/index.html
,之后请求又被location /
匹配,请求被重写为/file/index.html.txt
。
那就需要在location /
加个判断逻辑,过滤*.html
的请求,不做任何处理。如下:
server{
listen 8080;
server_name 10.179.161.233;
location =/ {
root html;
index index.html;
}
location / {
root html;
if ($uri ~ "\.html$") {
break; # 如果请求以'html'结尾,则不做处理
}
rewrite '^(.+)$' /file/$1.txt break;
}
}
重载之后,应该就可以正常访问了。
前面介绍到rewrite的语法为: rewrite regex replacement flag
,其中flag
包括last
、break
、redirect
和permanent
。那看下上述场景,分别使用几种标识得到的结果是什么。
空值
,响应为"500 Internal Server Error",错误日志如下:
2016/05/19 14:34:13 [error] 45836#0: *43 rewrite or internal redirection cycle while processing "/file//file//file//file//file//file//file//file//file//file//file//a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt", client: 10.135.13.1, server: 10.179.161.233, request: "GET /a HTTP/1.1", host: "10.179.161.233:8080"
last
,响应为"500 Internal Server Error",错误日志如下:
2016/05/19 14:39:06 [error] 46165#0: *1 rewrite or internal redirection cycle while processing "/file//file//file//file//file//file//file//file//file//file//file//a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt", client: 10.135.13.1, server: 10.179.161.233, request: "GET /a HTTP/1.1", host: "10.179.161.233:8080"
redirect
,请求地址栏的uri为http://10.179.161.233:8080/file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt
,access.log
中的信息为:
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//a.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//file/a.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//file/file/a.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//file/file/file/a.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//file/file/file/file/a.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:27 +0800] "GET /file//file/file/file/file/file/a.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
10.135.13.1 - - [19/May/2016:14:40:28 +0800] "GET /file//file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/file/a.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt.txt HTTP/1.1" 302 161 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
permanent
, 响应结果同redirect
从上述结果也可以看出,last
并没有阻止继续执行location
匹配;而break
可以防止上述匹配的情况,直接使用rewrite
后的资源。
permanent
和redirect
都会改变地址栏中的请求路径,最终导致匹配次数超过10次,服务端报出'500'的错误。浏览器中也显示重定向的次数过多。