Nginx安裝lua支持
Nginx安裝lua支持
需要LuaJIT-2.0.4.tar.gz,ngx_devel_kit,lua-nginx-module
1.下載安裝LuaJIT-2.0.4.tar.gz
wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar xzvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make install PREFIX=/usr/local/luajit
#註意環境變量!
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0
2.下載解壓ngx_devel_kit
wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
tar -xzvf v0.3.0.tar.gz
3.下載解壓lua-nginx-module
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz
tar -xzvf v0.10.8.tar.gz
4.下載安裝nginx-1.10.3.tar.gz
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -xzvf nginx-1.10.3.tar.gz
cd nginx-1.10.3
./configure --add-module=/opt/soft/ngx_devel_kit-0.3.0 --add-module=/opt/soft/lua-nginx-module-0.10.8
#註意ngx_devel_kit和lua-nginx-module以實際解壓路徑為準
make -j2
make install
註:報錯gcc需要安裝,可以執行
yum install -y gcc g++ gcc-c++
依賴報錯,可以執行
yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel
這樣會導致編好的nginx在啟動的時候會無法找到位於luajit內的類庫,類似於
/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf/opt/nginx/sbin/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
這個問題很多人發現後采用了將libluajit-5.1.so.2鏈接到系統庫的做法,比如http://cywhoyi.iteye.com/blog/2118913,以及https://www.ttlsa.com/nginx/nginx-modules-ngx_lua,采用的
ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/
這樣可以解決問題,但是相當於一個補救方法。
利用nginx+lua實現通用的請求輸入輸出日誌打印
nginx+lua在web開發中現在越來越多用於實現一些公共策略邏輯,比如防攻擊等,nginx有著高性能高並發的處理框架,lua語言開發也簡單,這次我們嘗試在nginx層用lua實現我們請求日誌的打印。
在開發調試、問題排查中,日誌信息很重要,尤其是一個請求的輸入及輸出信息,但nginx本身的日誌定義不能打印輸出信息及POST參數,我們往往會在後端業務代碼中(如用PHP)打印一個這樣的notice日誌,不過也可以在nginx中用lua中實現,所有經過這個nginx的請求日誌都會按你想要的格式打印出來,這樣實現簡單而且統一。下面介紹下我在nginx中用lua實現的一個日誌打印腳本。
nginx+lua的具體開發教程見這裏 https://github.com/openresty/lua-nginx-module,我就不介紹了,下面主要是介紹一下實現代碼:
我們要建立nginx各個處理階段的代碼文件,首先創建一個access.lua文件,代碼如下:
if ngx.var.log_val ~= nil then local request = "["..ngx.var.time_local.."] ".."\""..ngx.var.request_method.." "..ngx.var.scheme.."://".. ngx.var.host..ngx.var.request_uri.."\"" local post = "" local delimiter = "" local item = "" ngx.req.read_body() local args, err = ngx.req.get_post_args() if args then for key, val in pairs(args) do item = "" if type(val) == "string" then key = string.gsub(key,"%c"," ") val = string.gsub(val,"%c"," ") item = key.."="..val elseif type(val) == "table" then item = key.."=" local tstr = ""; local tdelimiter = "" for k, v in pairs(val) do if type(v) == "string" then tstr = tstr..tdelimiter..v tdelimiter = ‘,‘ end end item = item..tstr end post = post..delimiter..item delimiter = "&" end end ngx.var.log_val = request.." ".." postdata=["..post.."] output=["end1234567891011121314151617181920212223242526272829303132333412345678910111213141516171819202122232425262728293031323334
這個文件主要是記錄請求的時間、url及輸入參數等信息,包括post數據
接著創建一個body_filter.lua文件,內容如下:
if ngx.var.log_val ~= nil then local newcontent = string.gsub(ngx.arg[1],"%c"," ") ngx.var.log_val = ngx.var.log_val..newcontentend12341234
這裏記錄輸出信息,開發中發現ngx.arg[1]與任何字符串進行連接的話,日誌打印都會打印兩次,除了與內置log_val變量連接,原因可能跟內部跳轉有關,所以這裏就兩行代碼,不會有更多其它操作。
再創建一個log.lua文件,內容如下:
if ngx.var.log_val ~= nil then function mylog(msg) file = io.open ("/home/rong/nginx/logs/monitor.log","a+") file:write (msg) file:flush(); file:close(); end ngx.var.log_val = ngx.var.log_val.."] httpstatus=".. ngx.var.status.." request_time="..ngx.var.request_time.."\n" mylog(ngx.var.log_val) end123456789101112123456789101112
這裏將拼接起來的各個日誌信息寫入文件。
創建了各個階段的處理文件,將其加入nginx配置文件中,如下:
...... access_by_lua_file /home/rong/nginx/conf/access.lua; body_filter_by_lua_file /home/rong/nginx/conf/body_filter.lua; log_by_lua_file /home/rong/nginx/conf/log.lua; .....1234512345
註意nginx配置中 client_body_buffer_size 與 client_max_body_size的值要設得一樣大,且不能過小。
最後還要在server段定義一個變量,作為存儲每條日誌信息用
server{ ...... set $log_val ‘‘; ......}123456123456
這樣,有請求過來時,在 /home/rong/nginx/logs/monitor.log文件 中就可以很清楚地看到輸入輸出信息了。
本文出自 “夢想照進現實” 博客,請務必保留此出處http://lookingdream.blog.51cto.com/5177800/1961607
Nginx安裝lua支持