高併發 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

相關文章
相關標籤/搜索