2014-09-21 89 views
0

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

例如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查询作为变量并返回结果。

回答

0

首先,使用数据库进行基本路由听起来不是一个好主意 - 我建议将结果缓存在内存中,并可能定期从数据库刷新它们。其次,基本的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更合适。

0

感谢您的帮助。它不适合我,但经过很多工作,我终于有了一些工作。这是为别人,如果他们需要它

事实证明$ 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; 
相关问题