说明: 只有安装了'upstream'模块,才能使用'该模块'提供的'变量'
变量特点:
1)一系列以'$upstream_'开头的变量
2)知道哪些'变量'涉及多个值用';、:'分割 -->'$upstream_addr'
3)哪个'nginx版本'才引入这些变量
① $upstream_addr
补充: upstream_id的名称'不区分'大小写
1)特殊':'场景
[1]、 'proxy_intercept_errors on',导致上游的错误码被'error_page'补获,
[2]、 进行'internal'内部重定向,重新进行'find_config'寻找location
[3]、 该location对应的'proxy_pass'是另一个'upstream_id'
2)重点掌握'该变量'由哪些'常见'的形式
② $upstream_connect_time
1) nginx与'后端'是'http'的话,则是记录建立'tcp'连接'花费'的时间
2) nginx与'后端'是'https'的话,则在前面'tcp建立连接'的基础上+'SSL握手'时间
3)可能包含'多个'值,对应'$upstream_addr'的连接参数
③ $upstream_header_time
说明: 从'上游'开始接收'response_line'到完全解析出'response_header'所花费的时间
单位: 's'
理解: 'upstream上游'开始发数据到'nginx完全接收响应'所'花费'的时间
场景: 来分析'后端程序接口响应'的时候,需要在nginx的'log_format'中添加'$upstream_response_time'字段
补充: 如果数值'比较大',考虑'网络通信质量'和'发送数据量'问题
⑤ $upstream_http_
name
备注: 是nginx'接收'上游'没有加工处理'的响应头
区别于: 'sent_http_name(这个是filter之后的响应头)'是nginx返回给'客户端'的响应头
细节点: 仅保存来自'最后一个后端(请求了多次后端)'的'响应头'字段
⑥ $upstream_bytes_sent
说明: 记录的是'nginx发送给上游服务器'的字节数
⑦ $upstream_bytes_received
说明: 从'上游服务器'接收到的'响应长度',是包含'响应头'在内的所有'响应长度'
⑧ $upstream_response_length
说明: 保存从upstream服务器获得的'响应体(body)'的字节数
⑨ $upstream_status
1)如果是非'502'的错误状态码,可知'nginx已经将请求转发到上游'的信息,是上游返回的'状态码'
2)如果'没有'可用的'server',nginx会自动'填充'该变量为'502'
⑩ $upstream_cookie_
name
说明: 获取上游'Set-Cookies'响应头中指定'key(name)'对应的'value'
⑪ $upstream_http_
name
++++++++++'队列(queue)理解'++++++++++
1. 如果在'处理请求'时'无法'立即选择upstream服务器,则该请求将被'放入队列'中
2. 如果队列'已满'或者在'timeout参数指定的时间段'无法选中'后端的服务器',则会将'502错误'返回给客户端
3. nginx的listen 指令有'参数backlog' 用来指定'队列大小',默认的值为'511'
说明: 涉及'add_trailer',和'chunk'有关
⑬ $upstream_cache_status
说明: 记录缓存的'命中状态'
二 汇总
说明: 这一'部分'是为了从'宏观'的角度来学习
① 第一部分
② 第二部分
三 upstream模块时间变量的详细解读
① 时间轴
② 请求五个阶段剖析
1) 用户'请求'
client与nginx'建连',同时nginx'接收完'客户端的请求数据
2) nginx与'上游服务器'建立连接
3) 发送响应 -->'上游发送给nginx的'
上游服务器'处理完'nginx'转发'过来的请求,并响应给'nginx'的耗时
4) 接收响应 -->'nginx转发给client的'
nginx将'上游的响应'转给给'client'的耗时
5) 关闭'cleint'与'nginx'连接
③ 图谱解读
+++++++++++++++ "核心点:分析请求流各个部分的耗时,找到瓶颈点" +++++++++++++++
1) 上游服务器处理的'耗时'
上游服务'执行'耗时 = $upstream_header_time - $upstream_connect_time
504'错误'语义:是指'服务器'作为网关或'代理',但是nginx'没有及时'从上游服务器收到请求
观察: proxy_read_timeout 指令的'值'与'其'的关系
2) 'nginx'从'开始'响应到给'client'发送完数据的耗时 -->"数据响应给客户端"耗时
计算方式 = $request_time - $upstream_connect_time
反映: nginx-->client的'网络通信质量' -->'带宽'之类的
3) '上游'从'开始'响应给nginx到给'nginx'发送完数据的耗时
计算方式 ≈ $upstream_response_time - $upstream_header_time
通俗: '响应体' + '响应头' + '响应行' -->"后两部分可以忽略"
4) $upstream_connect_time
观察: proxy_connect_timeout 指令的'值'与'$upstream_connect_time'变量的关系
推断:
[1]、如果二者'相等',则是由于'nginx与上游连接超时',导致连接'中断'
[2]、如果'$upstream_connect_time'值较大,可能是'nginx到上游'之间的'网络质量'有问题
④ 案例1
++++++++++++ "现象和思考过程" ++++++++++++
1) 请求流: console -->nginx --> 后端服务
2) 现象'用户感知': console 访问比较'慢',耗时大约'3s'
3) 现象'nginx日志':request_time '3s' 左右,upstream_response_time 大约'0.5'
3) 判断'问题'可能出现的'点'
1、客户端由于'网络问题',连接nginx耗时较长,导致request_time比较'大'
2、nginx与后端'连接时间比较长',但是后端'应答'时间比较'短',upstream_response_time较短
++++++++++++ "验证过程" ++++++++++++
1) 确认'是否'由于'cleint-->nginx'的网络问题
思路: 在'nginx'节点直接curl模拟访问,如果'request_time'耗时依然存在,可以排除此问题
2) 确认'是否'由于'nginx-->后端'的问题
思路: 使用upstream模块的'时间变量',修改nginx日志的格式,并'打印日志'
现象: 耗时还在'request_time',说明nginx节点'本身耗时'
3) 最终判断
[1]、通过'error.log'观察到每个请求都有一个'subrequest'的错误日志
[2]、怀疑nginx的子请求错误等待导致每个请求'固定'耗时3s
备注:'access_by_lua和bbody_filter_by_lua'导致的子请求
4) 临时'补救'策略 --> '注释'相关子请求
小结: 综合'客户端在UI'侧感知和'nginx作为服务端'的日志综合判断
nginx的$request_time 比 $upstream_response_time 的时间长很多
⑤⑥⑦⑧⑨⑩