一 openresty实现灰度发布
① 灰度发布
说明: '早期'博客对'灰度'发布的'概念'进行解读,并且对'原生 nginx'灰度实现进行讲解
后续: 主要拿'节点引流'的灰度发布,并且关注'gray灰度策略'
相关借鉴
② 回顾HTTP反向代理流程
ngx_http_upstream
可'操作'点:根据'负载均衡策略'选择上游的服务器
wrr hash least_conn 反向代理和负载均衡原理
③ 指令
balance: '均衡'
说明: 只有下面'两个'指令,而不是'三个',没有'balancer_by_lua'指令
掌握: upstream {}、'balancer_by_lua_file'、'balancer_by_lua_block'
upstream
强调: upstream模块中'server配置的地址'不能用变量,只能为'ip'
balancer_by_lua_block
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传递结果给这个上下文的解决方法可以'绕过'这个限制
balancer_by_lua_file
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' 或全局模块里'传递'过来
k8s nginx ingress动态更新原理
③ ngx.balance
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
set_more_tries:设置连接'失败'后的'重试'次数
balancer.set_more_tries不能超过proxy_next_upstream_tries
推荐: 用'ngx.ctx.tries'记录进入balancer.lua的'次数',超过设置的重试次数直接给错误响应码
get_last_failure
get_last_failure:获取'上一次连接失败'的具体'原因'
注意: state_name '和' status_code 返回值的'含义'
set_timeouts
recreate_request
相关参考
④ 第三方lua-resty-balance