Nginx|nginx变量详解(一)

在nginx配置中,变量只能存放一种类型的值,那就是字符串
比如在nginx.conf文件有:

set $a "hello,world";

set $a hello;
set $b "$a,$a";
  • 使用标准ngx_rewrite模块度set配置指令对$a进行了赋值操作
  • 所有的nginx变量在nginx配置文件中被引用时,都要带上$前缀
  • 可以通过已有度nginx变量值来构造一个新的变量的值,称为"变量插值"。比如,上面我们通过已有的变量$a的值来构造变量$b度值。

一个完整实例

server {
  listen 8080;

  location /test {
  set $foo hello;
  echo "foo: $foo";
  }
}

使用 curl 这个 HTTP 客
户端在命令行上请求这个 /test 接口,我们可以得到

$ curl 'http://localhost:8080/test'
foo: hello

这里我们使用第三方 ngx_echo 模块的 echo 配置指令将 $foo 变量的值作为当前请求的响应体输出。
echo指令是支持"变量插值"的。

geo指令

如果我们想通过 echo 指令直接输出含有“美元符”($)的字符串,那么有没有办法把特殊的 $ 字符给转义掉呢?答案是否定的。
但是我们可用通过不支持“变量插值”的模块配置指令专门构造出取值为 $ 的 Nginx 变量,然后再在 echo 中使用这个变量。
geo指令可以帮我们的忙

geo $dollar {
  default "$";
}
server {
  listen 8080;
  location /test {
  echo "This is a dollar sign: $dollar";
  }
}

测试结果如下:

$ curl 'http://localhost:8080/test'
This is a dollar sign: $

这里用到了标准模块 ngx_geo 提供的配置指令 geo 来为变量 $dollar 赋予字符串 “$”,这样我们在下面需要使用美元符的地方,就直接引用我们的 $dollar 变量就可以了。
其实 ngx_geo 模块最常规的用法是根据客户端的 IP 地址对指定的 Nginx 变量进行赋值。

变量插值的歧义问题

当引用的变量名之后紧跟着变量名的构成字符时(比如后跟字母、数字以及下划线),我们就需要使用特别的记法来消除歧义:

server {
  listen 8080;
  location /test {
    set $first "hello ";
    echo "${first}world";
  }
}

我们在 echo 配置指令的参数值中引用变量 $first 的时候,后面紧跟着 world 这个单词,所以如果直接写作 “$firstworld” 则 Nginx “变量插值”计算引擎会将之识别为引用了变量 $firstworld。输出为:

$ curl 'http://localhost:8080/test
hello world

如果没有用{}把变量围起来,则会出现无法识别.例如

server {
  listen 8080;
  location /test {
    set $first "hello ";
    echo "$firstworld";
  }
}

再重启则出现

nginx: [emerg] unknown "firstworld" variable

创建变量

set 指令(以及前面提到的 geo 指令)不仅有赋值的功能,它还有创建Nginx 变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量。比如上面的例子中,$a,$b,$first,$dollar等变量在set或geo指令使用前未被创建,直到set指令使用后被创建。如果我们没有创建就直接使用变量,则会无法识别变量。

server {
  listen 8080;
  location /bad {
    echo $foo;
  }
}

此时 Nginx 服务器会拒绝加载配置:

[emerg] unknown "foo" variable

Nginx 变量的创建和赋值操作发生在全然不同的时间阶段。Nginx 变量的创建只能发生在 Nginx 配置加载的时候,或者说 Nginx 启动的时候;而赋值操作则只会发生在请求实际处理的时候。这意味着不创建而直接使用变量会导致启动失败,同时也意味着我们无法在请求处理时动态创建新的 Nginx 变量。

变量的作用域

Nginx 变量一旦创建,其变量名的可见范围就是整个 Nginx 配置,甚至可以跨越不同虚拟主机的 server 配置块。

server {
  listen 8080;
  location /foo {
    echo "foo = [$foo]";
  }
  location /bar {
    set $foo 32;
    echo "foo = [$foo]";
  }
}

这里我们在 location /bar 中用 set 指令创建了变量 $foo,于是在整个配置文件中这个变量都是可见的,因此我们可以在 location /foo 中直接引用这个变量而不用担心 Nginx 会报错。
但是,Nginx 变量名的可见范围虽然是整个配置,但每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,彼此互不干扰。

$ curl 'http://localhost:8080/foo'
foo = []
$ curl 'http://localhost:8080/bar'
foo = [32]
$ curl 'http://localhost:8080/foo'
foo = []

set 指令因为是在 location /bar 中使用的,所以赋值操作只会在访问 /bar 的请求中执行。而请求 /foo 接口时,我们总是得到空的 $foo 值,因为用户变量未赋值就输出的话,得到的便是空字符串。
因此,变量是全局创建,局部使用。也就是变量一旦创建,就在全局中存在,在其他每个请求中都可不创建就直接使用,但是,每个请求中的该变量又是独立的,有独立的值,各自互不影响。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 标签(空格分隔): nginx 在 Nginx 配置中,变量只能存放一种类型的值,那就是字符串。 1 自定义变量 ...
    ahcj_11阅读 46,820评论 0 11
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 第一章 Nginx简介 Nginx是什么 没有听过Nginx?那么一定听过它的“同行”Apache吧!Ngi...
    JokerW阅读 32,670评论 24 1,002
  • Nginx API for Lua Introduction ngx.arg ngx.var.VARIABLE C...
    吃瓜的东阅读 5,773评论 0 5
  • 早起的鸟儿有虫吃,早起的人儿有时间。早起十几分钟就可以更个百八十的字。感觉像是赚到了一样。 看一眼昨晚列下的今日清...
    田边细语阅读 124评论 0 0