网站首页 > 技术教程 正文
在上一篇文章「系统架构」Nginx调优之变量的使用(3)中我们介绍了变量的可见性及动态内置变量,下面我们继续接着介绍Nginx中的可变变量和不可变变量
可变变量和不可变变量
大部分编程语言在声明变量时一般会有特定的修饰符来标识变量是否可变,比如,java中的“final”修饰符和C中的“const”修饰符。如果某个变量在声明时加上了这些修饰符,那么它在后续是无法再被修改的,这体现了变量的不可变性。
nginx中的变量也存在可变和不可变之分,但是它并没有显著的修饰符,所以从表面上你根本看不出来该变量是否可变。不过nginx在启动过程中提供了一个自检查机制,当在配置文件中试图修改一个不可变变量时,nginx是不会顺利启动的。通过这种机制可以间接的判断某个变量是否可变,这种机制我们在前面已经体验过好多次,其实也算是nginx的一种自我保护机制,尽早发现错误尽早制止错误。
前面讲自定义变量的时候涉及到了两个指令set和geo,现在我们来看看用set指令定义的变量是否可改变,一个例子如下:
location/a {
? ? set $a“old a”;
? ? set $a “new a”;
? ? return 200 “$a”;
}
用curl测验一下:
curl http://127.0.0.1/a
new a
再看一个geo指令的例子:
http {
? ?geo $a {default “old a”}
? ?geo $a {default “new a”}
? ?location /a {
? ? ?return 200 “$a”;
? ?}
}
用curl测验一下:
curl http://127.0.0.1/a
new a
两个例子都可以成功启动并打印数据,因此,我们判定这两个指令定义的变量可以被改变。
记住上面的这个结论,然后咱们再看一个例子:
location /a {
? ?set $host “I am host”;
? ?return 200 “$host”;
}
nginx启动失败,并且打印了一条错误日志:
nginx: [emerg] the duplicate "host"variable in /path/conf/nginx.conf:49
看到这种结果你可能开始怀疑刚刚得出的结论似乎又是错误的。查阅nginx文档会发现“$host”这个变量是http核心模块中的一个内置变量,此时,你可能会猜测nginx中的内置变量是不可以改变的。为了验证这个结论我们再找一个内置变量验证一下:
location /a {
? ?set $args “I am querystring”;
? ?return 200 “$args”;
}
例子中的“$args”是一个内置变量,表示请求中的查询参数。当我们试图启动nginx的时候发现完全没有问题,而且用curl也可以正确访问,这时候你可能已经懵了,感觉nginx变量的这些行为毫无章法。
实际上这个问题的答案仅从做实验和文档上是找不到的,只能从代码上一窥究竟,不过我不打算带着读者读代码,这里简单说一下原理:
nginx中每个变量在被定义的时候都会打上一个是否可以被改变的标记,然后把放到一个容器中,当后续有人试图再次定义用一个变量的时候,nginx会首先从这个容器中查找这个变量,如果找到相同的变量则需要判断容器中的变量是否存在可改变的标记,如果有则定义的变量会把容器中的变量覆盖掉,如果没有则返回错误并终止nginx启动。
另一个要注意的是,http模块中的内置变量放入该容器中的时机,内置变量要先于“set”或“geo”指令,如果某个内置变量被打上了不可改变的标记,后续其它指令就无法再定义相同名字的变量了。
目前,nginx的核心http模块中几乎所有内置变量都是不可改变的,只有“$args”和“$limit_rate”这两个内置变量可以被改变。
另外,由于http模块的动态内置变量并不会把自己放入到容器中,所以它看起来是可以被改变的,比如:
location/a {
? ?set $arg_a “I am a”;
? ?return 200 “$arg_a”;
}
用curl验证下:
curl http://127.0.0.1/a?a=b
I am a
可以看到这个包含了一个内置变量的例子可以正常启动,并且输出了数据。所以,关于大部分内置变量不可改变这个结论,似乎需要再加上一条:除动态内置变量外。
实际上是因为动态变量被重新定义后它就不再是动态变量了,它之所以不再是动态变量,那是因为动态变量的“定义”发生在所有内置变量和自定义变量之后。在nginx中,一旦某个变量被认定为自定义或内置变量,后续就不会再被赋予动态变量的特性。
比如,例子中的“$arg_a”,其实已经变成了一个自定义变量,相应的动态变量特征也就不存在了,但其它以“$arg_”开头的变量仍然是动态变量。
猜你喜欢
- 2024-10-15 haproxy和nginx负载均衡(nginx负载均衡ip_hash策略)
- 2024-10-15 Centos 7 network.service 启动失败
- 2024-10-15 nginx做负载后导致登录失败返回新的cookie原因分析
- 2024-10-05 nginx报错之413 Request Entity Too Large导致文件上传失败的问题
- 2024-10-05 Nginx系列:Nginx自带后端健康检查
- 2024-10-05 Nginx负载均衡健康检测,你了解过吗?
- 2024-10-05 Nginx负载均衡原理及应用实践(nginx负载均衡策略有哪些,它是如何实现的)
- 2024-10-05 SSL证书安装失败怎么办?看这里教你轻松解决
- 2024-10-05 面试中关于Nginx的十问九答(面试中关于nginx的十问九答有哪些)
- 2024-10-05 Zabbix 5.2由浅入深之监控Nginx(监控nginx访问日志)
你 发表评论:
欢迎- 最近发表
-
- 阿里P8大佬总结的Nacos入门笔记,从安装到进阶小白也能轻松学会
- Linux环境下,Jmeter压力测试的搭建及报错解决方法
- Java 在Word中合并单元格时删除重复值
- 解压缩软件哪个好用?4款大多数人常用的软件~
- Hadoop高可用集群搭建及API调用(hadoop3高可用)
- lombok注解@Data没有toString和getter、setter问题
- Apache Felix介绍(apache fineract)
- Spring Boot官方推荐的Docker镜像编译方式-分层jar包
- Gradle 使用手册(gradle详细教程)
- 字节二面:为什么SpringBoot的 jar可以直接运行?
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)