一.下載軟件包
1..echo-nginx-module 下載,是一個 Nginx 模塊,提供直接在 Nginx 配置使用包括 "echo", "sleep", "time" 等指令。
wget?https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
?2.lua-nginx-module 下載??稍?Nginx 中嵌入 Lua 語言,讓 Nginx 可以支持 Lua 強大的語法。
wget?https://github.com/openresty/lua-nginx-module/archive/v0.10.12rc2.tar.gz
3.redis2-nginx-module 下載。是一個支持 Redis 2.0 協(xié)議的 Nginx upstream 模塊,它可以讓 Nginx 以非阻塞方式直接防問遠方的 Redis 服務(wù),同時支持 TCP 協(xié)議和 Unix Domain Socket 模式,并且可以啟用強大的 Redis 連接池功能。
wget?https://github.com/openresty/redis2-nginx-module/archive/v0.15rc1.tar.gz
4.set-misc-nginx-module 下載。是標準的HttpRewriteModule指令的擴展,提供更多的功能,如URI轉(zhuǎn)義與非轉(zhuǎn)義、JSON引述,Hexadecimal、MD5、SHA1、Base32、Base64編碼與解碼、隨機數(shù)等等
wget?https://github.com/openresty/set-misc-nginx-module/archive/v0.32rc1.tar.gz
?5.nginx 下載
wget?http://nginx.org/download/nginx-1.14.0.tar.gz
二、編譯安裝
1.確認下目錄位置? ?
[root@test01?~]#?ls
echo-nginx-module-0.61???????nginx-1.14.0????????????redis2-nginx-module-0.15rc1
lua-nginx-module-0.10.12rc2????set-misc-nginx-module-0.32rc1
2.進入nginx-1.12.2 ,編譯安裝
安裝依賴
yum?install?pcre-devel?openssl-devel?gcc?curl?lua?lua-devel
yum 安裝luajit-devel.x86_64
????./configure?--prefix=/usr/local/nginx?--user=www?--group=www?--with-http_gzip_static_module?--with-http_stub_status_module?--with-http_ssl_module?--with-file-aio?--with-http_realip_module?--add-module=../echo-nginx-module-0.61?--add-module=../redis2-nginx-module-0.15rc1?--add-module=../lua-nginx-module-0.10.12rc2?--add-module=../set-misc-nginx-module-0.32rc1
????make
注意:
若只是升級操作,則不需要make install ,若第一次安裝,則需要make install
? ? a.升級操作
????cd?/usr/local/nginx/sbin/
????mv?nginx?nginx.bak
????cd?~/objs/
????cp?-rp??nginx?/usr/local/nginx/sbin/
????kill?-USR2?$(cat?/var/run/nginx.pid)
????b.安裝操作
?????make?install
調(diào)整nginx配置文件,編寫啟動腳本
3.redis插件安裝
1)lua-resty-redis是openresty(1.9.15.1)的一個組件,簡單來說,它提供一個lua語言版的redis API,使用socket(lua sock)和redis通信。(不需要)
mdkir?/usr/local/nginx/lua??
cd?/usr/local/nginx/lua
wget?https://github.com/openresty/lua-resty-redis/archive/v0.26.tar.gz
tar?-xf??v0.26.tar.gz
2)安裝lua-redis-parser
wget??https://github.com/openresty/lua-redis-parser/archive/v0.13.tar.gz
tar?-xvf?v0.13.tar.gz
gmake?CC=gcc
gmake?install?CC=gcc
cd?/usr/local/lib/lua/5.1/redis/
cd?../..
cp?-rp?lua/?/usr/lib64/
4.?redis 安裝 (略過)
三.lua 腳本測試
首先,要解析并拆分URL字符串,各種百度和Google,需要寫一段Lua代碼,實現(xiàn)字符串按"/"拆分
function?split(str,?pat)
local?t?=?{}
local?fpat?=?"(.-)"?..?pat
local?last_end?=?1
local?s,?e,?cap?=str:find(fpat,1)
while?s?do
if?s?~=?1?or?cap?~=?""?then
table.insert(t,cap)
end
last_end?=?e+1
s,?e,?cap?=?str:find(fpat,?last_end)
end
if?last_end?<=?#str?then
cap?=?str:sub(last_end)
table.insert(t,?cap)
end
return?t
end
function?split_path(str)
return?split(str,'[\\/]+')
end
其實就是定義了一個split_path函數(shù)。
然后我們將上面的Split.lua文件,配置到Nginx的配置文件中
/usr/local/nginx/conf/nginx.conf
?init_worker_by_lua_file "/usr/local/nginx/lua/split.lua"
編輯 vhost.conf 配置文件
server?{
????????listen?80;
????????server_name?test.xxxx.com;
????????index?index.html?index.htm?index.php;
????????location?=?/redis?{
????????????internal;
????????????set_unescape_uri?$key?$arg_key;
????????????redis2_query?get?$key;
????????????#redis2_query?auth?"mypaas";
????????????redis2_pass?172.16.197.72:6379;
????????}
????????location?/?{
????????????set?$target?'';
????????????access_by_lua?'
????????local?parameters?=?split_path(ngx.var.uri)
????????local?action?=?parameters[1]
????????if(#parameters?==?0)?then
???????????????????ngx.exit(ngx.HTTP_FORBIDDEN)
????????end
????????local?key?=?action
????????local?res?=?ngx.location.capture(
????????????????????"/redis",?{?args?=?{?key?=?key?}?}
????????)
????????if?res.status?~=?200?then
????????????????????ngx.log(ngx.ERR,?"redis?server?returned?bad?status:?",
????????????????????????res.status)
????????????????????ngx.exit(res.status)
????????end
????????if?not?res.body?then
????????????????????ngx.log(ngx.ERR,?"redis?returned?empty?body")
????????????????????ngx.exit(500)
????????end
????????local?parser?=?require?"redis.parser"
????????local?server,?typ?=?parser.parse_reply(res.body)
????????if?typ?~=?parser.BULK_REPLY?or?not?server?then
????????????????????ngx.log(ngx.ERR,?"bad?redis?response:?",?res.body)
????????????????????ngx.exit(500)
????????end
????????if?server?==?""?then
????????????????????server?=?"test.paas.qjclouds.com"
????????end
????????ngx.var.target?=?server
???????';
???????resolver?8.8.8.8;
???????proxy_pass?http://$target;
??????proxy_set_header?Host?test.xxx.com;
?????}
access_log?/tmp/access.log;
????}
需求變更:
1. 訪問域名的? 重定向到某個頁面
2.訪問/xxx? ?重定向到 某個固定頁面
3.訪問/xxx/xxx/xxxx的重定向到 某個server并 把請求轉(zhuǎn)發(fā)過去
4.訪問到后端主機的請求,需要負載(負載地址 在redis value里面,并且以','分割)
更改?/usr/local/nginx/lua/split.lua文件為如下:
function?split(str,?pat)
local?t?=?{}
local?fpat?=?"(.-)"?..?pat
local?last_end?=?1
local?s,e,cap?=?str:find(fpat,1)
while?s?do
???if?s?~=?1?or?cap?~=?""?then
??????table.insert(t,cap)
???end
???last_end?=?e+1
???s,e,cap?=?str:find(fpat,?last_end)
end
if?last_end?<=?#str?then
???cap?=?str:sub(last_end)
???table.insert(t,?cap)
end
return?t
end
function?split_path(str)
return?split(str,'[\\/]+')
end
function?split_arr(inputstr,?sep)
????????if?sep?==?nil?then
????????????????sep?=?"%s"
????????end
????????local?t={}?;?i=1
????????for?str?in?string.gmatch(inputstr,?"([^"..sep.."]+)")?do
????????????????t[i]?=?str
????????????????i?=?i?+?1
????????end
????????return?t
end
更改Nginx文件為:
????server?{
????????listen?80;
????????server_name?uatx.paas.xxx.com;
????????index?index.html?index.htm?index.php;
????????location?=?/redis?{
????????????internal;
????????????set_unescape_uri?$key?$arg_key;
????????????redis2_query?get?$key;
????????????redis2_pass?172.19.151.176:6379;
????????}
????????location?/?{
????????????set?$target?'';
????????????access_by_lua?'
????????local?parameters?=?split_path(ngx.var.uri)
????????local?action?=?parameters[1]
????????local?action1?=?parameters[2]
????????local?action2?=?ngx.var.host
????????if?ngx.var.uri?==?"/"?then
???????????????res?=?ngx.location.capture(
????????????????"/redis",?{?args?=?{?key?=?"0_"..action2?}?}
????????????????)
??????????????local?parser?=?require?"redis.parser"
??????????????local?dapeng,?typ?=?parser.parse_reply(res.body)
???????????return?ngx.redirect(dapeng)
????????end
????????if(#parameters?==?0)?then
?????????????????ngx_log(ngx.ERR,?"----------------------->")
?????????????????ngx.exit(ngx.ERROR)
???????????????????ngx.exit(ngx.HTTP_FORBIDDEN)
????????end
????????if?action1?==?nil?then
?res?=?ngx.location.capture(
????????????????????"/redis",?{?args?=?{?key?=?"0_/paas/res"?}?}
????????????????)
else
?????????res?=?ngx.location.capture(
????????????????????"/redis",?{?args?=?{?key?=?"0_/"..action.."/"..action1?}?}
????????)
????????end
????????if?res.status?~=?200?then
????????????????????ngx.exit(res.status)
????????end
????????if?not?res.body?then
???????????????res?=?ngx.location.capture(
????????????????"/redis",?{?args?=?{?key?=?"0_paas/res"?}?}
????????????????)
????????end
????????local?parser?=?require?"redis.parser"
????????local?server,?typ?=?parser.parse_reply(res.body)
????????if?typ?~=?parser.BULK_REPLY?or?not?server?then
????????????????????return?ngx.redirect("/paas/res")
????????end
????????if?server?==?""?then
????????????????????server?=?"uat.paas.qjclouds.com"
????????end
????????if?server?==?""?then
????????????????????server?=?"uat.paas.qjclouds.com"
????????end
????????local?more?=?server
????????local?have?=?split_arr(more,?",")
????????ngx.var.target?=?have[math.random(1,#have)]
???????';
???????resolver?8.8.8.8;
???????proxy_pass?http://$target;
??????proxy_set_header?Host?$host;
??????proxy_set_header??X-Real-IP????????$remote_addr;
?????proxy_set_header??X-Forwarded-For??$proxy_add_x_forwarded_for;
?????}
access_log?/tmp/access.log;
error_log?/tmp/access.log;
????}
https配置
a.配置重定向
server?{
??listen?0.0.0.0:80;
??#listen?[::]:80?ipv6only=on?default_server;
??server_name?mp.xytest.qjclouds.com;
??server_tokens?off;?##?Don't?show?the?nginx?version?number,?a?security?best?practice
#location?~?^/.well-known?{
#root?/tmp;
#}
??return?301?https://$http_host$request_uri;
}
2.配置https??
server?{
????????listen?443;
server_tokens?off;
????????server_name?mp.xytest.qjclouds.com;
????????index?index.html?index.htm?index.php;
add_header?Access-Control-Allow-Origin?"*";
????????ssl??????????????????on;????
????????ssl_certificate??????vhosts/ssl/mp.xytest.qjclouds.com.pem;
????????ssl_certificate_key??vhosts/ssl/mp.xytest.qjclouds.com.key;????
????????#ssl_ciphers??HIGH:!aNULL:!MD5;????
????????ssl_prefer_server_ciphers???on;????
????????ssl_ciphers?"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
????????ssl_protocols?TLSv1?TLSv1.1?TLSv1.2?SSLv2?SSLv3;???
????????ssl_session_cache?shared:SSL:10m;???
????????ssl_session_timeout?5m;
????????location?=?/redis?{
????????????internal;
????????????set_unescape_uri?$key?$arg_key;
????????????redis2_query?get?$key;
????????????redis2_pass?10.68.0.16:6379;
????????}
????????location?/?{
????????????set?$target?'';????????????
????????????access_by_lua?'
????????local?parameters?=?split_path(ngx.var.uri)
????????local?action?=?parameters[1]
????????local?action1?=?parameters[2]
????????local?action2?=?ngx.var.host
????????if?ngx.var.uri?==?"/"?then
???????????????res?=?ngx.location.capture(
????????????????"/redis",?{?args?=?{?key?=?"0_"..action2?}?}
????????????????)
??????????????local?parser?=?require?"redis.parser"
??????????????local?dapeng,?typ?=?parser.parse_reply(res.body)
???????????return?ngx.redirect(dapeng)
????????end
????????if(#parameters?==?0)?then
?????????????????ngx_log(ngx.ERR,?"----------------------->")
?????????????????ngx.exit(ngx.ERROR)
???????????????????ngx.exit(ngx.HTTP_FORBIDDEN)
????????end
????????if?action1?==?nil?then?
?res?=?ngx.location.capture(
????????????????????"/redis",?{?args?=?{?key?=?"0_/paas/res"?}?}
????????????????)
else?
?????????res?=?ngx.location.capture(
????????????????????"/redis",?{?args?=?{?key?=?"0_/"..action.."/"..action1?}?}
????????)
????????end
????????if?res.status?~=?200?then
????????????????????ngx.exit(res.status)
????????end
????????if?not?res.body?then
???????????????res?=?ngx.location.capture(
????????????????"/redis",?{?args?=?{?key?=?"0_paas/res"?}?}
????????????????)
????????end
????????local?parser?=?require?"redis.parser"
????????local?server,?typ?=?parser.parse_reply(res.body)
????????if?typ?~=?parser.BULK_REPLY?or?not?server?then
????????????????????return?ngx.redirect("/paas/res")
????????end
????????if?server?==?""?then
????????????????????server?=?"uatb.ress.qjclouds.com"
????????end
????????ngx.var.target?=?server
???????';
???????resolver?8.8.8.8;???????????????
???????proxy_pass?http://$target;
??????proxy_set_header?Host?$host;
??????proxy_set_header??X-Real-IP????????$remote_addr;??
?????proxy_set_header??X-Forwarded-For??$proxy_add_x_forwarded_for;?
?????}
access_log?/usr/local/nginx/logs/access.log?access;
error_log?/usr/local/nginx/logs/error.log;
????}
redis 帶密碼的配置:
實現(xiàn)思路,
因為每次auth之后,會有返回ok,但是不需要返回OK ,還是返回之前的值的樣子,故重新編輯返回值,只返回之前的key的形式,具體實現(xiàn)方式如下:
????server?{
????????listen?80;
????????server_name?*.xingyun.xxx.com;
????????index?index.html?index.htm?index.php;
????????location?=?/redis?{
????????????internal;
????redis2_raw_queries?$args?$echo_request_body;
????????????redis2_pass?127.0.0.1:6382;
????????}
????????location?/?{
????????????set?$target?'';????????????
????????????access_by_lua?'
????????local?parameters?=?split_path(ngx.var.uri)
????????local?action?=?parameters[1]
????????local?action1?=?parameters[2]
????????local?action2?=?ngx.var.host
????????function?LsReadis(key)
??????????local?parser?=?require?"redis.parser"
??????????local?reqs?=?{
?????????????{"auth",?"mima"},
?????????????{"get",?key}
????????????????}??
??local?raw_reqs?=?{}
?for?i,?req?in?ipairs(reqs)?do
table.insert(raw_reqs,?parser.build_query(req))
??end
???local?res?=?ngx.location.capture("/redis?"?..?#reqs,
?????{?body?=?table.concat(raw_reqs,?"")?})
??if?res.status?~=?200?or?not?res.body?then
?????ngx.log(ngx.ERR,?"failed?to?query?redis")
?????ngx.exit(500)
???end
???replies?=?parser.parse_replies(res.body,?#reqs)
?????return?replies[2][1]
????????end
????????if?ngx.var.uri?==?"/"?then
????if?LsReadis("0_"..action2)?==?nil?then
????ngx.exit(501)
????else
????????????return?ngx.redirect(LsReadis("0_"..action2))
????end
????????end
????????----判斷paas后是否為空
????????if?action1?==?nil?then
????????key?=?"0_paas/res"
????????else
????????key?=?"0_/"..action.."/"..action1
????????end
???????----空值重定向
server?=?LsReadis(key)
????????if?not?server?or?server?==?nil?then
local?key?=?"0_paas/res"
server?=?LsReadis(key)
????????end
???????----redis?連接或取值失敗
???????if?server?==?""?then
??????????server?=?"uatb.xingyun.qjclouds.com"
????????end
???????ngx.var.target?=?server
???????';
???????resolver?8.8.8.8;
???????proxy_pass?http://$target;
???????proxy_set_header?Host?$host;
???????proxy_set_header??X-Real-IP????????$remote_addr;
???????proxy_set_header??X-Forwarded-For??$proxy_add_x_forwarded_for;
}
access_log?/usr/local/nginx/logs/test.log?access;
error_log?/usr/local/nginx/logs/test.log;
????}