Nginx+Lua+Redis配置


  想在Nginx上開發具有這樣功能的一個轉發模塊,外部轉發策略控制服務器將一些指定的URL發送給數據庫,Nginx讀取數據庫中的URL列表,將列表指定的這些URL轉發到特定的緩存代理服務器上,其他非數據庫URL列表中的URL請求直接通過Nginx轉發到出口網關上。實際上以上的功能就是很多網站利用Nginx做負載均衡時的實現的七層轉發功能,不太一樣的是,我想加一個外部的轉發策略控制服務器將一些實時的URL列表發送給Nginx,這樣如果這些URL信息是根據大數據處理結果統計出的最高熱點訪問URL,就可以在Nginx上實現基於內容熱度的七層轉發。

  以上是后續要完成的目標,看了看網上的資料,目前有這方面的類似模塊,就是Nginx+HttpLuaModule+Redis的實現方式,Nginx不用多說是服務器,HttpLuaModule是由淘寶的工程師清無(王曉哲)和春來(章亦春)所開發的nginx第三方模塊,它能將lua語言嵌入到nginx配置中,從而使用lua就極大增強了nginx的能力。Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日志型、Key-Value數據庫,並提供多種語言的API,說簡單了就是內存數據庫,效率高。這三個模塊組合在一起的基本流程是url請求nginx服務器,然后lua查詢redis,返回數據,這種方式依然保持高並發。廢話不多說了下面將配置方式,中間遇到了各種坑,不過幸好最后都成功解決。

  方式一:

  直接安裝OpenResty,OpenResty是Nginx打包裝好了各種模塊,包括Lua等等。具體可以看官方主頁:

  主頁:http://openresty.org/

  但是我沒有選擇這種傻瓜,沒有困難制造困難也要上,下面是手動配置Nginx+Lua+Redis步驟。

  方式二:

  1.下載Nginx源碼

  http://nginx.org/en/download.html

  下載和解壓都在目錄 /home/zjf/ 下進行的

  cd /home/zjf

  tar -zxvf nginx-1.6.2 

  解壓后出現以下目錄

  /home/zjf/nginx-1.6.2

  先不編譯Nginx,接着下載其他需要的模塊

  2.配置HttpLuaModule模塊

  2.1   下載並編譯安裝LuaJIT 2.0 

             HttpLuaModule模塊需要LuaJIT 2.0(推薦LuaJIT-2.1)或者Lua 5.1(Lua 5.2不支持)

      下載鏈接:http://luajit.org/download.html

      下載文件:LuaJIT-2.0.3.tar.gz

     解壓到:/home/zjf/luajit-2.0.3/

     編譯並安裝: cd /home/zjf/luajit-2.0.3/

            make 

            sudo make install

     2.2    下載ngx_devel_kit

     下載鏈接:https://github.com/simpl/ngx_devel_kit/tags

     下載文件:ngx_devel_kit-0.2.19.tar.gz

     解壓到:/home/zjf/ngx_devel_kit-0.2.19

  2.3    下載ngx_lua

           下載鏈接:https://github.com/openresty/lua-nginx-module/tags

      下載文件: lua-nginx-module-0.9.13rc1.tar.gz

      解壓到:/home/zjf/lua-nginx-module-0.9.13rc1

      2.4    將以上模塊和Nginx一起編譯 

      第一次編譯的時候出現了error:

      error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory  

        參考了http://blog.csdn.net/vboy1010/article/details/7868645的解決方法,我用的是在編譯前導入環境變量的方法

            export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH 

      或者在編譯時加入選項 --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" 如下

 # tell nginx's build system where to find LuaJIT 2.0:
    export LUAJIT_LIB=/usr/local/include/luajit-2.0/
    export LUAJIT_INC=/usr/local/lib/

#configure Nginx .
/configure --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" --prefix=/usr/local/nginx/ --add-module=/home/zjf/ngx_devel_kit-0.2.19/ --add-module=/home/zjf/lua-nginx-module-0.9.13rc1/ make -j2 make install

   2.5  測試Nginx+HttpLuaModule模塊

     經過以上的步驟Nginx的HttpLuaModule模塊就配置完成了,在瀏覽器輸入localhost地址會出現Nginx服務器的歡迎界面,表示Nginx正常工作,如果不能正常工作,考慮是不是有其他已安裝的服務器占用了端口。

     編輯/usr/local/nginx/conf/nginx.conf 文件看到server{...}內會有如下默認配置,這個是歡迎網頁的url配置。

        location / {
               root   html;
               index  index.html index.htm;
          }

             我們再加入如下配置:

     location /lua {  
              default_type 'text/plain';  
              content_by_lua 'ngx.say("hello, lua")';  
      }  

     然后訪問localhose/lua,返回字符hello,lua,則證明Lua模塊配置成功,Nginx成功的使用Lua輸出了字符串hello,lua。

    3.安裝Redis數據庫

     redis安裝很簡單,下載-解壓-安裝即可,下載地址 http://www.redis.io/download

     tar -zxvf redis-2.8.6.tar.gz

     cd /home/zjf/redis-2.8.6

     make 

              sudo make install

    4.安裝lua-resty-redis-master

     lua-resty-redis-masters是Lua client driver for the ngx_lua based on the cosocket API,也就是Nginx通過Lua操作Redis數據庫的驅動模塊。

     下載地址:https://github.com/openresty/lua-resty-redis

     解壓后的目錄為:/home/zjf/lua-resty-redis-master

     配置nginx.conf文件

     在http{...}段內加入以下路徑,讓nginx可以根據剛才的解壓目錄找到redis.lua模塊驅動文件,目錄不同可以根據情況修改,只要找到redis.lua即可。

 lua_package_path "/home/zjf/lua-resty-redis-master/lib/resty/redis.lua;;";

     然后加入一個新的location,用/test的URL來測試該模塊是否配置成功。

    location /test {
        default_type 'text/plain';
            content_by_lua '
                local redis = require "resty.redis"
                local red = redis:new()

                red:set_timeout(1000) -- 1 sec

                -- or connect to a unix domain socket file listened
                -- by a redis server:
                --     local ok, err = red:connect("unix:/path/to/redis.sock")

                local ok, err = red:connect("127.0.0.1", 6379)
                if not ok then
                    ngx.say("failed to connect: ", err)
                    return
                end

                ok, err = red:set("dog", "an animal")
                if not ok then
                    ngx.say("failed to set dog: ", err)
                    return
                end

                ngx.say("set result: ", ok)

                local res, err = red:get("dog")
                if not res then
                    ngx.say("failed to get dog: ", err)
                    return
                end

                if res == ngx.null then
                    ngx.say("dog not found.")
                    return
                end

                ngx.say("dog: ", res)

                red:init_pipeline()
                red:set("cat", "Marry")
                red:set("horse", "Bob")
                red:get("cat")
                red:get("horse")
                local results, err = red:commit_pipeline()
                if not results then
                    ngx.say("failed to commit the pipelined requests: ", err)
                    return
                end

                for i, res in ipairs(results) do
                    if type(res) == "table" then
                        if not res[1] then
                            ngx.say("failed to run command ", i, ": ", res[2])
                        else
                            -- process the table value
                        end
                    else
                        -- process the scalar value
                    end
                end

                -- put it into the connection pool of size 100,
                -- with 10 seconds max idle time
                local ok, err = red:set_keepalive(10000, 100)
                if not ok then
                    ngx.say("failed to set keepalive: ", err)
                    return
                end

                -- or just close the connection right away:
                -- local ok, err = red:close()
                -- if not ok then
                --     ngx.say("failed to close: ", err)
                --     return
                -- end
            ';
        }

      訪問localhost/test若配置成功,則顯示

set result: OK
dog: an animal

      注意,要啟動Redis數據庫服務,否則后顯示failed to connect : connection refused

      5.經過以上步驟,Nginx+Lua+Redis的所有配置就完成了,實現了Nginx根據Url查詢Redis返回相應內容的功能,可以進行相應的二次開發。

       

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM