# 学习nginx变量[openresty]

使用set $a "hello" 创建变量

可以向php一样${a} 插入变量, nginx变量只有一种类型,即字符串

不创建变量,加载conf会失败

变量创建后,可见性是整个nginx,无论在哪个location set,其他location都可见 但是只有所在的location,能使用,其他location会视为空字符串 也就是nginx的变量生命期,是不能跨越请求边界的。

# 变量2

ngx_echo 模块和rewrite模块实现的内部跳转,location A 到location B,则A中设置的变量,b中也可见。使用的是同一套变量副本

nginx 变量的生命期和正在处理的请求绑定,与location无关

nginx set创建的用户变量, 还有nginx自己定义的内建变量: $uri..$request_uri

get参数这一系列变量时都是arg_前缀开始的,而且nginx灰板get参数统一都转成小写

一些只读的内建变量,是不允许 修改的

# 变量3

通过 set $args "foo=1&bar=2"; 可以修改get参数部分, 这是整体修改,$arg_xxx也会变

proxy_pass 之前也是可以通过set 修改$args的

# 变量4

map 会存在惰性求值(也就是为了避免重复计算,会缓存第一次得到的值)

# 变量5

内部location自请求,各自的内部都有自己的变量,一般不会和主请求共用一套变量,但是有些模块会共用

# 变量6

curl --data 选项会自动请求post方法

并非所有的内建变量都作用于当前请求,少数请求只作用于主请求, 比如$request_method(只返回父请求的方法)

ngx_echo 模块发起的子请求都禁用了父子请求之间的变量共享, 所以$request_method 获取函数是只会取(主请求的方法)

这些变量都是通过自己的get方法获取的(取值程序: 而不是直接获取变量的值) 类型java对象的get/set

通过$echo_request_method 能取到父子请求各自的请求方法

ngx_auth_request模块就是父子共享一套变量。这会很坑, 如果在main里你设置tag=1, 但是如果你在echo tag之前发起子请求,自请求设置的tag=2; namemain中echo tag也是2,而不是设置的1;

# 变量7

nginx set创建的变量,是整个文件可见的。如果在某个location中未初始化就使用: nginx取值处理程序就会默认缓存成空字符串,在error.log 中输出 using uninitialized "" varuable ....

如果压根就没有set创建,直接使用,则reload配置文件就会失败, 如果在lua中判断就是nil

如果$arg_xxx不存在,这个参数,打印的时候nginx会处理成功空字符串显示,和name=""这种就不好区分了, ngx_lua可以区分,因为参数不存在是nil; 值不存在,nginx不会打印警告,所以我们可以通过ngx_lua来捕捉这种痕迹。

# 变量8

content_by_lua指令并不支持 变量插值 比如$x;

尝试获取未初始化的 “不合法”变量,nginx就会自动调用 “取处理程序” 返回空字符串, 所以不合法这种情况,不太好捕捉。

# 执行顺序1

先执行rewrite, access,content

set指令是rewrite阶段的指令,都会先执行

echo指令是content阶段执行的

某些声明性的指令,一般没有运行阶段,当配置指令运行在content阶段,则一般会指示运行阶段。

# 执行顺序2

location中的set, rewrite指令都运行在 rewrite阶段

server中的 set, rewrite执行运行在更早的server-rewrite阶段

ngx_set_misc模块也运行在rewrite阶段,所以其包含的指令可以和ngx_rewrite模块混合在一起用。

set_by_lua 指令也可以和set这样的ngx_rewrite模块一起混用,

set_bylua $c "return ngx.var.a ngx_rewrite模块以及能和他一起混合使用的第三方都是把指令注入到ngx_rewrite执行序列中(借助了ngx_devel_kit模块)

另外一些常规的在rewrite阶段的模块,虽然也运行在rewrite阶段,但是和ngx_rewrite模块的指令是分开的,所以执行顺序不确定。

## 执行顺序3

rewrite_by_lua 是运行在 rewrite阶段的末尾, more_set_input_headers 也是rewrite末尾,二者执行顺序不固定,不应该写二者有依赖关系的配置。

rewrite_by_lua 是运行在所有set指令之后。

标准的ngx_access 运行在rewrite之后,比如allow和deny限制ip的指令, ngx_auth_request指令也是这个阶段

## 执行顺序4

ngx_lua 模块的access_by_lua指令运行在access阶段末尾.因此也是在allow。deny这样的指令之后。

ngx_access标准模块,比access_by_lua快了一个数量级,前者是c写的,




















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37