前言
项目需要在登录之前调用登陆调度接口来获取登录接口的IP地址,如此便需要Nginx在登陆调度接口之后动态的对登录接口的IP地址进行赋值,因此决定在服务器安装OpenResty,利用Redis缓存功能、Lua的代码编写功能对Nginx的配置文件进行修改。
下载
从下载页 Download下载最新的 OpenResty® 源码包
wget https://openresty.org/download/openresty-1.19.9.1.tar.gz
安装前的准备
安装依赖库 perl 5.6.1+, libpcre, libssl
yum install pcre-devel openssl-devel gcc curl -y
安装
tar -zxvf openresty-1.19.9.1.tar.gz
cd openresty-1.19.9.1
./configure
make
make install
如果支持多核 make 工作的特性, 可以这样编译:
make -j2
默认, --prefix=/usr/local/openresty 程序会被安装到/usr/local/openresty目录。
也可以指定各种选项:
./configure --prefix=/opt/openresty \
--with-luajit \
--with-http_redis2_module
使用 ./configure --help 可以查看更多的选项。
配置
修改Nginx配置文件nginx.conf
server {
server_name 域名;
listen 服务器端口 ssl;
ssl_certificate /opt/openresty/nginx/cert/FullSSL.crt;
ssl_certificate_key /opt/openresty/nginx/cert/SSL.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location /{
root /opt/openresty/nginx/html;
}
# 登陆调度
location /LoginRoute {
proxy_pass https://IP:port/***/**;
}
# 保存URL
location = /SaveUrl {
internal;
set_unescape_uri $key $arg_key;
set_unescape_uri $value $arg_value;
redis2_query set $key $value;
redis2_pass 127.0.0.1:6379;
}
# 入口
location = /Entrance{
content_by_lua_block {
local cjson = require "cjson"
ngx.req.read_body()
-- 解析前端请求,获取其中userId
local bodyData = ngx.req.get_body_data();
local data = cjson.decode(bodyData);
local userId = data["userId"];
ngx.log(ngx.ERR, "useridis : ", userId)
-- 发起登录调度请求
local res = ngx.location.capture("/LoginRoute", { method = ngx.HTTP_POST, body = bodyData})
if res.status == 200 then
local resData = cjson.decode(res.body);
-- 请求成功,获取serviceUrl,并保存redis
local serviceUrl = string.gsub(resData["vspURL"], "http://", "");
ngx.log(ngx.ERR, "serviceUrl ====== : ", serviceUrl);
local saveRes = ngx.location.capture(
"/SaveUrl", { args = { key = userId, value = serviceUrl} })
end
-- 返回请求结果
ngx.say(res.body)
ngx.exit(res.status)
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
# 获取URL
location = /getUrl {
internal;
set_unescape_uri $key $arg_key;
redis2_query get $key;
redis2_pass 127.0.0.1:6379;
}
# 更改接口的URL
location /Interface {
set $target '';
access_by_lua '
local key = ngx.req.get_headers().userId
-- 从Redis获取该用户的Url
local res = ngx.location.capture(
"/getUrl", { 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
-- 从Redis解析出该用户的Url
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
-- 设置重定向的url
ngx.var.target = server
ngx.log(ngx.ERR, "server is =========: ",server)
';
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;
proxy_set_header X_CSRFToken $csrftoken;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
实现
在前端代码中先调用/Entrance,并在请求参数中添加key为userId的参数,Nginx会使用Redis将userId和URL做为键值对存储起来。后续的接口调用中,在参数列表里都加入前面的userId参数,Nginx会通过这个参数取到所需的URL。