2

我正在使用 OpenResty Nginx,并在 Nginx conf 中有一段 Lua 脚本。(下面的示例,但为简洁起见被截断)。当它位于 nginx.conf 文件中时,它可以正常工作。

rewrite_by_lua '

    -- Load Memcached module
    local memcached = require "resty.memcached"
    local memc, err = memcached:new()
    if not memc then
        ngx.log(ngx.ERR, "Failed to instantiate memc: ", err)
        return
    end
'

但是,如果我将此脚本提取到一个文件中,memcached.lua然后将其包含在 nginx 配置中rewrite_by_lua_file,我将无法重新启动 nginx 并收到有关语法错误的通知,例如:

unexpected "," in /etc/nginx/sites-enabled/memcached.lua

unknown directive "--" in /etc/nginx/sites-enabled/memcached.lua

如果我完全删除 ngx.log 行,语法错误就会消失。

为什么语法在 nginx conf 中有效,但在我将其提取到单独的文件时无效?我在某处读过有关字节码的文章,但不确定这是否相关?

编辑

这是 .lua 文件的完整输出。如果它通过以下方式直接嵌入到 nginx.conf 文件中,则此确切代码有效rewrite_by_lua

cat /etc/nginx/sites-enabled/memcached.lua

-- Define Memcached key
local memcached_key = "saas_" .. ngx.var.host

-- Load Memcached module
local memcached = require "resty.memcached"
local memc, err = memcached:new()
if not memc then
    ngx.log(ngx.ERR, "Failed to instantiate memc: ")
end

-- Set Memcached timeout
memc:set_timeout(1000)

-- Connect to Memcached daemon
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
    ngx.log(ngx.ALERT, "Failed to connect to Memcached: ", err)
end

-- Query for branch name in Memcached
local branch, flags, err = memc:get(memcached_key)
if err then
    ngx.log(ngx.NOTICE, "Failed to get account from Memcached: ", err)
end

-- If branch not found in Memcached, ask MySQL instead
if not branch then

    -- Load MySQL module
    local mysql = require "resty.mysql"
    local db, err = mysql:new()
    if not db then
        ngx.log(ngx.ALERT, "Failed to instantiate MySQL: ", err)
        return
    end

    -- Set MySQL timeout
    db:set_timeout(1000) -- 1 sec

    -- Connect to MySQL daemon
    local ok, err, errno, sqlstate = db:connect{
        path = "/var/run/mysqld/mysqld.sock",
        database = "dbname",
        user = "dbuser",
        password = "dbpass" }
    if not ok then
        ngx.log(ngx.ALERT, "Failed to connect to DB: ", err, ": ", errno, " ", sqlstate)
        return
    end

    -- Define subdomain string by extracting it from the http hostname
    local subdomain = string.match(ngx.var.host, "([%w-]+).")
    local quoted_subdomain = ngx.quote_sql_str(subdomain)

    -- Execute an SQL query to get the branch name based on the subdomain
    local sql = "SELECT branch FROM saas_account WHERE account = " .. quoted_subdomain
    local res, err, errno, sqlstate = db:query(sql, 1)
    if not res then
        ngx.log(ngx.ALERT, "Bad result from DB: ", err, ": ", errno, ": ", sqlstate, ".")
        return
    end

    -- Check we got a result
    if not res[1] then
        ngx.log(ngx.NOTICE, "No docroot was returned for subdomain: ", subdomain)
        ngx.var.branch = "chaletops"
    -- Assign the result from MySQL to the Nginx variable
    else
        ngx.var.branch = res[1].branch

        -- Store the result from MySQL back in to Memcached with a lifetime of 1 hour (3600 seconds)
        local ok, err = memc:set(memcached_key, ngx.var.branch, 3600)
        if not ok then
            ngx.log(ngx.WARN, "Failed to set branch in Memcached: ", err)
            -- return
        end
    end

    -- Save MySQL KeepAlive connection
    local ok, err = db:set_keepalive(10000, 100)
    if not ok then
        ngx.log(ngx.ALERT, "Cannot set MySQL keepalive: ", err)
        return
    end

    ngx.log(ngx.NOTICE, "Loading branch from MySQL: ", ngx.var.branch)

-- Else we did get a result from Memcached
else

    -- Assign the result from Memcached to the Nginx variable
    ngx.var.branch = branch

    ngx.log(ngx.NOTICE, "Loading branch from Memcached: ", ngx.var.branch)

end

-- Save Memcached KeepAlive connection
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
    ngx.log(ngx.ALERT, "Cannot set Memcached keepalive: ", err)
    -- return
end

解决方案

TL:DR - 将 .lua 文件放在 Nginx 配置目录之外。

在被要求发布确切的错误消息后,我不得不重新创建问题。对于参考和谷歌搜索,错误消息如下所示:

2015/12/17 10:04:02 [emerg] 6903#0: unexpected "," in /etc/nginx/sites-enabled/memcached.lua:18

这次我从我的 nginx.conf 中复制了 Lua 代码,并将它放在一个名为的文件中memcached.lua,并保存在我的项目目录中。然后我在我的 nginx.conf 中添加了以下包含来代替 Lua 脚本:

rewrite_by_lua_file /path/to/my/project/memcached.lua;

它立即开始工作!

以前我通过将它从我的项目目录中符号链接到/etc/nginx/sites-enabled/memcached.lua(假设它实际上与包含它的 .conf 一起生活会更好),然后只是使用rewrite_by_lua_file memcached.lua;它,因为它是相对的 .conf 文件。

所以我最初想知道是不是因为该rewrite_by_lua_file函数不能遵循符号链接或其他东西,但后来我意识到这与 Lua 包含语句无关,但显然(现在!)因为符号链接在/etc/nginx/sites-enabled所以 Nginx 是自动尝试加载文件,就好像它是一个普通的 Nginx 配置文件一样。

/etc/nginx/sites-enabled/*这是因为 Nginx(在 Ubuntu/Linux Mint 上)被配置为使用其主配置的路径导入所有配置文件。

我认为我犯这个简单错误的原因是,在带有 Apache 的更高版本的 Ubuntu 上,会发生类似的过程,但是使用 Apache(我更习惯于)你有一个包含路径/etc/nginx/sites-enabled/*.conf- 即它特别需要一个 .conf 文件扩展名,这就是为什么我错误地认为 Nginx 不会尝试包含我的 .lua 文件。

4

0 回答 0