nginx教學

WBOY
WBOY原創
2016-08-08 09:23:271251瀏覽

Nginx與Lua

火雲邪神語錄:天下武功,無堅不破,唯快不破! Nginx的看家本領就是速度,Lua的拿手好戲亦是速度,這兩者的結合在速度上無疑有基因上的優勢。

最先將Nginx,Lua組合在一起的是OpenResty,它有一個ngx_lua模組,將Lua嵌入到了Nginx裡面;隨後Tengine也包含了ngx_lua模組。至於二者的差別:OpenResty是Nginx的Bundle;而Tengine則是Nginx的Fork。值得一提的是,OpenResty和Tengine都是國人自己創造的項目,前者主要由春哥和曉哲開發,後者主要由淘寶打理。

至於OpenResty和Tengine孰優孰劣,留給大家自己判斷,如下資料可供參考:

  • ngx_openresty: an Nginx ecosystem glued by Lua
  • 淘寶網Nginx應用、客製化與開發實戰

推薦看看春哥在Tech-Club上關於『由Lua黏合的Nginx生態環境』的演講實錄,有料!

安裝

需要最新版的Nginx,LuaJIT,ngx_devel_kit,ngx_lua等安裝檔。

安裝Lua或LuaJIT都是可以的,但是出於效率的考慮,建議安裝LuaJIT。

shell> wget http://luajit.org/download/LuaJIT-.tar.gz shell> tar zxvf LuaJIT-.tar.gz shell> cd LuaJIT- shell> make shell> make install

因為安裝在缺省路徑,所以LuaJIT對應的lib,include都在/usr/local目錄裡。

shell> export LUAJIT_LIB=/usr/local/lib shell> export LUAJIT_INC=/usr/local/include/luajit-

下面就可以編譯Nginx了:

shell> wget http://nginx.org/download/nginx-.tar.gz shell> tar zxvf nginx-.tar.gz shell> cd nginx- shell> ./configure --add-module=/path/to/ngx_lua \ --add-module=/path/to/ngx_devel_kit shell> make shell> make install

試著啟動一下Nginx看看,如果你運氣不好的話,可能會遇到如下錯誤:

cannot open shared object file: No such

dicannot open shared object file: No such filefileorrectory

這是神馬情況?可以用ldd指令來看看:

shell> ldd /path/to/nginx libluajit-.so => not found

此類問題通常使用ldconfig指令就能解決:

shell> echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf shell> ldconfig

再試著啟動Nginx看看,應該就OK了。

應用

我們先用一個簡單的程式來暖暖場:把下面的程式碼加入到Nginx的設定檔nginx.conf,並重啟Nginx,然後瀏覽,就能看到效果了。

location /lua { set $test "hello, world."; content_by_lua ' ngx.header.content_type = "text/plain"; ngx.say(ngx.var.test); '; }

在深入學習ngx_lua之前,建議大家仔細閱讀一遍春哥寫的Nginx教學。

這裡我就說關鍵的:Nginx設定檔所使用的語言本質上是『聲明性的』,而非『過程性的』。 Nginx處理請求的時候,指令的執行並不是由定義指令時的物理順序來決定的,而是取決於指令所屬的階段,Nginx常用的階段按先後順序有:rewrite階段,access階段,content階段等等。示範程式碼中的set指令屬於rewrite階段,content_by_lua指令屬於content階段,如果試著把兩個指令的順序交換一下,會發現程式依然能夠正常運作。

下面我們試著結合Redis寫個比較實戰一點的例子。

首先,我們需要建立一個Redis設定檔config.json,內容如下:

{ "host": "", "port": "" }

然後,我們建立一個解析設定檔的腳本init.lua,其中用到了Lua CJSON模組:

local cjson = require "cjson"; local config = ngx.shared.config; local file = io.open("config.json", "r"); local content = cjson.decode(file:read("*all")); file:close(); for name, value in pairs(content) do config:set(name, value); end

說明:程式碼裡用到了共享內存,這樣就不必每次請求都解析一遍設定檔了。

接著,我們建立一個渲染內容的腳本content.lua,用到了Resty Redis模組:

ngx.header.content_type = "text/plain"; local redis = require "resty.redis"; local config = ngx.shared.config; local instance = redis:new(); local host = config:get("host"); local port = config:get("port"); local ok, err = instance:connect(host, port); if not ok then ngx.log(ngx.ERR, err); ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE); end instance:set("name", "laowang"); local name = instance:get("name") instance:close(); ngx.say("name: ", name);

說明:建議把Resty Redis模組放到vendor目錄下,稍後在Nginx中統一設定。

最後,我們需要在Nginx設定檔裡設定一下:

lua_shared_dict config 1m; lua_package_path "/path/to/vendor/?.lua;;"; init_by_lua_file /path/to/init.lua; server { lua_code_cache off; location /lua { content_by_lua_file /path/to/content.lua; } ... }

說明:為了方便調試,我關閉了lua_code_cache,如果是生產環境,應該開啟它。

另外,安裝CJSON的時候,需要注意Makefile檔案裡頭檔的路徑,缺省是:

PREFIX = /usr/local LUA_INCLUDE_DIR = $(PREFIX)/include

如果安裝的是LuaJIT的話,最好把頭檔拷貝到對應目錄:

cp /usr/local/include/luajit-/* /usr/local/include/

我最近參與的一個項目,提供了一些用於Web輪詢的接口,都是用Nginx+Lua實現的,雖然總共只有十幾台伺服器,但是每天可以提供幾十億次的請求量,賊拉拉的強。

最後,讓我引用某位屌絲的語錄做結束語吧:Lua,未婚男性程式設計師的最愛。

此條目由老王發表在Technical分類目錄,並貼了Lua、Nginx標籤。將固定連結加入收藏夾。

NGINX與LUA》上有29條評論


以上就介紹了nginx教程,包含了方面的內容,希望對PHP教程有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn