这里,我希望通过参数来判断要执行的功能,并获取指定lua代码目录下是否有相应的文件,如果有存在就执行,不存在就执行。但是这样也存在一个io的操作。而且代码缓存后,上次判断不存在的文件,下次执行时是否会一直认为不存在?
另外在lua中这样执行一个指定文件中的代码有哪些好的方法吗?(类似于PHP中include 功能)
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
1. 希望用nginx+lua实现类似网站统计的功能(页面PV,页面点赞这类的统计功能),原来的接口全是NGINX+PHP+MEMCACHE实现,现在希望能够使接口更快响应请求,采用了NGINX+LUA+REDIS做接口响应,后台功能仍然是采用PHP,以及用PHP去分析整理LUA接口采集到的数据。
1. 希望用nginx+lua实现类似网站统计的功能(页面PV,页面点赞这类的统计功能),原来的接口全是NGINX+PHP+MEMCACHE实现,现在希望能够使接口更快响应请求,采用了NGINX+LUA+REDIS做接口响应,后台功能仍然是采用PHP,以及用PHP去分析整理LUA接口采集到的数据。
Hello!
你好,用require代替loadstring可以么?目前的需求:已经被require的模块,后续还会修改,然后在不reload的情况下生效,即本次讨论的热加载。目前的方案:在shmdict中设置标志符号,在请求来到时发现置位后将package.loaded[module]=nil ,然后将标志符号反置位不让其反复require,这样就会执行一次require重新加载热的代码,有一个问题就是这个请求让一个worker热加载了后将dict中的标志符号反置位后,其它worker咋办呢,它们不能够热加载了
在 2015年4月6日星期一 UTC+8下午1:23:34,阿杜.shzz写道:噢,我忽略了 nginx 多 worker 的运行方式。用 ngx.shared.DICT 来协调各 worker 主动触发代码热更新这个方法很棒!
在 2015年4月6日星期一 UTC+8下午12:13:04,agentzh写道:Hello!
2015-04-05 20:50 GMT-07:00 阿杜.shzz:
> 对官方最新版(ngx_openresty-1.7.10.1)做了下测试 —— 配置 location /codechange {} ,在运行时动态修改
> package.loaded[modname] = nil ,操作成功,可以触发对应模块的重新加载,你可以用这种方法来做代码热更新。
>
loadstring + package.loaded 是标准玩法,但要仔细一些限制,比如被加载的 Lua 代码里不能通过 ffi.cdef
等接口定义新的 FFI 符号或通过 ffi.load 动态加载 .so 文件,否则在卸载 Lua
代码时会有内存错误。这个问题先前在这个邮件列表里面讨论过,比如
https://groups.google.com/d/msg/openresty/5ZLuSCQYh9w/wQTLRnRtFnkJ
在 CloudFlare 的 Lua CDN 系统中,我们就是使用的 loadstring + package.loaded 这个
trick,同时被加载的 Lua 代码是通过 KyotoTycoon 动态分发到 CloudFlare 的全球网络。
Regards,
-agentzh
--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty+subscribe@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+unsubscribe@googlegroups.com
local _M = {
_VERSION = '108',--构建版本号
shd_key = 'bu_version',
}
return _M
local version_path = 'dloading.version'
local main_path = 'dloading.main'
--上一版本
local cached_version = require(version_path)
package.loaded[version_path] = nil
--最新版本
local version = require(version_path)
--如果版本变更上线,重新加载指定的模块
local dloading = ngx.shared.dloading
dloading:set(version.shd_key, version._VERSION)
if version._VERSION and cached_version._VERSION and version._VERSION ~= cached_version._VERSION then
--代码上线后,更新代码缓存
package.loaded[main_path] = nil
local dyload = require(main_path)
dyload:reload_change()
ngx.say('up to '.. version._VERSION)
else
ngx.say('no update '.. version._VERSION)
end
--用于代码动态加载
local cached_version = require"dloading.version"
local ipairs = ipairs
local str_find = string.find
local _M = {}
_M.check_version = function(self)
local dloading = ngx.shared.dloading
local build_version = dloading:get(cached_version.shd_key)
if build_version and cached_version._VERSION and build_version ~= cached_version._VERSION then
self:reload_change()
end
end
--更新被加载的模块
_M.reload_change = function(self)
local cached_mod = package.loaded
local tmp_var
for k,v in pairs(cached_mod) do
if self:match_reload_dir(k) then
cached_mod[k] = nil
tmp_var = require(k)
end
end
end
--只有预定义的目录支持热加载,业务代码目录
_M.match_reload_dir = function(self, mod_name)
local reload_dir_or_file = {
'lib.',
'conf.',
'api.',
'model.',
'index',
}
local pos_start, pos_end
for _,v in ipairs(reload_dir_or_file) do
pos_start, pos_end = str_find(mod_name, v)
if pos_start and pos_start == 1 then
return true
end
end
return false
end
return _M
--动态加载
local dloading = require"dloading.main"
dloading:check_version()
location = /dloading { content_by_lua_file 'path/to/dloading/check_version.lua'; }
1. 希望用nginx+lua实现类似网站统计的功能(页面PV,页面点赞这类的统计功能),原来的接口全是NGINX+PHP+MEMCACHE实现,现在希望能够使接口更快响应请求,采用了NGINX+LUA+REDIS做接口响应,后台功能仍然是采用PHP,以及用PHP去分析整理LUA接口采集到的数据。