• 高并发 Nginx+Lua OpenResty系列(4)——Lua 模块开发


    在实际开发中,不可能把所有代码写到一个大而全的lua文件中,需要进行分模块开发;而且模块化是高性能Lua应用的关键。使用require第一次导入模块后,所有Nginx 进程全局共享模块的数据和代码,每个Worker进程需要时会得到此模块的一个副本(Copy-On-Write),即模块可以认为是每Worker进程共享而不是每Nginx Server共享;另外注意之前我们使用init_by_lua中初始化的全局变量是每请求复制一个;如果想在多个Worker进程间共享数据可以使用ngx.shared.DICT或如Redis之类的存储。
    在/usr/openResty/lualib中已经提供了大量第三方开发库如cjson、redis客户端、mysql客户端:
    在这里插入图片描述
    需要注意在使用前需要将库在nginx.conf中导入:

    #lua模块路径,多个之间”;”分隔,其中”;;”表示默认搜索路径,默认到/usr/servers/nginx下找  
    
    lua_package_path "/usr/openResty/lualib/?.lua;;"; #lua 模块
    
    lua_package_cpath "/usr/openResty/lualib/?.so;;"; #c 模块
    

    使用方式是在lua中通过如下方式引入:

    -- 初始化耗时的模块
    local redis =  require("resty.redis")
    local cjson =  require("cjson")
    

    接下来我们来开发一个简单的lua模块。

    vi /usr/openResty/lualib/module1.lua
    

    module1.lua

    local count = 0
    local function hello()
       count = count + 1
       ngx.say("count : ", count)
    end
    
    local _M = {
       hello = hello
    }
    
    return _M
    

    开发时将所有数据做成局部变量/局部函数;通过 _M导出要暴露的函数,实现模块化封装。
    接下来创建test_module_1.lua
    test_module_1.lua

    local module1 = require("module1")
    
    module1.hello()
    

    使用 local var = require(“模块名”),该模块会到lua_package_path和lua_package_cpath声明的的位置查找我们的模块,对于多级目录的使用require(“目录1.目录2.模块名”)加载。

    openResty.conf配置文件

        location /lua_module_1  {
            default_type "text/html";
            lua_code_cache on;
            content_by_lua_file /usr/openResty/lua/test_module_1.lua;
        }
    

    test_module_1.lua

    local model1 = require("model1")
    
    model1.hello()
    

    访问如http://127.0.0.1/lua_module_1进行测试,会得到类似如下的数据,count会递增
    count : 1
    count :2
    ……
    count :N
    此时可能发现count一直递增,假设我们的worker_processes 2,我们可以通过kill -9 nginx worker process杀死其中一个Worker进程得到count数据变化。
    假设我们创建了vim /usr/openResty/lualib/test/module2.lua模块,可以通过local module2 = require(“test.module2”)加载模块
    基本的模块开发就完成了,如果是只读数据可以通过模块中声明local变量存储;如果想在每Worker进程共享,请考虑竞争;如果要在多个Worker进程间共享请考虑使用ngx.shared.DICT或如Redis存储。

  • 相关阅读:
    【MySQL】MySQL的Sequence
    【Spring】Junit加载Spring容器作单元测试
    【Java】JDBC连接MySQL
    【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
    【Java】Map杂谈,hashcode()、equals()、HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap
    【Java】常见的Set类型,HashSet、TreeSet、LinkedHashSet
    【数据结构和算法】选择排序
    【数据结构与算法】插入排序
    【数据结构与算法】冒泡排序
    【Web】写个HTML页面去调试HTTP接口方便些
  • 原文地址:https://www.cnblogs.com/babycomeon/p/11109498.html
Copyright © 2020-2023  润新知