Skip to content

Commit 8d026dd

Browse files
committed
find-config 阶段阶段运行时间早于 rewrite 阶段执行
1 parent c5231c7 commit 8d026dd

File tree

2 files changed

+221
-5
lines changed

2 files changed

+221
-5
lines changed

Nginx-Develop/command-order-01.md

+124-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,127 @@
2525
```
2626
+ 两个命令 设置在执行阶段`rewrite`,两个命令 回声在随后阶段执行`content`。不同阶段的命令无法执行。
2727
28-
+ Lua 脚本变量 ` ngx.var.remote_addr` = Nginx的的内建变量 ` $REMOTE_ADDR`
28+
+ Lua 脚本变量 ` ngx.var.remote_addr` = Nginx的的内建变量 ` $REMOTE_ADDR`
29+
## Nginx指令执行命令(05)
30+
+ 多个命令的执行顺序
31+
+ 顺序: ` rewrite phase `=> `access phase` => `content phase`
32+
```
33+
location /test_rewrite_access_content {
34+
# rewrite phase
35+
set $age 1;
36+
rewrite_by_lua_block {
37+
ngx.var.age = ngx.var.age + 1
38+
}
39+
40+
# access phase
41+
deny 10.32.168.49;
42+
access_by_lua_block {
43+
ngx.var.age = ngx.var.age * 3
44+
}
45+
46+
#content phase
47+
echo "age = $age";
48+
}
49+
```
50+
+ 测试结果
51+
```
52+
# curl http://127.0.0.2:8008/test_rewrite_access_content
53+
age = 6
54+
55+
```
56+
+ 执行顺序结论
57+
> [1] 由ngx_rewrite模块 实现的命令 集同步执行rewrite。模块 ngx_lua的命令 rewrite_by_lua在阶段结束时执行
58+
59+
> [2] 模块 ngx_access的命令被 拒绝同步执行。模块 ngx_lua的命令 access_by_lua在阶段结束时执行。
60+
61+
> [3] 最后,我们最喜欢的命令 echo,由ngx_echo模块实现 ,执行阶段。
62+
63+
> [4] 最后的执行顺序:rewrite access access content
64+
65+
+ 命令` set `集和命令 `rewrite_by_lua ` 都属于阶段 `rewrite`
66+
+ 命令` deny `集和命令 `access_by_lua ` 都属于阶段 `access`
67+
+ 命令` set `集和命令 `rewrite_by_lua ` 都属于阶段 `rewrite`
68+
+ 下面的这样写是错误的 XXXXXXXXXX
69+
+ 错误写法?????
70+
```
71+
? location /test {
72+
? content_by_lua 'ngx.say("hello")';
73+
? content_by_lua 'ngx.say("world")';
74+
? }
75+
```
76+
+ 不是每个模块都支持在一个内部执行多次命令location。命令 content_by_lua为一个实例,只能使用一次
77+
+ 正确写法
78+
```
79+
location /test {
80+
content_by_lua 'ngx.say("hello") ngx.say("world")';
81+
}
82+
```
83+
+ 而不是使用content_by_lua两次 命令location,方法是在Lua代码中调用函数 ngx.say两次,该代码由命令content_by_lua执行
84+
+ 模块 ngx_proxy的命令 proxy_pass不能与一个中的命令echo共存, 因为它们都在同步执行
85+
+ 错误写法!!!!!!!!!
86+
```
87+
? location /test {
88+
? echo "before...";
89+
? proxy_pass http://127.0.0.1:8080/foo;
90+
? echo "after...";
91+
? }
92+
?
93+
? location /foo {
94+
? echo "contents to be proxied";
95+
? }
96+
```
97+
+ 测试结果
98+
```
99+
$ curl 'http://localhost:8080/test'
100+
contents to be proxied
101+
```
102+
+ 结论:该示例尝试在模块ngx_proxy返回其内容之前和之后 输出字符串"before..."和"after..."命令 echo。但是只有一个模块可以执行。测试表明模块 ngx_proxy获胜并且命令 echo来自模块 ngx_echo永远不会运行 content
103+
+ 为了实现这个例子想要的,我们将使用模块ngx_echo, echo_before_body和 echo_after_body提供的另外两个命令
104+
```
105+
location /test {
106+
echo_before_body "before...";
107+
proxy_pass http://127.0.0.1:8080/foo;
108+
echo_after_body "after...";
109+
}
110+
111+
location /foo {
112+
echo "contents to be proxied";
113+
}
114+
```
115+
+ 反向代理:可以看出反向代理前和反向代理后的结果
116+
+ 案例
117+
```
118+
location /echo_test {
119+
echo_before_body "before...";
120+
proxy_pass http://127.0.0.1:8008/tinywan;
121+
echo_after_body "after...";
122+
}
123+
location /tinywan {
124+
echo "contents to be proxied";
125+
}
126+
127+
```
128+
+ 测试结果
129+
```
130+
root@tinywan:/opt/openresty/nginx/conf# curl http://127.0.0.2:8008/echo_test
131+
before...
132+
contents to be proxied
133+
after...
134+
```
135+
+ 命令echo_before_body和 echo_after_body可以与其他模块同步共存的原因 content是,它们不是Nginx的“内容处理程序”,而是“输出过滤器”
136+
## Nginx指令执行命令(06)
137+
+ 当一个命令在 ` content ` 一个特定的阶段执行时 ` location `,通常意味着它的Nginx模块注册了一个 ` 内容处理程序 (content handler)`
138+
+ 没有模块将其命令注册为“内容处理程序”时候,将获得产生内容和产出回应是静态资源模块,它将请求URI映射到文件系统。只有当没有“内容处理程序”时,静态资源模块才会发挥作用,否则它将“责任”移交给“内容处理程序”
139+
+ Nginx有三个静态资源模块用于该content阶段( 按照执行顺序排列 )
140+
+ (1) `ngx_index` 模块
141+
+ (2) `ngx_autoindex` 模块
142+
+ (3) ` ngx_static ` 模块
143+
+ ngx_index和 ngx_autoindex模块 仅适用于那些以URI为结尾的请求URI /。对于不以其他方式结束的其他请求URI /,两个模块都将忽略它们,并让以下content阶段模块处理。ngx_static然而,模块具有完全相反的策略。它忽略结束的请求URI /并处理其余的
144+
+ 模块 ngx_index主要查找特定的主页文件,如文件系统index.html或index.htm文件系统
145+
```
146+
location / {
147+
root /var/www/;
148+
index index.htm index.html;
149+
}
150+
```
151+
+ 当地址 `/ ` 请求,Nginx的查找文件 ` index.htm `,并 `index.html` 在文件系统中的路径(按照这个顺序)。路径由命令 根目录指定。如果文件 `index.htm` 存在,Nginx内部跳转到位置 `index.htm`; 如果不存在并且文件 ` index.html` 存在,Nginx将内部跳转到位置`index.html`。如果文件 `index.html` 不存在,并且处理转移到同步执行命令的其他模块 `content`

Nginx/nginx-phases.md

+97-4
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,101 @@
1616
| NGX_HTTP_TRY_FILES_PHASE | HttpLogModuel / access_log |日志模块处理阶段|
1717

1818
+ 各个phase说明
19-
+ post read phase
20-
> nginx读取并解析完请求头之后就进入了post_read 阶段,它位于uri被重写之前,这个阶段允许nginx改变请求头中ip地址的值,相关模块HttpRealIpModule
19+
+ (1) post read phase
20+
> `post-read ` 属于 `rewrite`阶段
21+
22+
> `post-read` 支持Nginx模块的钩子
23+
24+
> 内置模块 `ngx_realip` 把它的处理程序`post-read`分阶段挂起,强制重写请求的原始地址作为特定请求头的值
25+
26+
```
27+
server {
28+
listen 8080;
29+
30+
set_real_ip_from 127.0.0.1;
31+
real_ip_header X-My-IP;
32+
33+
location /test {
34+
set $addr $remote_addr;
35+
echo "from: $addr";
36+
}
37+
}
38+
```
39+
40+
> 该配置告诉Nginx强制将每个请求的原始地址重写127.0.0.1为请求头的值X-My-IP。同时它使用内置变量 `$remote_addr`来输出请求的原始地址
41+
42+
```
43+
$ curl -H 'X-My-IP: 1.2.3.4' localhost:8080/test
44+
from: 1.2.3.4
45+
```
46+
> curl 参数 -H :自定义头信息传递给服务器
47+
48+
> 该选项X-My-IP: 1.2.3.4在请求中包含一个额外的HTTP头
49+
50+
> 测试结果
51+
```
52+
$ curl localhost:8080/test
53+
from: 127.0.0.1
54+
55+
$ curl -H 'X-My-IP: abc' localhost:8080/test
56+
from: 127.0.0.1
57+
``
2158
2259
+ server_rewrite phase
23-
> 这个阶段主要进行初始化全局变量,或者server级别的重写。如果把重写指令放到 server 中,那么就进入了server rewrite 阶段。(重写指令见rewrite phase)
60+
61+
> 这个阶段主要进行初始化全局变量,或者server级别的重写。如果把重写指令放到 server 中,那么就进入了server rewrite 阶段。(重写指令见rewrite phase)
62+
63+
> ( 1 ) `server-rewrite ` 阶段运行时间早于 `rewrite` 阶段
64+
65+
```
66+
location /tinywan {
67+
set $bbb "$aaa, world";
68+
echo $bbb;
69+
}
70+
set $aaa "HELLO";
71+
```
72+
73+
> `set $a hello` 声明被放在`server`指令中,所以它运行在`server-rewrite`阶段
74+
75+
> 因此 `set $b "$a, world'" `,在location指令中执行 `set ` 指令后,它将获得正确的`$a`值
76+
77+
> 执行结果
78+
79+
```
80+
# curl http://127.0.0.2:8008/tinywan
81+
HELLO, world
82+
```
83+
> ( 2 ) `post-read` 阶段阶段运行时间早于 `server-rewrite` 阶段执行
84+
85+
```
86+
server {
87+
listen 8080;
88+
89+
set $addr $remote_addr;
90+
91+
set_real_ip_from 127.0.0.1;
92+
real_ip_header X-Real-IP;
93+
94+
location /test {
95+
echo "from: $addr";
96+
}
97+
}
98+
```
99+
100+
> ( 3 ) `ngx_realip` 阶段阶段运行时间早于 `server 的 set 指令` 阶段执行
101+
102+
```
103+
$ curl -H 'X-Real-IP: 1.2.3.4' localhost:8080/test
104+
from: 1.2.3.4
105+
```
106+
107+
> 服务器指令中的命令集始终比模块ngx_realip晚,
108+
109+
> ( 4 ) `server-rewrite` 阶段阶段运行时间早于 `find-config` 阶段执行
24110
25111
+ find config phase
112+
> ( 5 ) `find-config` 阶段阶段运行时间早于 `rewrite` 阶段执行
113+
26114
> 这个阶段使用重写之后的uri来查找对应的location,值得注意的是该阶段可能会被执行多次,因为也可能有location级别的重写指令。这个阶段并不支持 Nginx 模块注册处理程序,而是由 Nginx 核心来完成当前请求与 location 配置块之间的配对工作
27115
28116
+ rewrite phase:
@@ -59,4 +147,9 @@
59147
> 一般会在一次请求中被调用多次, 因为这是实现基于 HTTP 1.1 chunked 编码的所谓“流式输出”的,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API
60148
61149
+ log_by_lua
62-
> 该阶段总是运行在请求结束的时候,用于请求的后续操作,如在共享内存中进行统计数据,如果要高精确的数据统计,应该使用body_filter_by_lua
150+
> 该阶段总是运行在请求结束的时候,用于请求的后续操作,如在共享内存中进行统计数据,如果要高精确的数据统计,应该使用body_filter_by_lua
151+
152+
+ --with-http_realip_module 模块
153+
+ set_real_ip_from   192.168.1.0/24;     指定接收来自哪个前端发送的 IP head 可以是单个IP或者IP段
154+
+ set_real_ip_from 192.168.2.1;
155+
+ real_ip_header X-Real-IP; IP head 的对应参数,默认即可。

0 commit comments

Comments
 (0)