原文:http://www.javashuo.com/article/p-tmbettdi-dn.htmlphp
ngx_lua 模塊詳細講解(基於openresty)---http://www.javashuo.com/article/p-vbroczys-dv.htmlhtml
用lua擴展你的Nginx(整理)-----------------http://www.javashuo.com/article/p-uwhaxwxl-ge.htmlpython
ngx_lua模塊中的共享內存字典項API-----https://blog.csdn.net/weiyuefei/article/details/38487475mysql
ngx_lua – 把lua語言嵌入nginx中,使其支持lua來快速開發基於nginx下的業務邏輯nginx
該模塊不在nginx源碼包中,需自行下載編譯安裝。使用lua 5.1(目前不支持lua 5.2) 或 luajit 2.0 。git
添加lua支持後,開發複雜的模塊,週期快,依然是100%異步非阻塞。github
ngx_lua 哪些人在用:sql
淘寶、騰訊財經、網易財經、360、去哪兒網等api
CloudFlare, CNN, Wingify, Reblaze, Turner, Broadcasting System緩存
該項目主要開發者:
chaoslawful Taobao, Alibaba Grp.
agentzh CloudFlare
https://github.com/chaoslawful/lua-nginx-module
JIT
一般,程序有兩種運行方式:靜態編譯與動態直譯。 靜態編譯的程序在執行前所有被翻譯爲機器碼,而動態直譯執行的則是一句一句邊運行邊翻譯。 即時編譯(Just-In-Time Compiler)則混合了這兩者,一句一句編譯源代碼,可是會將翻譯過的代碼緩存起來以下降性能損耗。 JAVA、.NET 實現都使用即時編譯以提供高速的代碼執行。 注意: 在nginx.conf中添加"lua_code_cache on/off",來開啓是否將代碼緩存,因此每次變動"*.lua"文件時,必須reload nginx纔可生效。 僅針對"set_by_lua_file, content_by_lua_file, rewrite_by_lua_file, and access_by_lua_file"有效, 由於其餘爲寫在配置文件 中,更改代碼也必須reload nginx。在生產環境下,不能禁用cache。同時在lua代碼中使用"dofile" 或 "loadfie" 來加載外部lua腳步 將不會對它進行緩存,應該使用"require"來代替。禁用cache,當且僅當在調式代碼下。 demo 1
LuaJIT
是一個利用JIT編譯技術把Lua腳本直接編譯成機器碼由CPU運行 版本:2.0 與 2.1 當前穩定版本爲 2.0。 2.1爲版本與ngx_lua將有較大性能提高,主要是CloudFlare公司對luajit的捐贈。 FFI庫,是LuaJIT中最重要的一個擴展庫。 1. 它容許從純Lua代碼調用外部C函數,使用C數據結構; 2. 就不用再像Lua標準math庫同樣,編寫Lua擴展庫; 3. 把開發者從開發Lua擴展C庫(語言/功能綁定庫)的繁重工做中釋放出來; demo 2
下載編譯
wget -c http://luajit.org/download/LuaJIT-2.0.2.tar.gz tar xzvf LuaJIT-2.0.2.tar.gz cd LuaJIT-2.0.2 make install PREFIX=/usr/local/luajit echo "/usr/local/luajit/lib" > /etc/ld.so.conf.d/usr_local_luajit_lib.conf ldconfig #注意環境變量! export LUAJIT_LIB=/usr/local/luajit/lib export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0
NDK(Nginx Development Kit)模塊是一個拓展Nginx服務器核心功能的模塊
第三方模塊開發能夠基於它來快速實現
NDK提供函數和宏處理一些基本任務,減輕第三方模塊開發的代碼量。
wget -c https://github.com/simpl/ngx_devel_kit/archive/v0.2.18.tar.gz wget -c https://github.com/chaoslawful/lua-nginx-module/archive/v0.8.6.tar.gz tar xzvf v0.2.18 tar xzvf v0.8.6
wget -c http://nginx.org/download/nginx-1.4.2.tar.gz tar xzvf nginx-1.4.2.tar.gz cd nginx-1.4.2 ./configure --add-module=../ngx_devel_kit-0.2.18/ --add-module=../lua-nginx-module-0.8.6/ make make install
本身編譯官方的 nginx 源碼包,只需事前指定 LUAJIT_INC 和 LUAJIT_LIB 這兩個環境變量。 驗證你的 LuaJIT 是否生效,能夠經過下面這個接口: location = /lua-version { content_by_lua ' if jit then ngx.say(jit.version) else ngx.say(_VERSION) end '; } demo 3 若是使用的是標準 Lua,訪問 /lua-version 應當返回響應體 Lua 5.1 若是是 LuaJIT 則應當返回相似 LuaJIT 2.0.2 這樣的輸出。 不要使用標準lua,應當使用luajit, 後者的效率比前者高多了。 也能夠直接用 ldd 命令驗證是否鏈了 libluajit-5.1 這樣的 .so 文件,例如: [root@limq5 sbin]# ldd nginx | grep lua libluajit-5.1.so.2 => /usr/local/luajit/lib/libluajit-5.1.so.2 (0x00007f48e408b000) [root@limq5 sbin]#
在nginx.conf中的service添加一個location。
location = /test { content_by_lua ' ngx.say("Hello World") ngx.log(ngx.ERR, "err err err") '; }
demo 4
用戶訪問 http://localhost/test 將會打印出「Hello World」內容。
ngx.say 是 lua 顯露給模塊的接口。
相似的有 ngx.log(ngx.DEBUG, 「」),能夠在error.log輸出調試信息。
另外也能夠調用外部腳本,如同咱們寫php、jsp應用時,業務腳本單獨組織在.php或.jsp文件中同樣
location = /test2 { content_by_lua_file conf/lua/hello.lua; }
文件hello.lua內容以下:
ngx.say("Hello World")
這裏的腳本能夠任意複雜,也可使用Lua 本身的庫
lua可用模塊列表:
http://luarocks.org/repositories/rocks/
安裝相似yum,它也有一個倉庫:
luarocks install luafilesystem
運行上面命令後,會編譯一個 「lfs.so」, 文件,拷貝文件到nginx定義的LUA_PATH中,而後引用
該庫,就可調用其中函數。
LUA_PATH:
lua_package_path ‘/opt/17173/nginx-ds/conf/lua/?.lua;;’
lua_package_cpath ‘/opt/17173/nginx-ds/conf/lua/lib/?.so;/usr/local/lib/?.?;;’;
其中」;;」表明原先查找範圍。
demo 5
咱們假定,同時要訪問多個數據源,並且,查詢是沒有依賴關係,那咱們就能夠同時發出請求
這樣我總的延時, 是我全部請求中最慢的一個所用時間,而不是原先的全部請求用時的疊加
location = /api { content_by_lua ' local res1, res2, res3 = ngx.location.capture_multi{ {"/memc"}, {"/mysql"}, {"/postgres"} } ngx.say(res1.body, res2.body, res3.body) '; } demo 6
ngx.location.capture 沒法跨server進行處理, 只能在同一個server下的不一樣location。
Nginx 處理每個用戶請求時,都是按照若干個不一樣階段(phase)依次處理的,而不是根據配置文件上的順序。
Nginx 處理請求的過程一共劃分爲 11 個階段,按照執行順序依次是
post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.
post-read: 讀取請求內容階段 Nginx讀取並解析完請求頭以後就當即開始運行 例如模塊 ngx_realip 就在 post-read 階段註冊了處理程序,它的功能是迫使 Nginx 認爲當前請求的來源地址是指定的某一個請求頭的值。
server-rewrite Server請求地址重寫階段 當 ngx_rewrite 模塊的set配置指令直接書寫在 server 配置塊中時,基本上都是運行在 server-rewrite 階段
find-config 配置查找階段 這個階段並不支持 Nginx 模塊註冊處理程序,而是由 Nginx 核心來完成當前請求與 location 配置塊之間的配對工做。
rewrite Location請求地址重寫階段 當 ngx_rewrite 模塊的指令用於 location 塊中時,即是運行在這個 rewrite 階段。 另外,ngx_set_misc(設置md五、encode_base64等) 模塊的指令,還有 ngx_lua 模塊的 set_by_lua 指令和 rewrite_by_lua 指令也在此階段。
post-rewrite 請求地址重寫提交階段 由 Nginx 核心完成 rewrite 階段所要求的「內部跳轉」操做,若是 rewrite 階段有此要求的話。
preaccess 訪問權限檢查準備階段 標準模塊 ngx_limit_req 和 ngx_limit_zone 就運行在此階段,前者能夠控制請求的訪問頻度,然後者能夠限制訪問的併發度。
access 訪問權限檢查階段 標準模塊 ngx_access、第三方模塊 ngx_auth_request 以及第三方模塊 ngx_lua 的 access_by_lua 指令就運行在這個階段。 配置指令可能是執行訪問控制性質的任務,好比檢查用戶的訪問權限,檢查用戶的來源 IP 地址是否合法
post-access 訪問權限檢查提交階段 主要用於配合 access 階段實現標準 ngx_http_core 模塊提供的配置指令 satisfy 的功能。 satisfy all(與關係) satisfy any(或關係)
try-files 配置項try_files處理階段 專門用於實現標準配置指令 try_files 的功能 若是前 N-1 個參數所對應的文件系統對象都不存在,try-files 階段就會當即發起「內部跳轉」到最後一個參數(即第 N 個參數)所指定的 URI.
content 內容產生階段 Nginx 的 content 階段是全部請求處理階段中最爲重要的一個,由於運行在這個階段的配置指令通常都肩負着生成「內容」 並輸出 HTTP 響應的使命。
log 日誌模塊處理階段 記錄日誌
淘寶有開放一個nginx開發手冊,裏面包含不少有用的資料
http://tengine.taobao.org/book/
做者的google論壇:
https://groups.google.com/forum/#!forum/openresty
Nginx下Lua處理階段與使用範圍:
init_by_lua http set_by_lua server, server if, location, location if rewrite_by_lua http, server, location, location if access_by_lua http, server, location, location if content_by_lua location, location if header_filter_by_lua http, server, location, location if body_filter_by_lua http, server, location, location if log_by_lua http, server, location, location if timer
init_by_lua: 在nginx從新加載配置文件時,運行裏面lua腳本,經常使用於全局變量的申請。 例如lua_shared_dict共享內存的申請,只有當nginx重起後,共享內存數據才清空,這經常使用於統計。 set_by_lua: 設置一個變量,經常使用與計算一個邏輯,而後返回結果 該階段不能運行Output API、Control API、Subrequest API、Cosocket API rewrite_by_lua: 在access階段前運行,主要用於rewrite access_by_lua: 主要用於訪問控制,能收集到大部分變量,相似status須要在log階段纔有。 這條指令運行於nginx access階段的末尾,所以老是在 allow 和 deny 這樣的指令以後運行,雖然它們同屬 access 階段。 content_by_lua: 階段是全部請求處理階段中最爲重要的一個,運行在這個階段的配置指令通常都肩負着生成內容(content)並輸出HTTP響應。 header_filter_by_lua: 通常只用於設置Cookie和Headers等 該階段不能運行Output API、Control API、Subrequest API、Cosocket API body_filter_by_lua: 通常會在一次請求中被調用屢次, 由於這是實現基於 HTTP 1.1 chunked 編碼的所謂「流式輸出」的。 該階段不能運行Output API、Control API、Subrequest API、Cosocket API log_by_lua: 該階段老是運行在請求結束的時候,用於請求的後續操做,如在共享內存中進行統計數據,若是要高精確的數據統計,應該使用body_filter_by_lua。 該階段不能運行Output API、Control API、Subrequest API、Cosocket API timer:
可參考官方文檔:
http://wiki.nginx.org/HttpLuaModule
and break do else elseif end false for function if in local nil not or repeat return then true until while
支持 +, -, *, /,^ 好比2^3 結果爲8, 2^4結果爲16。 鏈接兩個字符串,用".."運處符, php爲".", JAVA、C#爲"+"
a,b,c,d=1,2,3,4 -- 多變量一塊兒賦值 a,b=b,a --交換變量功能 在默認狀況下,變量老是認爲是全局的。假如須要定義局部變量,則在第一次賦值的時候,須要用local說明。好比: local a,b,c = 1,2,3 -- a,b,c都是局部變量
and, or, not 在Lua中,只有false和nil才計算爲false,其它任何數據都計算爲true,0也是true and 和 or的運算結果不是true和false,而是和它的兩個操做數相關。 a and b:若是a爲false,則返回a;a true 返回b a or b:若是 a 爲true,則返回a;a false 返回b
模擬C語言中的語句:x = a? b : c,在Lua中,能夠寫成:x = a and b or c。 最有用的語句是: x = x or v,它至關於:if not x then x = v end 。
if 條件 then ... elseif 條件 then ... else ... end
repeat ... until 條件
while 條件 do ... end
for 變量=初值, 終點值, 步進 do ... end
for 變量1, 變量2, ... 變量n in 表或枚舉函數 do ... end
1. table 是 lua 中最重要的數據類型。 2. table 相似於 python 中的字典。 3. table 只能經過構造式來建立
;例1
Lua代碼 tab = { a = 10, b = 20, c = 30, d = 40 } print(tab["a"]) 註釋: 1)table 中的每項要求是 key = value 的形式 2)key 只能是字符串, 這裏的 a, b, c, d 都是字符串,可是不能加上引號 3)經過 key 來訪問 table 的值,這時候, a 必須加上引號
;例2
tab = { 10, m = 20, 11, 12, 13 } print(tab[1]) = 10 print(tab[2]) = 11 print(tab[3]) = 12 print(tab[4]) = 13 獲取表長度: print(table.getn(tab)) -> 4 print(#tab) -> 4 遍歷表: for k, v in pairs(tab) do print(k, ":", v) end 1 : 10 2 : 11 3 : 12 4 : 13 m : 20 註釋: 1)省略key,會自動以1開始編號,並跳過設置過的key 2)獲取表長度,只有當表使用1自動編號開始,能夠獲取
在項目的腳本lua中常常有這樣的需求
local a = {} 判斷表a是否爲空,有提供api table.maxn(a) 或 #a 獲取表a長度,可是該狀況只 針對key爲數字且安裝遞增方式。 對於自定義key的狀況下,獲取表長度將會失敗,可經過lua內置 next函數解決該問題。
lua官方手冊 http://www.lua.org/manual/5.1/ lua中文翻譯手冊 http://www.codingnow.com/2000/download/lua_manual.html
轉載:http://17173ops.com/2013/11/01/17173-ngx-lua-manual.shtml