一.下载软件包
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 协议的 Nginx upstream 模块,它可以让 Nginx 以非阻塞方式直接防问远方的 Redis 服务,同时支持 TCP 协议和 Unix Domain Socket 模式,并且可以启用强大的 Redis 连接池功能。
wget https://github.com/openresty/redis2-nginx-module/archive/v0.15rc1.tar.gz
4.set-misc-nginx-module 下载。是标准的HttpRewriteModule指令的扩展,提供更多的功能,如URI转义与非转义、JSON引述,Hexadecimal、MD5、SHA1、Base32、Base64编码与解码、随机数等等
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
调整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代码,实现字符串按"/"拆分
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函数。
然后我们将上面的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并 把请求转发过去
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 带密码的配置:
实现思路,
因为每次auth之后,会有返回ok,但是不需要返回OK ,还是返回之前的值的样子,故重新编辑返回值,只返回之前的key的形式,具体实现方式如下:
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;
}