一 openresty实现灰度发布
① 灰度发布
- 说明: '早期'博客对'灰度'发布的'概念'进行解读,并且对'原生 nginx'灰度实现进行讲解
-
- 后续: 主要拿'节点引流'的灰度发布,并且关注'gray灰度策略'
② 回顾HTTP反向代理流程
可'操作'点:根据'负载均衡策略'选择上游的服务器
wrr hash least_conn 反向代理和负载均衡原理
③ 指令
- balance: '均衡'
-
- 说明: 只有下面'两个'指令,而不是'三个',没有'balancer_by_lua'指令
-
- 掌握: upstream {}、'balancer_by_lua_file'、'balancer_by_lua_block'
强调: upstream模块中'server配置的地址'不能用变量,只能为'ip'
- 1、负载均衡器'结果'可以和'现有的nginx upstream模块'一起使用
-
- 常见: 'ngx_proxy'和'ngx_fastcgi'
-
- 2、'balancer_by_lua*'可以和'标准upstream连接池'机制一同工作
-
- 常见: 标准'keepalive'指令
-
- 注意: 确保keepalive 指令在一个单独的upstream{}配置块中的'balancer_by_lua_*'的后面
-
- 3、'balancer_by_lua*' 会完全'忽略'掉定义在upstream{}块中定义的'servers'列表
-
- 重点: 但是'server'指令必须存在,作为一个'placeholder'占位符存在,避免'nginx -t'报错
-
- 同俗理解: openretry '优先走' balancer_by_lua 逻辑块
-
- 实质:通过lua-resty-core库中的'ngx.balancer'模块,从一个完全'动态'的server列表中'选择'
-
- 颗粒度:基于'每个请求'中
-
- 4、当nginx的upstream机制'重试'请求中指令指定的条件,如proxy_next_upstream指令
-
- 说明: 这个指令'注册的Lua代码'处理器可能在一个单独的'下游请求'中被调用'不止'一次
-
- 5、注意'事项'
-
- 1) 这个上下文中执行的Lua代码并'不支持yielding'
-
- 2) 所以可能yield的Lua APIs(例 cosockets和"light threads")在这个上下文中是'被禁用'
-
- 3) 通过在'早期阶段'处理程序'如:access_by_lua*'处理这种操作和
-
- 4) 通过'ngx.ctx 'table传递结果给这个上下文的解决方法可以'绕过'这个限制
- 1、OpenResty 的 'balancer_by_lua' 指令让'动态负载均衡'成为可能
-
- 2、它'替代'了原生的 'hash/ip_hash/least_conn' 等算法
-
- 3、不仅可以让'自由定制'负载均衡策略,还可以随意'调整'后端服务器的数量
-
- 4、完全'超越'了 upstream 系列指令,实现了接近'商业版' Nginx Plus 的功能
-
- +++++++++++++ "注意事项" +++++++++++++
-
- 1、'balancer_by_lua' 也是一个比较'特殊'的执行阶段
-
- 特点: 这里'不能'使用 'ngx.sleep'、'ngx.req.*' 或 'coocket'
-
- 补充: 同时应当尽量'避免'大计算量操作或磁盘读写,否则会导致'阻塞'
-
- 2、动态负载均衡使用的'服务器列表'通常'存储在外部'的 Redis '常见' 或 MySQL 里
-
- 备注: 由于'不能直接'使用 cosocker,所以在 'balancer_by_lua' 里也就'不能'操作这些服务器
-
- 解决: 但可以在'其他'的阶段'access_by_lua、ngx.timer[常见]'里 -->
-
- 访问服务器获取'列表'、解析'域名',然后放在 'ngx.ctx' 或全局模块里'传递'过来
- lua-resty-core 模块 '提供' ngx.balancer
-
- 1、这'四'个函数的的'用法'都很'简单'
-
- 2、动态负载均衡的'重点'其实是服务器'列表的维护'和'选择算法'
-
- 备注:这些工作通常应该在 'balancer_by_lua' 之'外'完成,ngx.balancer 只是最后的'执行者'
set_current_peer nginx转发实现过程中的问题总结
- 最佳实践: balancer.set_current_peer用于设置后端的'地址'与'端口'
-
- balancer中只能'设置ip',不'支持'直接设置域名,
-
- 思考: 如何解决'DNS'解析问题?
-
- 1、host中的域名'不起'作用,'可以'使用'lua-resty-dns'解析域名,然后获取'解析'结果
-
- 2、可以在'access_by_lua*阶段'解析域名,总之要在'upstream'之前'解析'域名
-
- 例如:这里是在rewrite阶段,从'请求信息'中读取出了'关键'信息,做了一次DNS解析再'设置'进去的
set_more_tries:设置连接'失败'后的'重试'次数
balancer.set_more_tries不能超过proxy_next_upstream_tries
推荐: 用'ngx.ctx.tries'记录进入balancer.lua的'次数',超过设置的重试次数直接给错误响应码
- get_last_failure:获取'上一次连接失败'的具体'原因'
-
- 注意: state_name '和' status_code 返回值的'含义'
④ 案例讲解
- 1: 简单'案例'
-
- if not ok then --> 检查'是否'设置成功,代码要'健壮'