`
jinnianshilongnian
  • 浏览: 21424308 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2403176
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2996176
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5630413
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257187
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1592662
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248795
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5845661
Group-logo
跟我学Nginx+Lua开...
浏览量:697478
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:779851
社区版块
存档分类
最新评论

第四章 Lua模块开发

阅读更多

在实际开发中,不可能把所有代码写到一个大而全的lua文件中,需要进行分模块开发;而且模块化是高性能Lua应用的关键。使用require第一次导入模块后,所有Nginx 进程全局共享模块的数据和代码,每个Worker进程需要时会得到此模块的一个副本(Copy-On-Write),即模块可以认为是每Worker进程共享而不是每Nginx Server共享;另外注意之前我们使用init_by_lua中初始化的全局变量是每请求复制一个;如果想在多个Worker进程间共享数据可以使用ngx.shared.DICT或如Redis之类的存储。

 

在/usr/example/lualib中已经提供了大量第三方开发库如cjson、redis客户端、mysql客户端:

cjson.so

resty/

   aes.lua

   core.lua

   dns/

   lock.lua

   lrucache/

   lrucache.lua

   md5.lua

   memcached.lua

   mysql.lua

   random.lua

   redis.lua

   ……

 

 

需要注意在使用前需要将库在nginx.conf中导入:

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

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

local cjson = require(“cjson”)
local redis = require(“resty.redis”) 

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

vim /usr/example/lualib/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

vim /usr/example/lua/test_module_1.lua
local module1 = require("module1")

module1.hello()

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

 

example.conf配置

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

 

访问如http://192.168.1.2/lua_module_1进行测试,会得到类似如下的数据,count会递增

count : 1

count :2

……

count :N

 

此时可能发现count一直递增,假设我们的worker_processes  2,我们可以通过kill -9 nginx worker process杀死其中一个Worker进程得到count数据变化。

 

 

假设我们创建了vim /usr/example/lualib/test/module2.lua模块,可以通过local module2 = require("test.module2")加载模块

 

基本的模块开发就完成了,如果是只读数据可以通过模块中声明local变量存储;如果想在每Worker进程共享,请考虑竞争;如果要在多个Worker进程间共享请考虑使用ngx.shared.DICT或如Redis存储。

 

 

4
3
分享到:
评论
6 楼 javaDog_li 2018-07-11  
kang19870415 写道
这一章内容我尝试了无数遍也没有成功,后来将模块包中mysql.lua,改成sql.lua也没成功,但直接加入mysql.lua就成功。
这内容是不是少了什么步骤?


如果是导lua package ,有问题, 看看是不是 把导包语句写到了http 里,我开始写到了nginx.conf 头部 是不行的
5 楼 main616 2016-09-12  
main616 写道
假设我们的worker_processes  2,
我们可以通过kill -9 nginx worker process杀死其中一个Worker进程得到count数据变化。


after kill a processor
nginx start a new processor


assume 2 worker_processor workerA & workerB
after curl localhost:8080
workerA process load the lua
do curl again
now count=2

==================kill workerA you will get count=1 ,reload lua
=> the log
2016/09/12 23:40:47 [notice] 9583#0: start worker processes
2016/09/12 23:40:47 [notice] 9583#0: start worker process 9584
2016/09/12 23:40:47 [notice] 9583#0: start worker process 9585
2016/09/12 23:41:00 [debug] 9584#0: *1 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:41:00 [debug] 9584#0: *1 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:41:00 [info] 9584#0: *1 client 127.0.0.1 closed keepalive connection
2016/09/12 23:41:05 [debug] 9584#0: *2 [lua] a_module.lua:5: hello(): count=2
2016/09/12 23:41:05 [info] 9584#0: *2 client 127.0.0.1 closed keepalive connection
2016/09/12 23:41:30 [notice] 9583#0: signal 17 (SIGCHLD) received
2016/09/12 23:41:30 [alert] 9583#0: worker process 9584 exited on signal 9
2016/09/12 23:41:30 [notice] 9583#0: start worker process 9607
2016/09/12 23:41:30 [notice] 9583#0: signal 29 (SIGIO) received
2016/09/12 23:41:37 [debug] 9585#0: *3 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:41:37 [debug] 9585#0: *3 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:41:37 [info] 9585#0: *3 client 127.0.0.1 closed keepalive connection

==================kill workerB you will get count=3 ,not reload
=> the log
2016/09/12 23:43:19 [notice] 9676#0: start worker processes
2016/09/12 23:43:19 [notice] 9676#0: start worker process 9677
2016/09/12 23:43:19 [notice] 9676#0: start worker process 9678
2016/09/12 23:43:31 [debug] 9677#0: *1 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:43:31 [debug] 9677#0: *1 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:43:31 [info] 9677#0: *1 client 127.0.0.1 closed keepalive connection
2016/09/12 23:43:44 [debug] 9677#0: *2 [lua] a_module.lua:5: hello(): count=2
2016/09/12 23:43:44 [info] 9677#0: *2 client 127.0.0.1 closed keepalive connection
2016/09/12 23:44:02 [notice] 9676#0: signal 17 (SIGCHLD) received
2016/09/12 23:44:02 [alert] 9676#0: worker process 9678 exited on signal 9
2016/09/12 23:44:02 [notice] 9676#0: start worker process 9701
2016/09/12 23:44:02 [notice] 9676#0: signal 29 (SIGIO) received
2016/09/12 23:44:05 [debug] 9677#0: *3 [lua] a_module.lua:5: hello(): count=3
2016/09/12 23:44:05 [info] 9677#0: *3 client 127.0.0.1 closed keepalive connection


file a_module.lua
local count = 0
ngx.log(ngx.DEBUG, "======start loading======")
local function hello()
count = count + 1
ngx.log(ngx.DEBUG, "count="..count)
ngx.say("count:",count)
end

local _M = {
hello = hello
}

return _M

file hello.lua
local a_module = require('a_module')
a_module.hello()

conf/nginx.conf
location / {
      default_type          text/html;
      content_by_lua_file   lua/hello.lua;
    }
4 楼 main616 2016-09-12  
假设我们的worker_processes  2,
我们可以通过kill -9 nginx worker process杀死其中一个Worker进程得到count数据变化。


after kill a processor
nginx start a new processor


assume 2 worker_processor workerA & workerB
after curl localhost:8080
workerA process load the lua
do curl again
now count=2

==================kill workerA you will get count=1 ,reload lua
=> the log
2016/09/12 23:40:47 [notice] 9583#0: start worker processes
2016/09/12 23:40:47 [notice] 9583#0: start worker process 9584
2016/09/12 23:40:47 [notice] 9583#0: start worker process 9585
2016/09/12 23:41:00 [debug] 9584#0: *1 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:41:00 [debug] 9584#0: *1 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:41:00 [info] 9584#0: *1 client 127.0.0.1 closed keepalive connection
2016/09/12 23:41:05 [debug] 9584#0: *2 [lua] a_module.lua:5: hello(): count=2
2016/09/12 23:41:05 [info] 9584#0: *2 client 127.0.0.1 closed keepalive connection
2016/09/12 23:41:30 [notice] 9583#0: signal 17 (SIGCHLD) received
2016/09/12 23:41:30 [alert] 9583#0: worker process 9584 exited on signal 9
2016/09/12 23:41:30 [notice] 9583#0: start worker process 9607
2016/09/12 23:41:30 [notice] 9583#0: signal 29 (SIGIO) received
2016/09/12 23:41:37 [debug] 9585#0: *3 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:41:37 [debug] 9585#0: *3 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:41:37 [info] 9585#0: *3 client 127.0.0.1 closed keepalive connection

==================kill workerB you will get count=3 ,not reload
=> the log
2016/09/12 23:43:19 [notice] 9676#0: start worker processes
2016/09/12 23:43:19 [notice] 9676#0: start worker process 9677
2016/09/12 23:43:19 [notice] 9676#0: start worker process 9678
2016/09/12 23:43:31 [debug] 9677#0: *1 [lua] a_module.lua:2: ======start loading======
2016/09/12 23:43:31 [debug] 9677#0: *1 [lua] a_module.lua:5: hello(): count=1
2016/09/12 23:43:31 [info] 9677#0: *1 client 127.0.0.1 closed keepalive connection
2016/09/12 23:43:44 [debug] 9677#0: *2 [lua] a_module.lua:5: hello(): count=2
2016/09/12 23:43:44 [info] 9677#0: *2 client 127.0.0.1 closed keepalive connection
2016/09/12 23:44:02 [notice] 9676#0: signal 17 (SIGCHLD) received
2016/09/12 23:44:02 [alert] 9676#0: worker process 9678 exited on signal 9
2016/09/12 23:44:02 [notice] 9676#0: start worker process 9701
2016/09/12 23:44:02 [notice] 9676#0: signal 29 (SIGIO) received
2016/09/12 23:44:05 [debug] 9677#0: *3 [lua] a_module.lua:5: hello(): count=3
2016/09/12 23:44:05 [info] 9677#0: *3 client 127.0.0.1 closed keepalive connection
3 楼 漫听风月 2016-03-25  
访问如http://192.168.1.2/lua_module_1进行测试,会得到类似如下的数据,count会递增
这个不会递增吧,一直是1
2 楼 newboy2004 2015-12-20  
    location /lua_module_1 {
        default_type 'text/html';
        lua_code_cache on;
        content_by_lua_file /usr/example/lua/test_module_1.lua;
    }

导入这个重新reload  nginx  无法访问
1 楼 kang19870415 2015-10-20  
这一章内容我尝试了无数遍也没有成功,后来将模块包中mysql.lua,改成sql.lua也没成功,但直接加入mysql.lua就成功。
这内容是不是少了什么步骤?

相关推荐

    Android应用开发揭秘pdf高清版

    第4章 用户界面开发 4.1 用户界面开发详解 4.1.1 用户界面简介 4.1.2 事件处理 4.2 常用控件应用 4.2.1 文本框(Textiew) 4.2.2 列表(ListView) 4.2.3 提示(T0ast) 4.2.4 编辑框(EditText) 4.2.5 单项选择(RadioGroup...

    Generation_2:Titan Generation 2 开发。 Titan Generation 2 是一个用 RBX.Lua 编写的大项目。 我计划用每种主要语言(即 Java、Lua、CPP)为它制作一些东西,我至少要完成 34 次。RBX.Lua 是第一代

    我计划用每种主要语言(即 Java、Lua、CPP)为它制作一些东西,我至少有 3/4 的时间才能完成。主要开发人员的注意事项 在任何情况下,都不要将主脚本放在 Github 上,也不要出售脚本。 12packkid 很容易就能猜到 ...

    Cocos2D-X游戏开发技术精解

    第4章 动作功能 100 4.1 概述 100 4.2 动作基类 101 4.2.1 动作类的继承关系 102 4.2.2 动作基类CCAction的成员函数 102 4.2.3 类CCNode中与动作有关的函数 104 4.3 时间动作 105 4.3.1 及时动作 105 4.3.2 持续动作...

    像计算机科学家一样思考Python(第2版).pdf

    第4章 案例研究:接口设计 30 4.1 turtle模块 30 4.2 简单重复 31 4.3 练习 32 4.4 封装 33 4.5 泛化 34 4.6 接口设计 34 4.7 重构 35 4.8 一个开发计划 36 4.9 文档字符串 37 4.10 调试 38 ...

    EM-X1.06 2D游戏开发软件

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件,工具更加高效。 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏。 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库等编辑工具)...

    SOUI入门文档(第一版).pdf

    SOUI入门文档(第一版) 针对于SOUI的说明文档 简介 SOUI为一款由个人(启程软件)开发并开源的C++ DirectUI库。基于DuiEngine经过重构跟优化完成的一个新的版本(DuiEngine是一个基于原金山的Bkwin重构的UI库,...

    Edgame make脚本游戏大师v1.3(无例程)

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件,工具更加高效。 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏。 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库等编辑工具)...

    EM脚本游戏制作大师X系1.5版

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件, 工具更加高效。 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏。 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库...

    Edgame Maker 1.1 正式版

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件,工具更加高效. 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏. 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库等编辑工具). 5...

    Edgame Maker 1.1正式版

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件,工具更加高效. 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏. 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库等编辑工具). 5...

    Edgame Maker 1.2版

    2.方便外接各种插件,支持纯中文易语言DLL,搭配各种第三方扩展类,模块,插件,工具更加高效. 3.脚本速度优秀,可制作各种类型2D游戏,包含网络游戏. 4.提供大量辅助工具(各种类型游戏地图,关卡,脚本,数据库等编辑工具). 5...

    AppEmit.zip

    4) 开发本地硬件DLL驱动模块的封装插件,实现在网页中操作控制本地的读卡器、打印机、扫描仪、高拍仪、U盾等各种硬件设备 5) 各个应用程序之间通信,比如聊天 6) 在Chrome里嵌入IE内核网页,保护源码,可以不修改...

    网狐荣耀版开发使用常见问题解答

    第四步,填写好各个相关信息,注意密码那里和上个页面的一致。其它随便。然后下一步,选择打包APK文件的存储路径。 第五步,点击finish等待程序签名与APK的生成,结束。 六、网狐荣耀版游戏启动时出现“正在初始...

    网站安全狗Linux-Nginx版(32位)v2.4.2.gz

    2、新增对lua-nginx-module-master模块支持; 3、新增对nginx_upstream_check_module-master 模块支持; 4、新增对nginx-backtrace-master 模块支持; 5、新增对ngx_http_accounting_module-master模块支持; 6...

    单点登录源码

    | ├── zheng-upms-dao -- 代码生成模块,无需开发 | ├── zheng-upms-client -- 集成upms依赖包,提供单点认证、授权、统一会话管理 | ├── zheng-upms-rpc-api -- rpc接口包 | ├── zheng-upms-rpc-...

Global site tag (gtag.js) - Google Analytics