高并发 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中导入:html

#lua模块路径,多个之间”;”分隔,其中”;;”表示默认搜索路径,默认到/usr/servers/nginx下找  

lua_package_path "/usr/openResty/lualib/?.lua;;"; #lua 模块

lua_package_cpath "/usr/openResty/lualib/?.so;;"; #c 模块

使用方式是在lua中经过以下方式引入:mysql

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

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

vi /usr/openResty/lualib/module1.lua

module1.luaweb

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.luaredis

local module1 = require("module1")

module1.hello()

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

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存储。json

相关文章
相关标签/搜索