Nginx的配置指令执行的顺序 11 个阶段

作者&投稿:淳羽 (若有异议请与网页底部的电邮联系)
~ Nginx的配置指令执行不是按照配置的先后顺序执行,二十分为11 个阶段post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log , Nginx配置文件中的所有指令是按照上面11个阶段的顺讯执行。

set_real_ip_from的值可以是一个ip,也可以是一个ip段,表示当请求是某一个ip时,使用real_ip_header的值替换 realip_remote_addr 和 realip_remote_port中。

运行命令

查看日志其中的remote_addr 已经改为 192.2.2.2,而 $realip_remote_addr 是127.0.0.1。 当Header IP是非法的IP地址,则remote_addr 不改变。
** 注意 real_ip_header 的默认值为 X-Real-IP

下面我们着重看一下 real_ip_recursive(默认值为off)
1) real_ip_header 的http header中仅有一个ip时,则直接替换remote_addr。
2) real_ip_header 的http header 中有多个ip时
- real_ip_recursive 为off时, 则用第一个ip替换remote_addr
- real_ip_recursive 为on时, 则用第一个不在set_real_ip_from 的ip替换remote_addr
例如nginx配置如下:

请求命令为

remote_addr 被替换为 192.168.2.3 (注意这里的顺序是从右至左)。当real_ip_recursive为off时 remote_addr被替换为 192.178.2.2

例如nginx有以下配置

访问/first之后,日志中输出 Hello world; 这是因为 set $b "Hello"; 定义在server模块下,所以在server-rewrite阶段已经执行。所以在location块中定义的才能执行的结果才是正确的。
后面再rewrite阶段会详细讲解这几个命令。

下面我们详细看一下ngx_rewrite中的7个指令:
1) rewrite (基本语法: rewrite regex replacement [flag]; 可以配置在server,location和if配置块下)
regex是RCPE风格的,如果regex匹配URI,nameURI就会被替换成replacement,replacement就是新的URI,如果同一个配置块下有多个rewrite配置指令,匹配并不会终止,而是继续用新的URI(也就是上一次匹配到的replacement)继续进行匹配,直至返回最后一个匹配。如果在匹配到之后想要停止匹配直接返回,可是使用flag参数(将其设置为break)。

注意 : 如果匹配到replacement中有关于协议的东西,例如http://或者https://等,处理将终止,直接返回客户端302(Temporary redirect)。
如果Nginx返回给客户端30x,浏览器在接收到这个状态码时,会根据response中的Location响应头再发起一次请求;如果不是30x状态码,所有的跳转只是在nginx内部完成,有兴趣的可以将nginx的日志调为debug看一下整个跳转过程。
举一个例子

当请求 curl -I http://localhost:8080/first 时,nginx接到请求之后,匹配到/first 根据第一个rewrite指令,将URI替换为/test, 然后继续执行第二个rewrite指令,将URI替换为/index.html,之后继续执行第三个指令,返现regex(/test)与新的URI(/index.html)并不匹配,所以最终我们将会看到index.html的返回结果。开启debug日志,可以看到详细的跳转过程。

再举一例

当请求 curl -I http://localhost:8080/first 时,首先会执行server块下的rewrite,所有请求都返回302 (Location: https://127.0.0.1:8080/first )。

下面讲一下rewrite的第三个参数flag:
1.1 ) last
如果有last参数,那么停止处理任何rewrite相关的指令,立即用替换后的新URI开始下一轮的location匹配。

1.2) break
停止处理任何rewrite的相关指令,就如同break 指令本身一样。

last的break的相同点在于,立即停止执行所有当前上下文的rewrite模块指令;不同点在于last参数接着用新的URI马上搜寻新的location,而break不会搜寻新的location,直接用这个新的URI来处理请求,这样能避免重复rewite。因此,在server上下文中使用last,而在location上下文中使用break。

1.3) redirect
replacement 如果不包含协议,仍然是一个新的的URI,那么就用新的URI匹配的location去处理请求,不会返回30x跳转。但是redirect参数可以让这种情况也返回30x(默认302)状态码,就像新的URI包含http://和https://等一样。这样的话,浏览器看到302,就会再发起一次请求,真正返回响应结果的就是这第二个请求

1.4) permanent
和redirect参数一样,只不过直接返回301永久重定向

虽说URI有了新的,但是要拼接成完整的URL还需要当前请求的scheme,以及由server_name_in_redirect和port_in_redirect指令决定的HOST和PORT.

还有一个比较有意思的应用,就是如果replacement中包含请求参数,那么默认情况下旧URI中的请求参数也会拼接在replacement后面作为新的URI,如果不想这么做,可以在replacement的最后面加上?。

2) break (基本语法: break; 可以配置在server,location 和if配置块下)
停止任何处理rewrite的相关指令。如果出现在location里面,name所有后面的rewrite模块都不会执行,也不发起内部重定向,而是直接用新的URI处理请求。
例如有如下配置

访问 curl -I http://localhost:8080/server/break ,将返回404;
请求 curl -I http://localhost:8080/server/last 将返回index.html
访问 curl -I http://localhost:8080/hello ,将返回 404;
请求 curl -I http://localhost:8080/hello1 ,将返回index.html。

综合以上的实验,可以肯定的是在server中配置块中如果使用break指令,下面所有的location将不会执行,而last会进行下一次内部跳转。location中的break则是直接退出,返回URI的结果; last 进入下一次内部跳转,该location内的rewrite配置指令不再执行。

3) if (基本语法:if(condition) {....}) 可以配置在server和location配置块中
根据condition是true和false决定是否加载 花括号中的配置,花括号中的配置可以继承外面的配置,也可以对外面的指令进行重写。
condition 可以是自定义变量或者系统变量本身,也可以是表达式:
a. condition 为变量本身时, 0: false 非0 : true
b. 变量可以通过"=" 、"!=" 与字符串比较
c. 匹配正则表达式 ~ !~ (大小写敏感) ~* !~* (大小写不敏感)
d. -f -d -e -x !-f !-d !-e !-x 等检验文件或者目录存在或者文件属性

4) return (基本语法: return code [text]; return code URL; return URL; 可以配置在server,location和if配置块中)
停止任何的进一步处理,并且将指定状态码返回给客户端。如果状态码为444(此状态码是非标准的),那么直接关闭此TCP连接。

return的参数有四种形式:

5) set (基本语法: set $var value; 可以配置在server,location和if配置块中)
这个指令可以用来自定义变量,也可以改变系统变量的值。

6) rewrite_log (基本语法: rewrite_log on | off; 可以配置在http,server,location和if配置块中)
如果开启on,name当rewrite时,会产生一个notice基本的日志;否则不产生日志。可以在调试的时候将其设置为on。

请求 curl -I http://localhost:8080/first 时,先找到 /first location,在 /first location中rewrite URI 为/index.html进入post-rewrite阶段,进行一次内部跳转,回到find-config阶段,使用新的/index.html做为URI重新匹配location至 location / 。
这里有一个问题,为什么不在rewrite阶段执行内部跳转?答案就是为了在一个location中支持反复改写URI。试想一下如果有以下配置。

如果在rewrite阶段直接做内部跳转,那么 第二个rewrite将不能执行,我们必须再声明一个 /second location进行URI 重写。
想证实这一点很简单,我们做一个简单的例子:

请求 curl http://localhost:8080/first 之后将得到 "third content"相应值,同时可以在日志中看到如下日志。

注意一下,server配置块下的rewrite命令在server-rewrite阶段执行。

nginx限制请求是一个比较复杂的模块,后面会单独解说。

在接口/post_access 中同时配置了ngx_access 和ngx_lua两个模块,这样access阶段就由两个模块一起检查,其中deny all 会让ngx_access模块处理程序拒绝当前请求,而语句access_by_lua 'ngx.exit(ngx.OK)' ; 则总是允许访问。当satify指令为all时,当前的请求会被拒绝,返回403(forbidden)。


nginx如何丢弃指定ip的请求
在 server 或 location 块中添加以下代码:markdownCopy codelocation \/ { deny 192.168.1.100;}这里的 192.168.1.100 就是要禁止访问的 IP 地址。你可以在 deny 指令中指定多个 IP 地址,以空格分隔。重启 Nginx 服务器,使配置文件生效。rubyCopy code$ sudo systemctl restart nginx现在,...

nginx的root和alias指令的区别
location \/img\/ { alias \/var\/www\/image\/;} 若按照上述配置的话,则访问\/img\/目录里面的文件时,nginx会自动去\/var\/www\/image\/目录找文件 location \/img\/ { root \/var\/www\/image;} 若按照这种配置的话,则访问\/img\/目录下的文件时,nginx会去\/var\/www\/image\/img\/目录下找文件。]alias是一个...

nginx的root和alias指令的区别
root和alias的最基本的区别是:root指定的目录可以做为根目录,可以定位到里面的其他目录;而alias则指定的目录是准确的 其中alias的一个应用可以是,如果希望把不在root下的文件要能让web访问的到 下面用实际例子说明root和alias的区别:[java] view plain copy location ~ .*\\.jsp$ { alias \/test...

nginx配置完 并发了还是上不去
备注:ulimit 命令本身就有分软硬设定,加-H 就是硬,加-S 就是软预设显示的是软限制 soft 限制指的是当前系统生效的设定值。 hard 限制值可以被普通使用者降低。但是不能增加。 soft 限制不能设定的比 hard 限制更高。 只有 root 使用者才能够增加 hard 限制值。 五、下面是一个简单的nginx 配置档案: user...

nginx的root和alias指令的区别
还是看范例最明了 location \/img\/ { alias \/var\/www\/image\/;} 若按照上述配置的话,则访问\/img\/目录里面的文件时,nginx会自动去\/var\/www\/image\/目录找文件 location \/img\/ { root \/var\/www\/image;} 若按照这种配置的话,则访问\/img\/目录下的文件时,nginx会去\/var\/www\/image\/img\/目录下找...

nginx配置listen和不配置的区别
listen指令的默认值是任何IP的80端口 如果不配置listen,则监听的是本机所有IP的80端口 如果配置listen,则监听按配置中所示的IP和端口

高并发nginx,需要注意哪些配置
2. worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;为每个进程分配cpu,上例中将8 个进程分配到8 个cpu,当然可以写多个,或者将一个进程分配到多个cpu。3. worker_rlimit_nofile 65535;这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值...

请求怎么匹配到nginx配置的servername
nginx中的server_name指令主要用于配置基于名称虚拟主机,server_name指令在接到请求后的匹配顺序分别为:1、准确的server_name匹配,例如:server { listen 80;server_name frady.info www.frady.info; ...} 2、以*通配符开始的字符串:server { listen 80;server_name *.frady.info;....

Nginx给客户返回的是自身ip吗?
在这个过程中,客户端无法直接访问后端服务器,而是通过Nginx服务器进行转发。因此,Nginx会将自己的IP地址作为服务器的地址返回给客户端。当然,如果您在Nginx配置中指定了proxy_set_header指令,可以修改返回给客户端的服务器地址。例如,您可以使用以下指令将服务器地址设置为指定的IP地址:```proxy_set_...

nginx中的“pid”是什么?
还可以通过在nginx的配置文件中修改。如下:\\x0d\\x0apid \/data\/test\/nginx.pid;\\x0d\\x0a这里修改的值只对使用该配置文件的nginx有效。\\x0d\\x0a用PID文件停止Nginx\\x0d\\x0a假设pid文件路径为\/data\/logs\/nginx.pid\\x0d\\x0akill _QUIT `cat \/data\/logs\/nginx.pid`\\x0d\\x0a用pid...

海口市17334809686: 请求怎么匹配到nginx配置的servername -
申哀复方: nginx中的server_name指令主要用于配置基于名称虚拟主机,server_name指令在接到请求后的匹配顺序分别为:1、准确的server_name匹配,例如: server {listen 80;server_name frady.info www.frady.info;... }2、以*通配符开始的字符串: ...

海口市17334809686: nginx如何处理一个请求 -
申哀复方: Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始:server { listen 80; server_name example.org www.example.org; ... }server { listen 80; server_name example.net www....

海口市17334809686: Nginx中的正则如何匹配数字 -
申哀复方: Nginx中的正则匹配数字:1、正则表达式匹配 ~ 区分大小写匹配 ~* 不区分大小写匹配!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 ^ 以什么开头的匹配$ 以什么结尾的匹配 转义字符.可以转. * ?等* 代表任意字符2、文件及目录匹...

海口市17334809686: nginx配置文件中怎么把hostname的值赋给其它变量 -
申哀复方: Nginx 的配置文件使用的就是一门微型的编程语言,许多真实世界里的 Nginx 配置文件其实就是一个一个的小程序.当然,是不是“图灵完全的”暂且不论,至少据我观察,它在设计上受 Perl 和 Bourne Shell 这两种语言的影响很大.在这一点上...

海口市17334809686: 请问nginx.conf的执行过程(执行顺序),以及和include vhost/*. -
申哀复方: 回复 1# 的帖子 先nginx.conf,再include

海口市17334809686: nginx location优先级高低 -
申哀复方: location本身存优先级按顺序右及依执行说定义相同条件location两先执行面再执行面举例 location ~ /abc/ { ... } 面 location ~/abc/.+\.jpg {....} url /abc/依贰三.jpg 满足两条件先执行面执行

海口市17334809686: 如何在windows上配置并运行Nginx -
申哀复方: 1、下载nginx稳定版2、解压nginx.zip,将解压后的目录移动到指定要求目录,如c:\nginx3、进到该目录去,nginx.exe是nginx启动程序,conf是nginx一些配置文件目录,其中nginx.conf是nginx主配置文件4、编辑主配置文件nginx.conf#表示注释 ...

海口市17334809686: 重启nginx服务器用哪个指令比较好 -
申哀复方: nginx -s reload :修改配置后重新加载生效 nginx -s reopen :重新打开日志文件 nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确关闭nginx: nginx -s stop :快速停止nginxquit :完整有序的停止nginx其他的停止nginx 方式...

海口市17334809686: window8怎么配置nginx -
申哀复方: 工具原料:电脑+win8+php环境 window8配置nginx方法如下: 1、首先需要准备的应用程序包. nginx:nginx/Windows-1.0.4php:php-5.2.16-nts-Win32-VC6-x86.zip (nginx下php是以FastCGI的方式运行,所以我们下载非线程安全也就是nts的php...

海口市17334809686: php和nginx安装后怎么配置 -
申哀复方: 先安装编译依赖的一些组件 复制代码 代码如下:yum install pcre pcre-devel openssl openssl-devel -y1、解压程序包 复制代码 代码如下:tar xf nginx-1.10.0.tar.gz cd nginx-1.10.02、预编译配置参数 复制代码 代码如下:./configure --user=www \--...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网