- 本文是对前面做一个'阶段性'的总结,更加'结构化',便于理解和'记忆',并补充工作中的一些'易错点'
-
- ps1:前面'变量写的章节'太乱了,后续会'删除'
-
- ps2:后续'非框架'模块提供的变量,我会随着'指令'的讲解来讲述'应用场景'
-
- ps3:目的是形成自己的'知识框架',本章节'不会'细讲
一 变量的运行原理
① 原理图
- 1)nginx中的'变量模块'可以分为两类:一类是'提供变量'的模块;另外一类是'使用变量'的模块
-
- 明确: 变量'使用前'都必须'先定义'
-
- 备注: 有些使用的变量我们在'nginx.conf'找不到,是因为'模块'内置了

- 1)nginx启动'之后',加载'模块',在读取'nginx.conf'之前,会扫描'所有'模块变量,only定义'变量名'以及可以'解析出变量'的方法
-
- ngx_http_variables.h/ngx_http_variable_value_t; # 变量值结构体
-
- ngx_http_variables.h/ngx_http_variable_t; # 变量名结构体
-
- 通俗:只是定义了一个规则'(如何解析变量)';如果'没有'使用,则不会'触发'变量的解析
-
- 2)读取nginx.conf,接收和处理'请求'时,如何'获取变量值'?
-
- 细节点:当需要'获取这个变量值'的时候,会调用这个'变量上绑定的get_handler()'方法,该方法会创建或者从缓存中'获取'一个ngx_http_variable_value_t结构体
-
- 3)'使用变量'的场景: '日志'格式、'指令'中的值、'逻辑'判断
-
- 4)思考:哪些需要'读取nginx.conf'或'处理请求'才会'定义'变量?
-
- map、set、正则(命名补获、'数字编号'补获)
② 变量的特性

- 1)惰性求值:只有'使用'的时候才会去调方法解析获取'变量值'
-
- 2)'动态'理解:变量值可以时刻变化,其值为'使用的那一时刻'的值
-
- 例如:nginx发送给客户端'响应包体字节数',实际在发送的过程中是一直在'变化'的


![]()
③ 存放变量的hash表

④ 变量相关的报错
- unknown "a" variable -->'未定义(声明)变量'
-
- nginx: [emerg] invalid variable -->'变量名([0-9a-Z_])不符合语法规范'
⑤ 杂谈
- 1)在 nginx 配置中,变量只能存放一种类型的值,有且只能是'字符串类型';
-
- 2)使用变量:$var、${var} -->推荐后者'变量内插'方式
-
- 3)nginx 自定义变量的'创建'和'赋值操作'发生在全然不同的时间阶段
-
- [1]、nginx 变量的创建只能发生在' 配置加载'的时候
-
- [2]、而'赋值操作'则只会发生在'请求实际处理'的时候
-
- 4)作用域
-
- [1]、nginx变量一旦创建,其变量名的'可见范围'就是整个nginx配置,甚至可以跨越不同虚拟主机的server配置块
-
- [2]、但每个请求都有'所有变量的独立副本',或者说都有各变量用来存放值的容器的'独立副本',彼此互不干扰
-
- [3]、nginx变量的生命期是'不可能跨越请求边界'的
-
- 5)生命期
-
- nginx变量容器的生命期,并'不严格'与'location配置块'绑定,比如"内部跳转";但"外部跳转"是会与location配置块'绑定'的
- 引言: 除了'nginx的模块'之外,'nginx 框架'也包含许多的变量
-
- 框架变量'特点': 不需要通过'编译模块'来引入,而且框架所提供的变量往往反映了'处理请求的细节'
-
- 补充: nginx 内建变量'最多见的用途'就是获取关于'请求或响应'的各类信息
① 框架变量分类

系统变量特点: '不随'请求变化而变化
② HTTP请求相关的变量
(1)知识铺垫
- +++++++++++ "需求" +++++++++++
-
- 1)请求行包括'哪些内容'? nginx如何获取完整'请求行'的内容? nginx如何'拆解'请求行?
-
- 关键字: '查询参数'、'编码'
-
- 2)nginx如何获取'请求头(request_header)'?
-
- 关注点: 获取部分'请求头'的'等价'形式
-
- 3)nginx如何获取'请求体(request_body)'?
-
- 4)补充:客户端请求的时候有'#'锚点,这是客户端'解析',不会透传给'nginx'
(2) 变量一
- 请求头:'content_length'、'content_type'
-
- args:非'只读'变量,是url中'?'和'#'中间的参数
-
- is_args:空字符串为'假'

(3)变量二

- +++++++++++ '$uri细讲' +++++++++++
-
- $uri – 在请求中的当前URI,被"标准化"后的
-
- 被标准化:解码'被编码'的字体(以"%XX"形式),解析'相对路径'引用,将连续'反斜线合并'为1个
-
- 补充:在请求处理期间,变量$uri的值可能'发生变化';比如进行'内部重定向',或者使用'index指令'
+++++++++ '案例1' +++++++++

![]()
+++++++++ '案例2' +++++++++

![]()
(4)变量三

(5)变量四

- 辨析:$http_host、$host、$server_name
-
- 关注:'端口'的问题
-
- 结论:$http_host是携带'端口号'的;默认'http(80)'和'https(443)'会'省略'端口号


+++++++++++ '案例分割线' +++++++++++

![]()
(6)变量五
遗留: nginx如何'特殊'处理这些请求头?

② TCP连接相关的变量
关注点: 哪些信息可以通过'tcpdump'和'wiresahrk'唯一确定其tcp连接对应的'http'请求?
(1)变量一

(2)变量二

③ nginx处理请求过程中产生的变量
(1)变量一
- 备注: $server_name 是 'server_name指令'的'主域名'的值,'不建议'使用
-
- 1)server_name多域名'http-->https'禁止使用:
-
- rewrite ^(.*) https://$server_name$1 permanent;

(2)变量二
响应头: 'X-Accel-Rates'影响'limit_rate'

④ 发送HTTP响应相关的变量
遗留: 这'9个响应头',nginx是如何做'特殊'处理的?

⑤ nginx系统变量

⑥ 补充信息
- 1)nginx处理变量的一些细节:大写转化为小写,横杠转化为下划线
-
- 2)变量作用域
-
- 在转发的时候,proxy_pass 等,数据
-
- 在内部转发的时候 -->内部重定向或者请求转发的时候 (last)
-
- 请求信息丢失
-
- 细节点:protocol p 转发的时候 -->后端的端口记得8443和443都是往443转发 Host头的一些细节
-
- ④⑤⑥⑦⑧⑨⑩
-
- 变量的应用场景:日志排错等 -->
-
- key:value 逗号分割多个k/v -->观察:return(rewrite阶段,$字节数为0)和日志的输出
-
- 2)http框架提供变量分类
-
- nginx --> openresty(lua) -->结合来学习其它中间件
-
- 后续:openresty中变量使用