5

我一直在尝试找到一种方法来首先捕获环境变量 HOSTNAME,然后使用 MySQL 查询来获取并返回 Nginx conf 文件根目录为我们的虚拟主机。我们将它们用于当前在 Apache 中但正在迁移到 Nginx 的动态文档根。

nginx.conf 示例(可能看起来像这样):

server {
    listen   80;
     # grab Environment variable HOSTNAME
     $hostname= ENV(HOSTNAME);
     # execute mysql query
    $doc_root = mysql(select docroot from table where host = '$hostname' );
     # set document root
    root           /var/www/$doc_root;

.....我正在探索使用 Lua 和https://github.com/openresty/lua-resty-mysql 但一直无法弄清楚如何将 HOSTNAME 和 mysql 查询捕获为变量并返回结果回来了。

4

2 回答 2

4

谢谢你的帮助。它对我不起作用,但经过大量工作,我终于得到了一些工作。这是给其他人的,如果他们需要的话

事实证明 $http_host 已经在 nginx 中全局定义了 - 所以这是固定的。

        set $httphost $http_host; # create and initialize var
        set $docroot "";

    # begin LUA scripting
    rewrite_by_lua '
                    -- make sure http host is defined
                    if not ngx.var.httphost then
                      ngx.log(ngx.ERR,"ERROR - no httphost defined")
                      return
                    end

                       -- begin mysql
                    local mysql = require "resty.mysql"
                    local db, err = mysql:new()

                    db:set_timeout(1000) -- 1 sec

                    local ok, err, errno, sqlstate = db:connect
                    {
                            host = "127.0.0.1",
                            port = 3306,
                            database = "db",
                            user = "user",
                            password = "password",
                            max_packet_size = 1024 * 1024
                    }

                    if not ok then
                      ngx.log(ngx.ERR,"MySQL failed to connect: ", err, ": ", errno, " ", sqlstate)
                      return
                    end

                    -- prevent injection attack
                    local hname = ngx.unescape_uri(client)
                    local quoted_name = ngx.quote_sql_str(hname)

                    local sql = "select docroot from users where customer =" .. quoted_name
                    result,err,errno,sqlstate = db:query(sql,1)
                    if not result then
                       ngx.log(ngx.ERR,"MySQL bad result: ", err, ": ", errno, ": ", sqlstate, ".")
                       return
                    end

                    if not result[1].docroot then
                      ngx.log(ngx.ERR,"MySQL ERROR - no docroot was returned")
                      return
                    end

                    ngx.var.docroot = result[1].docroot
            ';
           # now we can set the docroot for this host
          root           /var/www/$docroot;
于 2014-09-22T01:24:28.160 回答
1

首先,使用数据库进行基本路由听起来不是一个好主意——我建议将结果缓存在内存中,并可能定期从数据库中刷新它们。

其次,基本的 Nginx 配置文件只能为您提供到目前为止 - 为了获得更高级的功能,您需要在其之上使用脚本语言(如 Lua)。这允许您读取环境变量的一件事。我在这里写了如何做到这一点:

https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html

让 Lua 在 Nginx 上运行的常用方法是使用 Openresty,这是 Nginx 的一个版本,预装了几个模块,包括 Lua 模块。你可以添加lua-resty-mysql到组合中,然后直接从 Lua 做你想做的一切。我从未使用过 lua-resty-mysql,所以我无法为您编写代码。如果你打算使用 Mysql,你将不得不研究它的文档。边看边看 Redis,它可能比 Mysql 更合适。

于 2014-09-21T11:33:12.620 回答