说明: 假定使用'proxy'模块,其它'upstream模块'类同
(1)总述
① next upstream概念
++++++++++ 这一"功能"在'nginx指令'中称为"next upstream" ++++++++++
1)当上游'出错'时
出错场景: '传输层tcp连接'、'ssl/tls表示层握手'、'应用层响应状态码'
2)作为'负载均衡的nginx'可以'实时更换'server
nginx'遇错'行为: 重新根据'lb算法'选择一台'server'
3)在客户端'无感知'的情况下'重新转发'HTTP请求
用户体验: '无感知'
② error.log错误信息的来源
后续: 'tcp/ip'协议、'网络编程'、'tls加密'
目的: 能'一眼'看懂'错误'的含义,分析出是'OSI哪个层面'的报错
③ next upstream没有发挥作用场景
说明: 先做一个'铺垫',了解'有'这些场景
'补充'场景:
1)'error_page'和'proxy_intercept_errors' 同时配置相同的'错误码'
2) error_page'优先级高',导致'proxy_intercept_errors'不生效
(2) nginx在OSI网络模型的多个层级中检测
nginx作为代理服务器'转发请求'时,next upstream机制'检测错误'并重新转发给'上游'的执行流程
高级:怎么把'传输层的错误'转化为'应用层'的错误?
① TCP传输层的错误处理
说明: 从'处理流程'的阶段讲解'哪个阶段涉及timeout的报错'
具体: '连接、nginx发送请求、nginx接收响应'
1)TCP三次握手的机制
2)哪些场景nginx认为连接建立失败
当nginx'作为客户端(client)'发起三次握手时,它会向'上游server'监听的端口上发送'SYN'报文
++++++++++ nginx会认为与'上游'3次握手'建立失败' ++++++++++
1)接收到对方'返回的RST重置'报文 -->'error'错误
备注:通常'发生'在上游对应的'应用程序未启动'、或者进程'没有监听'相应的端口、'防火墙未打通'
2)在proxy_connect_timeout时间内'默认60秒','没有'接收到对方返回的'SYN+ACK'报文
备注:tcp'超时'重传
思考:没有收到'SYN+ACK'报文的'原因'? -->'网络时延丢包'、'iptables策略'
3) nginx如何用timeout处理的
核心: nginx在'TCP传输层'是如何'应用next upstram机制'的
说明: 暂时只关注'error'和'timeout'这两个参数
++++++++++++ 'proxy_send_timeout' ++++++++++++
proxy_send_timeout TCP中的RTT和RTO
++++++++++++ 'proxy_read_timeout' ++++++++++++
1) 当nginx'转发完'请求,在'接收上游返回响应'的过程中
2) 如果epoll_wait'两次返回读事件的间隔'超过了proxy_read_timeout秒,'触发'timeout错误
4)proxy_next_upstream_tries重试机制
说明: 该'指令'还可以限制'更换'上游server转发请求的'总'时长,'默认不加限制'
细节点:
1) 该时长的'起始(start)'时间是从'首次转发请求'算起,而不是每次更换上游server时'重新'计算
2)而'截止(end)'时间则是'最后1次'检测next upstream是否允许使用的时刻
② TLS表示层的错误处理
核心: 看nginx如何'处理'表示层'TLS/SSL'协议的'error'错误
备注: TLS会话的建立需要通过'握手'完成
注意: 一旦'证书链'或者'SNI域名'验证失败,next upstream机制将按'error错误'处理
1)TLS握手
2)nginx基于哪些指令判断TLS的error
说明: 在'TLS/SSL'处理的任何一个'过程',都会出现'error'
掌握: nginx'哪些指令'与这些关联,下面只是列出了'两个不太常用'的指令
proxy_ssl_verify proxy_ssl_name
③ 应用层错误处理
下图: 是'TCP层、TLS层与应用层'结合在一起后,next upstream的'工作流程示意图'
+++++++++++ "解读" +++++++++++
1)当proxy_intercept_errors'开启(on)'后,拦截上游返回的'>=300'响应码的请求
2)思考:拦截之后'如何'处理? 处理的'顺序'?
[1]、如果'proxy_next_upstream'配置了'相应'的状态码,则'启用next upstream机制'
[2]、如果没有配置'proxy_next_upstream'或'配置了但状态码不匹配',则看'error_page'
[3]、如果配置了'error_page',并且'status'匹配上,则进行处理
[4]、否则'nginx'原样返回
细节点: 'proxy_next_upstream'优先级比'error_page'指令高
2)可以拦截上游哪些HTTP状态代码进行next_upstream
细节点:
1)虽然应用层在'协议层面'返回了'正确'的response响应
2)但从'HTTP 语义上'却是'错误'的,nginx同样可以'启用next upstream'机制
强调: 必须'显示'的'按需'配置要拦截的'特定状态码',否则'不生效'
思考: error_page指令执行后'返回给client'的状态码是什么?
1)从上游'拦截'的 error_page 504 uri
2) 自定义的 error_page 504 =401 uri -->'伪装'
3)重定向页面返回的 error_page = uri
注意: 返回的'内容'不变
3) invalid_header选项
注意: 该参数的'两个'应用场景,一般'不配置'该参数
4)HTTP请求方法
1)默认对于'幂等的method(GET/HEAD/DELETE/PUT)'支持'next_upstream'
2)对于'非幂等的method',如果需要支持'next upstream',需显示'开启'non_idempotent参数
常见现象: 客户端有时候'有的请求(POST)'报错,有时候'有的请求(GET)'不报错
④ 题外话
通过upstream模块的变量可以验证next upstream 是否生效
说明: 淘宝的'第三方健康检查模块'可以'定期通过心跳'检查上游
补充: 官方'模块'是有请过来,才'尝试'建立连接,如果'无法'建立连接,在规定的时候重试多次都不行,则在接下来的'时间段'不再选择这个节点
⑤ 其它upstream模块