🙈 By 洪昕 2024-05-07
OpenNJet 是基于Nginx fork并独立演进的应用引擎,提供的Lua脚本运行能力移植自OpenResty 社区开源的lua-nginx-module 模块,该开源的Lua模块可以将Lua脚本通过内嵌的方式直接写在配置文件中,或者通过 *_by_lua_file 的指令(如content_by_lua_file, access_by_lua_file) 写在外部文件中。
Nginx 上难于进行动态化配置的问题,同样存在于Lua脚本的修改上。一旦完成初始配置,脚本内容进行修改后,需要生效一般只能通过两种方式。其一是服务进程重新加载配置(reload),另一种方案是将脚本放置于外部文件,并通过配置 lua_code_cache off的方式关闭代码缓存机制,但这种方式只适用于开发阶段,生产环境并不适用。
OpenNJet 架构设计已经考虑了动态配置的问题,Lua 脚本内容的修改上,使用架构提供的能力,在兼顾性能的情况下,实现了无需重启或重加载,实时更新Lua脚本的功能。
1 功能说明
Lua动态配置能力,通过模块 ”njt_http_dyn_lua_module”实现,使用时需要在数据面的配置文件中加载该模块。
在文件njet.conf中,首先配置测试的server及location, 接下来的功能演示测试中将用到, 配置如下:
worker_processes auto;
cluster_name njet;
node_name node1;
error_log logs/error.log error;
helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
helper broker modules/njt_helper_broker_module.so;
load_module modules/njt_http_location_module.so;
load_module modules/njt_http_lua_module.so;
load_module modules/njt_http_dyn_lua_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
access_log off;
lua_package_path "$prefix/lualib/lib/?.lua;/usr/local/njet/modules/?.lua;;";
lua_package_cpath "$prefix/lualib/clib/?.so;;";
upstream weba {
server 127.0.0.1:8888;
}
server {
listen 8888;
location / {
return 200 "return from server8888\n";
}
}
server {
listen 8080;
location / {
root html;
}
location /lua {
content_by_lua_block {
njt.say("lua test")
}
}
}
}
该配置文件使用内嵌的方式,在location /lua 下, 配置了content_by 脚本。服务进程启动后, 访问该测试地址,可以看到输出的内容。
通过查询接口,获取当前配置。
通过Restful 接口提交新的Lua脚本内容,变更将实时生效,不需要重加载配置。
除了修改content_by 脚本内容,还可以添加或修改access 阶段的脚本。
2 进阶场景
结合OpenNJet 的动态Location 配置能力,可以实现更为复杂的场景。
例如设计如下场景:
-> 动态添加一个location, location 中使用proxy_pass 代理到后端服务
-> 使用动态Lua设置,覆盖掉proxy_pass的配置,输出Lua 脚本中的内容
-> 动态删除location
-> 重新添加location
场景验证如下:
动态Lua 配置,目前实现了最为常用的content_by, access_by 两个阶段,能够实时替换当前服务进程使用的Lua脚本内容,后续也可以逐步将动态配置能力扩展到其它阶段(如log_by, header_filter, body_filter)。