Nginx高階之Lua
高階階段回顧:
Nginx高階之高階模組(secure_link/secure_link_md5/geoip_module)
基礎語法
Lua是一個簡潔/輕量/可擴充套件的指令碼語言
安裝Lua直譯器:
yum install lua
檢視lua版本:
輸出:
① 互動式輸出
② 指令碼式輸出
指令碼內容:
#!/usr/bin/lua print("this is lua test!!!")
註釋:
行註釋: --
塊註釋:
--[[
註釋內容...
--]]
變數:
a='alo\n123'
a="alo\n123\""
數值變數只有double型別.
布林型別只有nil和false: nil代表是空, false代表是false, 其他(包括空串 數字0)都是true
lua中的變數在沒有宣告的情況下都是全域性變數, 如果要宣告成區域性變數, 需要加上local
迴圈: lua不支援++或+=的操作
while迴圈:
sum = 0
num = 1
while num <= 100 do
sum = sum + num
num = num + 1
end
print("sum =", sum)
for迴圈:
sum = 0
for i = 1, 100 do
sum = sum + i
end
if判斷:
if age == 40 and sex == "Male" then
print("大於40男人")
elseif age > 60 and sex ~= "Female" then
print("非女人而且大於60")
else
local age = io.read()
print("Your age is "..age)
end
注: "~=" 表示不等於, 字串的拼接操作符"..", io庫的分別從stdin和stdout讀寫的read和write函式
Nginx的Lua環境
準備工作:
① LuaJIT(Lua直譯器)
② ngx_devel_kit(nginx的Lua開發庫)和lua-nginx-module(nginx的Lua模組)
③ 重新編譯nginx
Nginx呼叫Lua的指令:
set_by_lua、 set_by_lua_file |
設定nginx變數, 可以實現複雜的賦值邏輯 |
access_by_lua、 access_by_lua_file |
請求訪問階段處理, 用於訪問控制 |
content_by_lua、 content_by_lua_file |
內容處理器, 接收請求處理並輸出響應 |
Lua呼叫Nginx的指令:
ngx.var | nginx變數 |
ngx.req.get_headers | 獲取請求頭 |
ngx.req.get_uri_args | 獲取url請求引數 |
ngx.redirect | 重定向 |
ngx.print | 輸出響應內容體 |
ngx.say | 同ngx.print, 但是會最後輸出一個換行符 |
ngx.header | 輸出響應頭 |
步驟:
注: 所有步驟都在/opt/Milky-Way/lua目錄下, 執行nginx編譯時需要進入nginx的資料夾, 並且所有的tar包需先解壓
LuaJIT(需要解壓後進入資料夾內)
wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz
make install PREFIX=/usr/local/LuaJIT
export LUAJIT_LIB=/usr/local/LuaJIT/lib
export LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.0
ngx_devel_kit和lua-nginx-module(需解壓)
wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
nginx-1.14.1
需要進入nginx資料夾
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/opt/Milky-Way/lua/ngx_devel_kit-0.3.0 --add-module=/opt/Milky-Way/lua/lua-nginx-module-0.10.9rc7
編譯
make -j 4 && make install
載入lua庫,加入到ld.so.conf檔案並啟動配置
echo "/usr/local/LuaJIT/lib" >> /etc/ld.so.conf
ldconfig
實戰:
灰度釋出
按一定的關係區別, 分部分程式碼進行上線, 平滑過渡的一種釋出方式.
根據個人資訊(cookie)來做區別
根據個人ip來做區別
模型:
模型解釋:
當用戶訪問Nginx&Lua伺服器時, Lua會去MemCache取ip列表, 判斷該使用者是否在列表中, 如果存在, 則訪問8080埠, 不存在則訪問9090埠.
準備工作:
① 安裝MemCache(key-value快取資料庫)
命令: yum install memcached
② 安裝tomcat(網上自行下載tomcat進行解壓即可), 分別設定埠為8080和9090
在兩個tomcat的webapps/ROOT目錄下建立一個.jsp檔案, 內容自定義.
啟動tomcat: 進入bin/, 執行 sh catalina.sh start
檢視程序: netstat -luntp
啟動MemCache: 執行 memcached -p [預設埠11211] -u nobody -d(-d表示以守護程序執行)
檢視程序: netstat -luntp | grep 11211
③ 下載Lua呼叫MemCache包
wget https://github.com/agentzh/lua-resty-memcached/archive/v0.11.tar.gz
tar -zxvf v0.11.tar.gz
cp -r lua-resty-memcached-0.11/lib/resty [lua本地的安裝路徑]
④ 配置default.conf
⑤ dep.lua檔案
clientIP = ngx.req.get_headers()["X-Real-IP"]
if clientIP == nil then
clientIP = ngx.req.get_headers()["x_forwarded_for"]
end
if clientIP == nil then
clientIP = ngx.var.remote_addr
end
local memcached = require "resty.memcached"
local memc, err = memcached:new()
if not memc then
ngx.say("failed to instantiate memc: ", err)
return
end
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local res, flags, err = memc:get(clientIP)
ngx.say("value key: ", res, clientIP)
if err then
ngx.say("failed to get clientIP", err)
return
end
if res == "1" then
ngx.exec("@server_test")
return
end
ngx.exec("@server")
⑥ 將需要的ip設定進MemCache中, 沒有安裝telnet工具自行百度.
執行: telnet 127.0.0.1 11211
連線上之後執行: set [需要的ip] 0 0 1 ==> 回車
回車後填上值 1 == > 再回車 ==> quit 退出telnet
⑦ 啟動nginx, 訪問[ip]/[jsp檔名].