本文是对前面做一个'阶段性'的总结,更加'结构化',便于理解和'记忆',并补充工作中的一些'易错点'
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中变量使用