tengine源代码分析(二)--连接配置与C程序的LUA
接前文: tengine源代码分析之编译运行
现在分析,前文中的运行时配置文件,该部分嵌入了控制业务逻辑的LUA代码,也是LUA在nginx中的入口。
本文从此次作为入口,也会涉及到nginx内的代码实现,包括ngx_http_lua模块, ngx_http_ingress模块等。
块:init_by_lua_block
一
configuration.lua 中用到package “ngx”, 他是从哪来的?

通过配置文件,可以看见,是配置文件中有这样一段定义。那么command lua_shared_dict是干嘛用的?

通过代码分析,是设置了名为 certificate_data 的nginx 共享内存。
在初始化 LuaJIT环境时,ngx_http_lua_inject_shdict_api 函数将上述共享内存压入调用栈传递给了LuaJIT框架。
见流程图:

其名为“ngx.shared”,如截图代码所示:


在C语言中使用LuaJIT的典型用法与例子,见链接:
https://luajit.org/install.html#Embedding%20LuaJIT
http://lua-users.org/wiki/SimpleLuaApiExample
二
在configuration.lua中,使用了上述共享内存

在balancer.lua中,引用了 ngx.balancer , 该包有lua_resty_core 提供。

lua_resty_core 默认还提供了其他的包,从其源码中可以看见:

每一个包都配有相应的文档(md),见:
https://github.com/openresty/lua-resty-core?tab=readme-ov-file#ngxbalancer
https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md#set_more_tries
三
分析上一个问题时发现,C函数 ngx_http_lua_ffi_balancer_set_current_peer 并没有被直接调用的地方,
~/Source/tengine-tengine-3.1.0/modules/ngx_http_lua_module/src/ngx_http_lua_balancer.c::ngx_http_lua_ffi_balancer_set_current_peer()
但是看起来跟 ngx.balancer 有关,试分析其作用。
https://groups.google.com/g/openresty/c/vzgaf7mHk4o
题外话:FFI:它允许从纯 Lua 代码调用外部 C 函数,使用 C 数据结构。
https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/FFI.html
上面这个函数,在C代码中与FFI中,都没有找到调用的地方。
最终方向在这里,lua_resty_core, 改库与ngx_lua module约定了变量的名字:

后文 balancer_by_lua_block 部分会详细讲解这一段逻辑
四
plugin
如图,有个plugins模块,可以注册初始化,不过在我们的配置文件里,这里是空的,没有提前加载什么plugin

块:init_worker_by_lua_block
一
lua_ingress.init_worker()很简单,下了个随机数的种子,下面看balancer.init_worker()
这里调用了函数 sync_backends(), 并且启动了一个1s再调用一次的定时器。

相关代码逻辑的流程图:
backend以及相应调度算法的配置通过port10246的http接口进行更新,定时器每隔一秒进行刷新生效。

块:balancer_by_lua_block
该块的配置位置如下:

这部分相关逻辑的流程图:

七层通过http请求进行config的接口
入口在这个地方:
configuration.lua::call()
代码流程图如下, 如图所示,这套接口有4个URI,只能干如下三件事情:
1 变更backend
2 修改证书
3 证书查询。

块:ssl_certificate_by_lua_block
即证书处理流程
如上所述,证书的下发在configuration中已经涉及,下面是证书的处理部分,配置方法如下图:

流程图如下:
主要是证书密钥变更,没有算法,tls版本的变更,但是resty-core貌似提供了,可以二次开发。

块:access_by_lua_block
配置:

跟上边的类似,先设置 llcf->access_handler = ngx_http_lua_access_handler_inline
函数ngx_http_lua_access_handler_inline的功能,跟前边一样,加载lua然后用协程执行。
http 11 阶段的回调框架
各阶段的lua注入点与access都类似,框架相同,流程图见:

块:set_by_lua
这块非常重要,也十分灵活。可以动态变更很多变量的值,所以只要是通过变量设置的配置项就都可以修改。
依赖NDK模块,见前文,流程图如下:

配置文件的典型结构
1 events { 2 } 3 4 http { 5 lua_package_path ""; 6 lua_package_cpath ""; 7 8 init_by_lua_block { 9 pcall(require, "xxx"); 10 plugins.init({"aaa","bbb"}) 11 } 12 13 init_worker_by_lua_block { 14 xxx.init_worker() 15 plugins.run() 16 } 17 18 upstream upstream_balancer { 19 balancer_by_lua_block { 20 balancer.balance() 21 } 22 } 23 24 server { 25 server_name _ ; 26 27 listen 80 default_server reuseport backlog=4096 ; 28 listen [::]:80 default_server reuseport backlog=4096 ; 29 listen 443 default_server reuseport backlog=4096 ssl http2 ; 30 listen [::]:443 default_server reuseport backlog=4096 ssl http2 ; 31 32 ssl_certificate_by_lua_block { 33 certificate.call() 34 } 35 36 location / { 37 set $upstream_read_time $ingress_read_timeout; 38 set $proxy_upstream_name $ingress_route_target; 39 40 access_by_lua_block { 41 } 42 43 content_by_lua_block { 44 } 45 46 log_by_lua_block { 47 } 48 49 rewrite_by_lua_block { 50 } 51 52 header_filter_by_lua_block { 53 lua_ingress.header() 54 plugins.run() 55 } 56 57 body_filter_by_lua_block { 58 } 59 60 proxy_pass http://upstream_balancer; 61 } 62 } 63 }
浙公网安备 33010602011771号