Openresty(二十二)ngx.balance和balance_by_lua终结篇

这篇具有很好参考价值的文章主要介绍了Openresty(二十二)ngx.balance和balance_by_lua终结篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一  灰度发布铺垫

①  init_by_lua*

init_by_lua   

init_by_lua_block

特点: 在openresty 'start'、'reload'、'restart'时执行,属于'master init' 阶段

机制: nginx 'master' 主进程'加载配置文件'时,运行全局Lua VM级别上的参数指定的'Lua代码'

场景: 想对于应用'做一次全局性'的初始化

openresty灰度,Openresty,openresty,灰度发布

案例1: init阶段'已经加载'的模块会放在'package.loaded'中,供'后续阶段'直接使用

备注: 在'初始化时'候加载过了,已经在 package.loaded '表'里

openresty灰度,Openresty,openresty,灰度发布

案例2: ' lua_shared_dict' 和 'ngx.shared'的'set、get'方法结合使用

openresty灰度,Openresty,openresty,灰度发布  

当配置重载时,init_by_lua* 不会清空其内的lua_shared_dict共享数据

注意事项: 只能使用'print'、'ngx.log' API 和 'lua_shared_dict' 指令

推荐: 在'init_by_lua'中调用'require()'来加载自己的模块文件

特点: 

 1) require()会在全局Lua注册的'package.loaded表'中缓存Lua模块

 2) 所以在'整个Lua虚拟机实例中'你的模块将'只会加载一次'

补充: 'init_by_lua*'中master进程'执行'lua代码

openresty灰度,Openresty,openresty,灰度发布

案例3: 阻塞'I/O'调,执行'shell'命令  --> '特殊场景'

 1、在这个'上下文'中,你可以保守使用'lua库'完成阻塞I/O调用

 2、因为在'master进程'的阻塞调用在服务的启动过程中是完全'没问题'的

 3、进一步说在'配置加载'阶段,Nginx核心就是'阻塞 I/O 方式'处理的

场景: 采用在'init阶段'调用'shell'命令

lua执行系统命令方法os.execute和io.popen      init_by_lua_file不能连接redis

openresty灰度,Openresty,openresty,灰度发布

注意: 此处的'content'是'字符串',需要自己重新解析成字典,可以存入变量,也可以存在共享内存中

openresty灰度,Openresty,openresty,灰度发布

init_by_lua_file 

说明: '推荐'使用'init_by_lua_file'

openresty灰度,Openresty,openresty,灰度发布

②  init_worker_by_lua*

说明: ​官方对'init_worker_by_lua*'并没有'API'的限制

init_worker_by_lua

init_worker_by_lua_block

openresty灰度,Openresty,openresty,灰度发布

1、在'每个'nginx worker进程启动时调用'指定'的lua代码

2、用于启动一些'定时'任务:比如'心跳'检查,定时'拉取'服务器配置等等

强调:此处的任务是'跟Worker进程数量'有关系的,不要'重复'了,那么如何'避免'重复呢?

openresty灰度,Openresty,openresty,灰度发布

 ngx.worker.id判断某个worker进行初始化

说明: 使用ngx.timer可以'突破' init_worker_by_lua 中'不能使用 cosocket' 的限制

openresty灰度,Openresty,openresty,灰度发布

如何在 init_worker_by_lua 阶段连接redis/mysql/dns    redis连接池封装

③   lua_shared_dict

openresty灰度,Openresty,openresty,灰度发布

④   ngx.shared.DICT

ngx.shared共享内存操作

二   灰度发布案例

建议: 配置'指令'和'代码'解耦,这里暂时'不讲究'了

①  业务流程图

canary  --> gray  --> '灰度'

LBM: 做'配置下发'的时候,UI侧会有一个'gray灰度'开关按钮,在upstream生成对应的'代码'片段

形如:

  upstream {
     server 127.0.0.1:80;
     balance_by_lua 'lua/gray.lua'
  }

备注: 这里暂时'不讨论 upstream{}'内的健康检查
​
再次强调: 同一个'schema'集群内选举灰度节点,也即'集群内'灰度引流,而不是'集群间'引流

openresty灰度,Openresty,openresty,灰度发布

补充: 

 1、一般会将'灰度策略'先写入'DB',例如'mysql'中

 2、利用'bgr灰度插件'解析从'redis'拉取的'灰度'策略,返回'灰度节点'信息

 3、init_worker_by*的'功能'

  1) 从'redis'中拿灰度策略,放到'ngx.shared本地缓存'中

  2) 启动定时任务,定时'异步'拉取'灰度'策略

②  相关参考

openresty+Lua+Redis灰度发布     高性能软件负载OpenResty整合Reids集群配置

关于openresty的全局初始化问题   基于openresty/lua-resty-redis 二次封装的工具库

Lua Redis 使用   Java Redis 预热数据    openresty定时任务    限制定时任务耗尽资源

k8s灰度发布

+++++++++++++ "题外话" +++++++++++++

1、一般会'将nginx的配置信息'写到'数据库'中,然后通过nginx+consul-template 做'配置渲染'

假定: mysql中的 'region'、'集群名'能唯一的决定一个'集群'的配置信息

附加: 其中'upstream_id'是其一个'field'字段

2、利用每个'upstream_id'的schmea的'不能'重复的特性

应用: 根据'upstream_id'获取'后端服务器'列表

补充: 后端服务器列表的信息在'对应服务配置'注册LB,做'配置下发'的时候已经'写入'数据库

③  代码雏形1

openresty灰度,Openresty,openresty,灰度发布

说明: 通过'init_worker_by_block' + 'ngx.timer.every' 实现定时'拉取'redis配置数据

实现: 管理面将策略'下发'到redis后,openresty '定时[5min]'从redis中'拉取'数据  

openresty灰度,Openresty,openresty,灰度发布

遗留: redis'资源池'如何'复用'?

nacos能实现'灰度发布'吗?

灰度用户请求中'打上'标签: 'gray=true'

④  灰度策略管理面

说明: 一般会通过'UI'将策略下发到'redis'中,这里我们'模拟'手动将'key'写到缓存数据库中

关键: redis 'key' 组成,一般会通过':'分割,分割的'每一个字段'都是一个'维度'特征信息

模拟'key': 这里'假定'key是'uuid:ip'形式,讲解一种'简单'的形式,key的'组成'反映'特征'形式

常见: $upstream_id:$tenant  --> 保证这个'key'的唯一性

模拟'value': 'ip:port'形式,要'与'upstream关联[存储在'mysql'中],选取'某个server 节点'

补充: 业界喜欢称一个'upstream'为一个'schema'

后续设计: UI侧可以设置'多种灰度特征策略',然后选取'灰度'节点信息

也即: 在'后台管理系统中'添加'ip'、'用户名'灰度白名单后

+++++++++++++++  "典型案例"  +++++++++++++++

灰度策略配置'UI'侧设计:

 1、'region'、'集群名称'、LB类型 进行 '灰度'策略的下发

 2、对应'server'块的'域名'、'端口'、'location'信息

OpenResty的Redis模块踩坑记录   openresty操作redis,null处理    redis连接池

openresty灰度,Openresty,openresty,灰度发布

1、'遍历'key

2、key的'设计',到底是'hash'结构,还是'其它'数据结构?

⑤   灰度机制

1、'优先'从'本地缓存'中去取

local cacheip = cache_ngx:get('gray_key')

2、本地缓存中'不存在',去'redis缓存服务中'去取,然后加载到'本地'缓存

检查'redis缓存中的键'是否存在 --> if redis_client.exists(key):

if cacheip == "" or cacheip == nil or cacheip == ngx.null then

3、通过本地'ngx.shared 一级'缓存 和 redis'二级'缓存

高并发灰度策略    小破站诡异0问题    openresty最佳实践   灰度发布

⑥  代码雏形2

openresty灰度,Openresty,openresty,灰度发布

细节: balance_by_lua 会 '忽略' upstream中的'server'配置

openresty灰度,Openresty,openresty,灰度发布

用到的'两个'指令: ​​access_by_lua_file 和 ​​balancer_by_lua_file

 1、在'前一个指令'中获取'租户'信息选择'灰度'节点;

 2、在'第二个指令'中根据获取的信息'执行'负载均衡,进行'转发';

不依赖于balance_by_lua实现灰度发布

# 另外一种方式  --> 这种'不依赖'于'balance_by_lua'做判断

upstream  default_route {
   ...
}

location /gray {	
	set $backend 'default_route';
    rewrite_by_lua_file   'lua/gray.lua';  # 获取灰度节点的'逻辑'
	proxy_pass http://$backend;			
}	

强调: 如果使用 'content_by_lua' 这个命令,就'无法'在进行'proxy_pass'了,会'冲突'

openresty实现灰度发布 

利用 proxy_pass 及lua指令 set_by_lua 动态修改当前 upstream 变量实现灰度发布

ngx_balancer.set_more_tries设置不生效,导致无限重试

OpenResty balancer_by_lua负载均衡原理解析    Openresty专栏     跨域

OpenResty火焰图性能分析工具安装     Nginx调试工具Coredump    Lua性能优化

⑦   lua/gray.lua 灰度插件

考虑: 如果'不是灰度白名单',则要使用原来的'负载均衡'策略

--> '如何解决呢?' --> '重点'

最佳实践: 自定义'负载均衡'算法

引申:在'配置'注册的阶段,如果使用'灰度'策略,那么后续如何'取消'呢?

openresty灰度,Openresty,openresty,灰度发布

⑧  lua/gray_access.lua  灰度策略命中

重点: 从redis读取'租户'信息,如果有就'存'到 ​​ngx.ctx​​ 中

-- 太'累'了,九不往这里贴代码了,后续有时间再补充

⑨   测试

思考:用户如何将用户'特征'信息传递过来? --> 'request Header'、'查询参数'

⑩  题外话

local http = require("resty.http")  -->  http'相关'模块

深入理解ngx.log

 lua_code_cache

openresty 项目问题汇总

nginx主动加载配置文件

openresty灰度,Openresty,openresty,灰度发布

openresty性能对比 文章来源地址https://www.toymoban.com/news/detail-730589.html

lua_load_resty_core on|off

自v0.10.16版本起'该指令'就在本模块'失效'了

当前resty.core模块会在'Lua VM初始化'的时候被'强制加载',不需要再显示'require'加载

lua + nginx可以'作为网关'进行 '限流'、'流控'和'多级缓存'使用

到了这里,关于Openresty(二十二)ngx.balance和balance_by_lua终结篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Openresty原理概念篇(九)LuaJIT分支和标准Lua有什么不同

    一  LuaJIT分支和标准Lua有什么不同 ①  背景 luajit官方   标准lua官方   openresty自身维护的luajit  编译luajit ②  LuaJIT 在 OpenResty 整体架构中的位置 ③   标准 Lua 和 LuaJIT 的 关系 ④  为什么 选择LuaJIT ⑤  lua特别之处 pairs和ipairs看table的内部结构 nil、ngx.null、cjson.null、user

    2024年02月11日
    浏览(35)
  • 开源的API Gateway项目- Kong基于OpenResty(Nginx + Lua模块)

    Kong 是一个在 Nginx 内运行的开源 API 网关和微服务抽象层。它是用于处理 API 流量的灵活、可扩展、可插入的工具。 Kong 提供了以下功能: 用户登录 :Kong 提供了多种认证插件,像 JWT、OAuth 2.0 等,可以满足用户登录需求。 Token 管理 :使用上述认证插件,Kong 可以有效地管理

    2024年01月23日
    浏览(44)
  • Windows 环境下nginx 静态资源服务器(图片,文件)权限控制(nginx/openresty/lua)

    1 同nginx配置server以后,我们可以很方便的直接访问到文件服务器上的文件资源,但是某些情况下,文件资源可能是隐私图片,比如客户注册时上传的身份证照片等等,这时候我们需要对图片访问进行控制,必须登录后才能查看到这些隐私图片。 2 一般来说,我们都是通过后端

    2024年02月09日
    浏览(55)
  • 在Openresty中使用lua语言向请求浏览器返回请求头User-Agent里边的值

    可以参考《Linux学习之Ubuntu 20.04在https://openresty.org下载源码安装Openresty 1.19.3.1,使用systemd管理OpenResty服务》安装Openresty。 然后把下边的内容写入到openresty配置文件 /usr/local/openresty/nginx/conf/nginx.conf (根据实际情况进行选择文件): 然后 sudo openresty 启动openresty。 最后在浏览器里

    2024年02月07日
    浏览(62)
  • 安卓玩机搞机技巧综合资源-----修复基带 改串码 基带qcn 改相关参数 终结贴【二十】

    有需要了解这方面常识的友友梦可以先参阅我这几个帖子 请点击跳转 基带qcn的备份与写入相关 格机 nv报错 高通联机修改IMEI等参数的相关解析 关于高通QPST平台功能和选项的一些简单说明 基带qcn的备份与写入相关 格机 nv报错 以上几个帖子可以初步了解基带 串码等参数方面

    2024年02月04日
    浏览(56)
  • 中文编程入门(Lua5.4.6中文版)第十二章 Lua 协程 参考《愿神》游戏

    在《愿神》的提瓦特大陆上,每一位冒险者都拥有自己的独特力量——“神之眼”,他们借助元素之力探索广袤的世界,解决谜题,战胜敌人。而在提瓦特的科技树中,存在着一项名为“协同程序”的高级秘术,它使冒险者能够以一种独特的方式调度和管理自己的行动序列,

    2024年04月28日
    浏览(35)
  • 【Redis】Redis 的学习教程(十二)之在 Redis使用 lua 脚本

    lua 菜鸟教程:https://www.runoob.com/lua/lua-tutorial.html 在 Redis 使用 lua 脚本的好处: 减少网络开销 。可以将多个请求通过脚本的形式一次发送,减少网络时延及开销 原子性操作 。Redis会将整个脚本作为一个整体执行,中间不会被其他请求插入。因此在脚本运行过程中无需担心会出

    2024年02月07日
    浏览(47)
  • 第二十二章 光照贴图

    光照贴图过程将预先计算场景中静态物体表面的亮度,并将结果存储在称为“光照贴图”的纹理中供以后使用。光照贴图可以包含直接光照和间接光照,以及阴影效果。但是,烘焙到光照贴图中的数据无法在运行时更改,这就是为什么移动静态物体后,阴影不会跟随移动。接

    2024年02月02日
    浏览(42)
  • C++学习笔记(二十二)

    概念: 重载函数调用操作符的类,其对象常称为函数对象 函数对象使用重载的 () 时,行为类似函数调用,也叫仿函数 本质: 函数对象(仿函数)是一个类,不是一个函数 特点: 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值 函数对象超出普通函数

    2024年01月18日
    浏览(58)
  • Android——数据存储(二)(二十二)

    1.1 知识点 (1)了解SQLite数据库的基本作用; (2)掌握数据库操作辅助类:SQLiteDatabase的使用; (3)可以使用命令操作SQLite数据库; (4)可以完成数据库的CRUD操作; (5)掌握数据库查询及Cursor接口的使用。 1.2 具体内容 在Android当中,本身提供了一种微型的嵌入式数据库

    2024年02月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包