nginx的变量和配置指令
2016-01-05 02:27
211 查看
nginx变量
说明
看了好多介绍nginx变量和配置的博客,春哥写的太好了,虽然春哥说了不要读者转载,文章内容很多,我简单的写出了一部分自己局的好的,以后会经常用的写下来,例子也会都测试一下,反正没人会看,万一被人看到,这里是春哥的原作地址:春哥的新浪博客 和春哥维护的OpenResty官网书的地址nginx变量简介
Nginx的配置文件使用的就是一门微型的编程语言,变量说白了就是存放“值”的容器。而所谓“值”,在许多编程语言里,既可以是3.14这样的数值,也可以是 hello world 这样的字符串,甚至可以是像数组、哈希表这样的复杂数据结构。然而,在 Nginx 配置中,变量只能存放一种类型的值,因为也只存在一种类型的值,那就是字符串。 set $a "hello world"; 标准 ngx_rewrite 模块的 set 配置指令对变量 $a 进行了赋值操作 -- set指令在什么阶段 所有的 Nginx 变量在 Nginx 配置文件中引用时都须带上 $ 前缀,直接把变量嵌入到字符串常量中以构造出新的字符串:
Perl的变量插值
变量插值(Perl)这样一段程序
$tt="123" print 'this is $tt.';
结果将打印出
this is $tt.
如果将第二句改成
print "this is $tt.";也就是把单引号改成双引号
结果就会打印出
this is 123.
这是因为在使用双引号时,perl将检查引号内的每个字符,看看是否有特殊定义, 然后将它替换为其内容,这叫做变量插值。而对于单引号,则原封不动的保持引号 间的内容,不做任何替换。查找了资料之后发现,这里的变量插值和lua的变量替换相似,
set $a hello; set $b "$a, $a";
通过已有的 Nginx 变量 $a 的值,来构造变量 $b 的值,于是这两条指令“顺序执行”完之后,$a 的值是 hello,而 $b 的值则是 hello, hello. 这种技术在 Perl 世界里被称为“变量插值”(variable interpolation),它让专门的“字符串拼接运算符”变得不再那么必要。 想通过 echo 指令直接输出含有“美元符”($)的字符串,那么有没有办法把特殊的 $ 字符给转义掉呢?答案是否定的 geo $dollar { default "$"; } server { listen 8080; location /test { echo "This is a dollar sign: $dollar"; } } 我的理解:其他模块会发生变量替换,但是geo模块不会发生变量替换。并不是说geo模块的重要,只是表名,除非使用特殊的非“变量插值”模块,一般都要发生变量替换。
geo模块的作用
ngx_geo 模块最常规的用法是根据客户端的 IP 地址对指定的 Nginx 变量进行赋值,这里只是借用它以便“无条件地”对我们的 $dollar 变量赋予“美元符”这个值。 在“变量插值”的上下文中,还有一种特殊情况,即当引用的变量名之后紧跟着变量名的构成字符时(比如后跟字母、数字以及下划线),我们就需要使用特别的记法来消除歧义,例如: -- 会出现歧义 server { listen 8080; location /test { set $first "hello "; -- hello无论加不加引号都行 echo "${first}world"; -- 加空格也行 } --看字理解有点烦,看程序好多了 } 这里,我们在 echo 配置指令的参数值中引用变量 $first 的时候,后面紧跟着 world 这个单词,所以如果直接写作 "$firstworld" 则 Nginx “变量插值”计算引擎会将之识别为引用了变量 $firstworld. 为了解决这个难题,Nginx 的字符串记法支持使用花括号在 $ 之后把变量名围起来,比如这里的 ${first}. 上面这个例子的输出是: $ curl 'http://localhost:8080/test hello world --输出,不会出现¥firstworld ,会报错 set 指令(以及前面提到的 geo 指令)不仅有赋值的功能,它还有创建 Nginx 变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量
nginx变量的用法
Nginx 变量的创建和赋值操作发生在全然不同的时间阶段。Nginx 变量的创建只能发生在 Nginx 配置加载的时候,或者说 Nginx 启动的时候;而赋值操作则只会发生在请求实际处理的时候。这意味着不创建而直接使用变量会导致启动失败,同时也意味着我们无法在请求处理时动态地创建新的 Nginx 变量。我们无法在请求处理时动态地创建新的 Nginx 变量。
自己的理解:nginx变量中加不加引号都行,假如
$a hello; echo $a world;–结果为
hello world
如果
$a [hello]; echo $a world;–结果为[hello] world,()等都可以,但是{}确是不可以
Nginx 变量名的可见范围虽然是整个配置,但每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰。比如前面我们请求了
/bar接口后,
$foo变量被赋予了值
32,但它丝毫不会影响后续对
/foo接口的请求所对应的
$foo值(它仍然是空的!),因为各个请求都有自己独立的
$foo变量的副本。
Nginx 变量理解成某种在请求之间全局共享的东西,或者说“全局变量”。而事实上,Nginx 变量的生命期是不可能跨越请求边界的
server { listen 8080; location /foo { echo "foo = [$foo]"; } location /bar { set $foo 32; echo "foo = [$foo]"; } }
这里我们在
location /bar中用
set指令创建了变量
$foo,于是在整个配置文件中这个变量都是可见的,因此我们可以在
location /foo中直接引用这个变量而不用担心 Nginx 会报错。
下面是在命令行上用
curl工具访问这两个接口的结果:
$ curl ‘http://localhost:8080/foo’
foo = []
$ curl 'http://localhost:8080/bar' foo = [32] $ curl 'http://localhost:8080/foo' foo = [] 变量容器的生命期,是与 location 配置块绑定的。其实不然。我们来看一个涉及“内部跳转”的例子. 发起到 location /bar 的“内部跳转”。所谓“内部跳转”,就是在处理请求的过程中,于服务器内部,从一个 location 跳转到另一个 location 的过程。 后者是由 HTTP 客户端配合进行跳转的,而且在客户端,用户可以通过浏览器地址栏这样的界面。
server { listen 8080; location /foo { set $a hello; echo_exec /bar; -- 模块的内部跳转,从一个location- 到另一个location } location /bar { echo "a = [$a]"; } }
第三方模块 ngx_echo 提供的 echo_exec 配置指令,后者是由 HTTP 客户端配合进行跳转的,而且在客户端。内部跳转和 Bourne Shell(或 Bash)中的 exec 命令很像,都是“有去无回”。另一个相近的例子是 C 语言中的 goto 语句。
相关文章推荐
- nginx代理指定目录
- 访问Nginx发生SSL connection error的一种情况
- Nginx+Naxsi部署专业级Web应用防火墙
- CentOS 6.2实战部署Nginx+MySQL+PHP
- nginx中http核心模块的配置指令2
- nginx中http核心模块的配置指令3
- nginx中http核心模块的配置指令4
- nginx中http的fastcgi模块的配置指令1
- Nginx 学习笔记(一)
- 网站502与504错误分析
- 艰难完成 nginx + puma 部署 rails 4的详细记录
- 把Lua编译进nginx步骤方法
- web 应用中常用的各种 cache详解
- Linux系统上配置Nginx+Ruby on Rails+MySQL超攻略
- window+nginx+php环境配置 附配置搭配说明
- 解析CI即CodeIgniter框架在Nginx下的重写规则
- 将PHP从5.3.28升级到5.3.29时Nginx出现502错误
- 基于Nginx0.8.54+PHP5.3.4+MySQL5.5.8的全新LNMP稳定版架构搭建的VPS
- Nginx(PHP/fastcgi)的PATH_INFO问题