Nginx openrestylua脚本只工作一次
以下代码按预期工作,但只执行一次Nginx openrestylua脚本只工作一次,nginx,lua,openresty,Nginx,Lua,Openresty,以下代码按预期工作,但只执行一次 require("loadCheckfile") require("checkValPairs") local checklist = loadCheckfile("/home/myname/code/workbench/src/check.lst") local keyList = {} local valList = {} -- Load GET arguments into tables local args = ngx.req.get_uri_a
require("loadCheckfile")
require("checkValPairs")
local checklist = loadCheckfile("/home/myname/code/workbench/src/check.lst")
local keyList = {}
local valList = {}
-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
-- Show wether the combination fits or not
ngx.say(doesFit)
在第二次运行时,即使是从新的浏览器窗口,我也会遇到以下错误:
*1 lua条目线程中止:运行时错误:/home/myname/code/workbench/src/handler。lua:3:尝试调用全局“loadCheckfile”(一个nil值)
nginx.conf(仅用于开发,不是最终版本):
loadCheckfile.lua:
local function fillChecklistTable(checklist, valueLine)
repeat
firstValLength = string.find(valueLine,"=")
firstVal = string.sub(valueLine, 1, firstValLength-1)
valueLine = string.sub(valueLine, firstValLength+1)
secondValLength = string.find(valueLine, ",")
if secondValLength ~= nil then
secondVal = string.sub(valueLine, 1, secondValLength-1)
else
secondVal = valueLine
end
if checklist[firstVal] == nil then
checklist[firstVal] = {secondVal}
else
table.insert(checklist[firstVal], secondVal)
end
if secondValLength ~= nil then
valueLine = string.sub(valueLine, secondValLength+1)
else
valueLine = nil
end
until valueLine == nil
end
checklist = {}
function loadCheckfile(checkfile)
local values = io.open(checkfile)
local valueLine = values:read()
while valueLine ~= nil do
fillChecklistTable(checklist, valueLine)
valueLine = values:read()
end
return checklist
end
有人知道这家伙又做错了什么吗?提前谢谢
更新:
汉德勒·卢阿
checklist = {}
local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/pw_list.txt")
local keyList = {}
local valList = {}
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
ngx.say(doesFit)
loadCheckfile.lua
module("loadCheckfile", package.seeall)
local function fillChecklistTable(checklist, valueLine)
repeat
firstValLength = string.find(valueLine,"=")
firstVal = string.sub(valueLine, 1, firstValLength-1)
valueLine = string.sub(valueLine, firstValLength+1)
secondValLength = string.find(valueLine, ",")
if secondValLength ~= nil then
secondVal = string.sub(valueLine, 1, secondValLength-1)
else
secondVal = valueLine
end
if checklist[firstVal] == nil then
checklist[firstVal] = {secondVal}
else
table.insert(checklist[firstVal], secondVal)
end
if secondValLength ~= nil then
valueLine = string.sub(valueLine, secondValLength+1)
else
valueLine = nil
end
until valueLine == nil
end
checklist = {}
function loadCheckfile.loadCheckfile(checkfile)
local values = io.open(checkfile)
local valueLine = values:read()
while valueLine ~= nil do
fillChecklistTable(checklist, valueLine)
valueLine = values:read()
end
return checklist
end
据我所知,我只将模块放入loadCheckfile.lua和checkValPairs.lua中。但即使把它放进
handler.lua不起作用(只是需要尝试一下) 使用
lua\u code\u cache off
是一个很大的性能问题,因为它将一次又一次地执行代码。试试这个
local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/check.lst")
让我知道这是否有效,我将添加一个解释注意 请不要使用此解决方案。虽然它确实有效,但并不好。 我将把它留在这里,以便理解其中一个答案 原始答案: 我的问题的解决方案是通过nginx.conf使模块成为全局的 因此,我在配置中插入了一个
init_by_lua_文件
,调用一个预加载的lua文件,该文件包含了我需要的所有函数,在全局级别上提供了该函数
.conf:
user root;
worker_processes 1;
daemon off; #used for developing purpose
error_log /dev/stdout warn; #as well for developing
events {
worker_connections 32;
}
http {
default_type text/html;
access_log off;
lua_package_path '/home/myname/code/workbench/src/?.lua;;';
init_by_lua_file '/home/myname/code/workbench/src/preLoader.lua';
server {
listen 80;
location / {
content_by_lua_file /home/myname/code/workbench/src/handler.lua;
}
}
}
新的preload.lua:
require("loadCheckfile")
require("checkValPairs")
checklist = loadCheckfile("/home/myname/code/workbench/src/check.list")
最后是handler.lua:
local keyList = {}
local valList = {}
-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
table.insert(keyList, key)
table.insert(valList, val)
end
-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))
local key1
-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
if keyList[i] == "user" then
key1 = i
for j = 1, table.maxn(keyList) do
if keyList[j] == "pass" then
doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
end
end
end
end
-- Show wether the combination fits or not
ngx.say(doesFit)
你的解决方案应该是可行的,但是有一些事情需要知道 OpenResty为每个请求创建一个具有全新全局环境的协同程序(Lua绿色线程),但是
require()
只加载一次模块,不再执行其主块。所以,您在这些模块中设置的所有全局变量仅在第一次请求期间存在。此外,如果您的处理程序进行i/o操作,则会有一个窗口供第二个请求到达并窃取其全局部分,因此不会完成任何请求。准确的解决方案是永远不要在OpenResty中的模块中设置全局变量(在普通Lua中也是如此,因为破坏\u G
通常是个坏主意),而是遵循标准的模块习惯用法:
-- mymod.lua
local M = { }
local function private() -- for internal use
...
end
function M.public() -- to be 'exported'
...
end
return M -- this will be returned from require
-- uses_mymod.lua
local mymod = require 'mymod' -- mymod is M from above
mymod.public()
通过这种方式,模块创建一个包含函数的表,而不是将它们设置为全局函数,并将其返回到require()
require()
将在每次调用时返回它
当您对本地函数的可见性规则感到厌倦时,请引入另一个localm={}
或任何您想命名的名称,并将所有私有项存储在那里。在这变得难看之后,请选择高级主题,如Lua环境(setfenv()
,setmetatable()
)。如果您不想了解详细信息,请在每个模块的localm={}
前面加上这一行:
setfenv(1, setmetatable({ }, { __index = getfenv(0) }))
您的所有全局文件都是该模块的本地文件,因此您可以避免m
(但不是m
,仍然是“导出”所必需的)。同时发布nginx配置并加载检查文件,以及将lua\u code\u缓存添加到nginx.conf中解决了问题。然而,我非常怀疑这是否适合工作环境。我得到一个错误,行localchecklist=checkFile.loadCheckfile(“/home/myname/code/workbench/src/check.lst”)
表示试图索引本地“checkFile”(布尔值)将其添加到文件模块(“loadCheckfile”,package.seeall)的顶部,更改另一个文件的名称,并查看它是否工作。它仍在尝试索引本地“checkFile”(布尔值)。在问题中发布更新的代码以及错误详细信息。谢谢你的努力,我真的觉得我在这件事上抓住了那个笨蛋-谢谢。你的回答帮助我理解了我原来问题中的错误。我从未在模块末尾返回函数,只是返回函数本身中的表。
setfenv(1, setmetatable({ }, { __index = getfenv(0) }))