前言:
目前朋友们对“两台nginx请求隔离”大约比较重视,咱们都需要了解一些“两台nginx请求隔离”的相关文章。那么小编也在网摘上搜集了一些有关“两台nginx请求隔离””的相关知识,希望同学们能喜欢,大家一起来了解一下吧!在nginx中所有的变量在定义的时候都会被关联上一个get_handler()方法,所有变量在第一次获取值的时候,都是通过这个handler方法获取的,后续再次获取变量值的时候,是否仍然调用该handler方法则取决于该变量是否可以被缓存。
不可缓存的变量在获取值的时候都是实时计算的,比如“$arg_”开头的动态变量,每次获取值的时候都会从查询参数中重新解析对应的值;而可以缓存的变量并不会每次都调用这个handler方法,在它的整个生命周期中,如果这个变量没有被刷新过,那么自始至终只会调用一次。
nginx中用set指令定义的变量都是可以缓存的,但set指令不会改变已有变量的缓存特性(比如内置变量,但动态变量除外),而所有以“arg_”开头的动态变量都是不可缓存的,这两种变量结合在一起的时候会产生一种有意思的现象,来看一个简单的例子:
location/a { set $a “$arg_name”; return 200 “$a = $arg_name”;}
用curl测试一下:
curl =zhangsan
这个结果看起来并没有超出我们的预期,跟变量是不是可以缓存好像也没啥关系。
下面我们把这个例子稍微改造一下,改成如下形式:
location /a { set $a “$arg_name”; set $args “name=lisi”; return 200 “$a = $arg_name”;}
再次用curl测一下:
curl = lisi
这时候我们可以看到,“$a”和“$arg_name”这两个变量虽然都是在表示入参name的值,但是且输出了不同的结果。
这其实就是变量是否可缓存的特性引起的,因为变量“$a”是一个可缓存的变量,当被设置后变量值就被保存下来了;而“$arg_name”是一个不可被缓存的变量,每次获取该值的时候都会调用其对应的handler方法。
我们看到第一次调用的时候查询参数值是“name=zhangsan”,这个值被赋值给了变量“$a”,在第二次获取该变量值之前,我们把查询参数改成了“name=lisi”,当它再次调用对应的handler方法的时候获取到的值就变成了“lisi”。
动态内置变量此时仍然是一个特殊的存在,我们之前说过,动态变量被重新定义后它就不再是动态变量了,所以它也就不再保有不可缓存的特性,看个例子就知道了:
location /a { set $arg_name “$arg_name”; set $a “$arg_name”; set $args “name=lisi”; return 200 “$a = $arg_name”;}
用跟上面同样的入参访问以下该location:
curl =zhangsan
可以看到这两个变量的值又一样了。其实原因很简单,用set指令重新定义“$arg_name”后它就不再是动态变量了,它原本的不可缓存特性也就不存在了,所以此时查询参数的更改对他也就不起任何作用。
变量的隔离性
nginx中变量的隔离性类似于其它编程语言中变量的作用域,但它又不像其它语言那样有全局和局部变量之分。nginx中的变量隔离是基于请求的,同一个变量在不同的请求中毫无关系,即A请求不会读到(或改变)B请求中的变量值,B也不会读到(改变)A的,比如下面一个例子:
server { set $a “$uri”; location /a { return 200 “I am $a”; } location /b { return 200 “I am $a”; }}
我们在server块定义了一个看似是“全局变量”的“$a”,如果它有全局性,那么访问上面的两个location的时候肯定会得到相同的值,但nginx中不是这样的。
在nginx中两个location都可以看到这个变量“$a”,这体现了nginx变量的全局可见性;但两个location看到的变量值确实是不一样的,这体现了隔离性。用curl验证一下结论是否正确:
curl
可以看到结果跟预期一致。
在同一个请求中nginx的变量是有全局性的,但仅限于当前请求中。不管变量的更改发生在配置文件的哪个位置,在同一个请求中都可以被看到,看下面一个例子:
server { set $a “server”; location / { set $a “location”; if ($uri) { set $a “if”; } return 200 “$a”; }}
从上面的例子可以看到,变量“$a”被更改了三次。因为“$uri”总会有值,所以if块中的set指令也会执行。这种情况如果在其它语言中一般是输出字符串“location”的,因为每块作用域都会关联一块内存空间来存放本作用域内的变量值。但是nginx在整个请求过程中只会为某个变量保留一份存储空间,所以变量值也会只保留最后一次修改的值,因此上面的例子一定是输出字符串“if”。
标签: #两台nginx请求隔离