在实际开发中,不可能把所有代码写到一个大而全的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存储。

最新文章

  1. Unity WebGL MoonSharp崩溃问题
  2. Java—多线程编程
  3. Android中实现多彩的霓虹灯
  4. js随机点名
  5. C语言 指针与字符串
  6. 【BZOJ】1090: [SCOI2003]字符串折叠(dp)
  7. [转]ubuntu错误解决E: Sub-process /usr/bin/dpkg returned an error code (1)
  8. python:笔记for循环中的else
  9. Struts2动态调用DMI及错误解决方法
  10. android开发之使用上下文菜单
  11. linux磁盘管理增加,扩容
  12. 家庭记账本之微信小程序(六)
  13. 转载-js如何设置网页横屏和竖屏切换
  14. USACO 好题汇总
  15. spring -mvc service层调用工具类配置
  16. 20145304 刘钦令 Exp2 后门原理与实践
  17. jquery validate不用submit提交,用js提交的
  18. 图论1 Tarjan算法
  19. leetcode 题解 || Remove Nth Node From End of List 问题
  20. 源代码管理git的使用

热门文章

  1. 计算广告(computational advertising)
  2. 微信公众平台消息接口开发(12)消息接口Bug
  3. 利用Adorner制作用于图像裁切的选择框
  4. ‘3 sigma’rule(68–95–99.7 rule)
  5. C++ string的那些坑,C++ string功能补充(类型互转,分割,合并,瘦身) ,c++ string的内存本质(简单明了的一个测试)
  6. WPF应用程序内嵌网页
  7. libev整体设计
  8. springboot 集成swagger ui
  9. Xml格式的Bared和Warpped
  10. WPF中TextBlock文本换行与行间距