Nginx之lua实现机制

1.  nginx_lua原理

    ngx_lua将lua集成进Nginx

    Lua内建协程,协程调用异步API,然后协程挂起,在异步回调事件到来时,再将协程唤醒,继续执行。

    这样既可以实现全异步的Nginx机制,不会影响nginx的高并发处理性能,又使开发者以同步的方式编写异步程序,使代码复杂性大为降低。

    ngx_lua中Lua的I/O操作都委托给Nginx事件模型,从而实现完全的非阻塞调用。

    ngx_lua在Nginx的管理/工作进程机制基础上加入了Lua解释器或虚拟机。

    ngx_lua在每一个Nginx工作进程上执行一个Lua解释器或LuaJIT实例,这个工作进程上处理的所有请求共享这个实例。

    每个请求的上下文都被Lua的协程分割,保证每个请求都是独立的。

    ngx_lua采用 “一个请求一个协程”的处理模型,对于每个用户请求,ngx_lua都会创建一个协程用于执行用户代码以处理请求,请求处理完毕,协程会被销毁。

    协程是轻量级线程,所以占用极少内存,通常每个请求ngx_lua只会占用2KB左右内存。协程不能同时运行。 

    下面是一个简单的ngx_lua请求处理流程      

    ffbcc52b516da381fe170cbbdf8b195a

 2.  HTTP请求的处理阶段

    参考另外一篇文章https://www.cnblogs.com/yangjianbo/articles/19113524

3.  ngx_lua的处理阶段

    ngx_lua在HTTP处理阶段基础上,分别在Rewrite/Access阶段,content阶段,log阶段注册了自己的handler,加上系统初始阶段master的两个阶段,共11个阶段为Lua脚本提供处理介入的能力

    指令可以在http,server ,server if ,location,location if几个范围进行配置

    1.  Lua可以使用的主要阶段流程    

        2ed05f608a11e3671a9caa6cf589729c

    2.  Lua指令使用        

        7a9b88238e882a1108ebb5f4916c6d27

        ec5ce9ef0fb4644bf9f3906eed96c30b

 4.  Lua阶段详细解析

    1.  init_by_lua

        init_by_lua 在每次 Nginx 重新加载配置时执行,可用来完成一些耗时模块的加载,或者初始化一些全局配置。在管理进程创建工作进程时,指令中的全局变量会复制到工作进程中。

          1.  在nginx.conf的http模块中写入

# 设置全局共享变量(字典),名字为 shared_data 共享内存的大小是1M
 
lua_shared_dict shared_data 1m;
 
init_by_lua_file /tmp/init.lua;                     # 初始化的lua代码位置

          2.  编写init.lua

-- init_by_lua_file 在 Nginx 启动时执行一次(所有 worker 共享)
local shared_data = ngx.shared.shared_data
shared_data:set("count", 1)
ngx.log(ngx.INFO, "init.lua 初始化完成,count=1")

          3.  编写test.lua

-- 对全局变量进行+1操作
 
count = count + 1
 
-- 输出全局变量的值
 
ngx.say("global variable : ", count)
 
-- 获取共享内存的值
 
local shared_data = ngx.shared.shared_data
 
ngx.say(", shared memory : ", shared_data.get("count"))
 
-- 对共享内存的值 + 1 操作
 
shared_data:incr("count", 1)
 

          4.  增加location测试

location /lua {
    default_type "application/json";
 
    content_by_lua_file "test.lua"
}
 
// 启动 Nginx ,访问 /lua 可见全局变量一直保持不变,共享内存中的变量每次访问依次 + 1,因为共享内存的变量只在 Nginx 退出后才被收回,而每个 worker 接受 /lua 请求后都能获取共享变量并执行 test.lua 文件

  

  

  

  

            

 

 

        

 

   

posted @ 2025-10-09 17:43  奋斗史  阅读(8)  评论(0)    收藏  举报