nginx(非openresty) 实现解析uri自动upstream并支持动态新增删除(redisCluster)节点(四种方式)

来源:互联网 发布:淘宝店铺怎样使用seo 编辑:程序博客网 时间:2024/06/06 02:51

1.lua+本地properties文件(json/key:value)

2.nginx直接调用java模块(nginx-clojure)

思路:nginx启动时,同时运行自定义的jar包(openapi-nginx-java.jar),自定义jar包会初始化启动spring容器加载rediscluster,然后在location里面通过rewrite_handler去调用java,java这边implements NginxJavaRingHandler接口能做各种操作,我这里需要设置变量来upstream,所以java这边还需要nginxJavaRequest.setVariable(String name, String value);来设置nginx内存

两个类,一个初始化,一个实时调用
初始化(com.pa.openapi.nginx.JVMInitHandler):

package com.pa.openapi.nginx;


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.pa.openapi.cache.core.framework.realize.CacheUtil;
import nginx.clojure.java.Constants;
import nginx.clojure.java.NginxJavaRingHandler;
import com.pa.openapi.nginx.util.PropertiesUtils;


public class JVMInitHandler implements NginxJavaRingHandler{


private static ClassPathXmlApplicationContext context = null;
    static final String CLASSPATH="classpath*:applicationContext.xml";
    
    public static Map<String, String> NODES_MAP = new ConcurrentHashMap<String,String>();
    
    private static final Logger LOGGER = LoggerFactory.getLogger(JVMInitHandler.class); 
    
    public static ClassPathXmlApplicationContext getContext() {
        return new ClassPathXmlApplicationContext(CLASSPATH);
    }


    private static void init(){
        try {
        getContext();
        NODES_MAP.putAll(PropertiesUtils.propertiesToMap());
        } catch (Exception e) {
        LOGGER.error(e.getMessage());
        }
    }


public Object[] invoke(Map<String, Object> request) throws IOException {
init();
try {
LOGGER.debug("NODES_MAP = "+NODES_MAP.toString());
CacheUtil.set("nginx-java", "version1.0");
Object nginxJavaValue = CacheUtil.get("nginx-java");
LOGGER.debug("nginxJavaValue = "+nginxJavaValue.toString());
CacheUtil.removeKey("nginx-java");
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
return Constants.PHASE_DONE;
}
}


实时调用(com.pa.openapi.nginx.RewriteHandler):

package com.pa.openapi.nginx;


import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pa.openapi.cache.core.framework.realize.CacheUtil;


import nginx.clojure.java.ArrayMap;
import nginx.clojure.java.Constants;
import nginx.clojure.java.NginxJavaRequest;
import nginx.clojure.java.NginxJavaRingHandler;


/**
 * rewrite handler rewrite handler可用于请求的转发。
 * @author DENGXINTAO073
 *
 */
public class RewriteHandler implements NginxJavaRingHandler {


private static final Logger LOGGER = LoggerFactory.getLogger(RewriteHandler.class); 


private static final ObjectMapper MAPPER = new ObjectMapper();


private static Map<String, String> map =JVMInitHandler.NODES_MAP;


private static String regexAuthApp = "^.*/AuthApp/.*$";


private static String ReqUriRegex = "^.*openapi/(\\w+)/(\\w+)(/\\w+)?(/|\\?)?\\??.*$";


public Object[] invoke(Map<String, Object> request) {
try {
long startTime = System.currentTimeMillis();
NginxJavaRequest nginxJavaRequest = (NginxJavaRequest) request;


String reqUri = nginxJavaRequest.getVariable(Constants.URI);
LOGGER.debug("The URI is :"+reqUri);


String requestBody = getRequestBody(request);
LOGGER.debug("The requestBody is :"+requestBody);

String comp_sign = map.get(getCompSign(reqUri,requestBody));
//String comp_sign = CacheUtil.get(getCompSign(reqUri,requestBody));
LOGGER.debug("The comp_sign is :"+comp_sign);


String reSetReqUri = getReSetReqUri(reqUri);
LOGGER.debug("The reSetReqUri is :"+reSetReqUri);


nginxJavaRequest.setVariable("comp_sign", comp_sign);
nginxJavaRequest.setVariable("reSetReqUri", reSetReqUri);


long totalTime = System.currentTimeMillis()-startTime;
LOGGER.debug("The totalTime is :"+totalTime+"ms");
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return new Object[] { 
Constants.NGX_HTTP_NOT_FOUND, //http status 404
ArrayMap.create(Constants.CONTENT_TYPE, "text/plain"), //headers map
"{404:网页找不到}" //response body can be string, File or Array/Collection of them
};
}
return Constants.PHASE_DONE;
}


public static String getCompSign(String reqUri,String requestBody) {
//得到forward_sbtpsboa_IPOsOrderCancel
Pattern pattern = Pattern.compile(ReqUriRegex);  
Matcher matcher = pattern.matcher(reqUri);
StringBuffer comSign = new StringBuffer();
if(matcher.find()){  
comSign.append(matcher.group(1)).append("_").append(matcher.group(2)).append("_");
if (matcher.group(3)!=null) {
comSign.append(matcher.group(3).substring(1));
}else {//uri不包含method,从requestBody中取
comSign.append(getRequestBodyHeadMethod(requestBody));
}
}
return comSign.toString();
}
public  static String getRequestBodyHeadMethod(String json) {
JsonNode jsonNode = null;
try {
jsonNode = MAPPER.readTree(json);
} catch (IOException e) {
LOGGER.error("exception requestBody is " + json);
LOGGER.error(e.getMessage(), e);

return jsonNode.get("head").get("method").asText() ;
}




public static String getReSetReqUri(String reqUri) {
if (reqUri.matches(regexAuthApp)) {
reqUri = reqUri.substring(reqUri.indexOf("AuthApp")+7);
LOGGER.debug("The regexAuthApp reqUri is :"+reqUri);
}
return reqUri;
}


public static String getRequestBody(Map<String, Object> request) {
String reqStr = "";
InputStream reqIn = (InputStream) request.get(Constants.BODY);
try {
if (reqIn == null) {
LOGGER.debug("request is null !");
}
reqStr = IOUtils.toString(reqIn, "UTF-8");
if (StringUtils.isBlank(reqStr)) {
LOGGER.debug("request is blank !");
}
reqStr = URLDecoder.decode(reqStr, "UTF-8");
}
catch (Exception e){
LOGGER.error("exception requestBody is " + request);
LOGGER.error(e.getMessage(), e);
}
return reqStr;
}
}


nginx.conf 配置:


#运行用户和组,缺省为nobody,若改为别的用户和组,则需要先创建用户和组
#user wls81 wls; 


#开启进程数,一般与CPU核数等同
worker_processes  4;


#设置进程到cpu(四cpu:0001 0010 0100 1000)
#worker_cpu_affinity 0001 0010 0100 1000;


#每个进程最大打开文件数
worker_rlimit_nofile 8000;


#进程号保存文件
#pid        /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/nginx.pid;
error_log  /wls/appsystems/nginx/nginx/logs/error.log;
pid        /wls/appsystems/nginx/nginx/logs/nginx.pid;


#设置错误日志
#error_log  /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
error_log  logs/error.log  debug;


events
{
    #运行模式设置[ kqueue | rtsig | epoll | /dev/poll | select | poll ];
    #使用epoll(linux2.6的高性能方式)
    use epoll;

    #每个进程最大连接数(最大连接=连接数x进程数)
    worker_connections  8000;
}


http
{


    #文件扩展名与文件类型映射表
    #include       mime.types;


    #默认文件类型
    #default_type  text/html;
    default_type  application/octet-stream;
    
    #服务器名称相关设置
    server_names_hash_max_size    256;
    server_names_hash_bucket_size 512;


    #默认编码
    charset UTF-8;


    #开启高效文件传输模式,直接从系统级别传输(Linux 2.4以上支持,纯文件服务器才能打开)
    sendfile   off;


    #网络TCP_NOPUSH和TCP_NODELAY参数设置
    #tcp_nopush on;
    tcp_nodelay on;


    #设置保留链接超时时间为75秒 设置header超时时间为20秒
    keepalive_timeout 75 20;


    #打开gzip压缩
    gzip  on;


    #最小压缩文件大小
    gzip_min_length  1K;


    #压缩缓冲区
    gzip_buffers     4 8k;


    #压缩类型
    gzip_types       text/* text/css application/javascript application/x-javascript application/xml;


    #压缩级别 1-9 1最快 9最慢
    gzip_comp_level  9;


    #压缩通过代理的所有文件
    gzip_proxied     any;


    #vary header支持
    gzip_vary        on;


    #压缩版本(默认1.1,前端为squid2.5使用1.0)
    gzip_http_version 1.1;
    


    #输出缓冲区
    output_buffers   4  32k;


    #输出拆包大小
    postpone_output  1460;


    #接收header的缓冲区大小
    client_header_buffer_size 128k;
    large_client_header_buffers 4 256k;


    #客户端发送header超时
    client_header_timeout  3m;


    #客户端发送内容超时
    client_body_timeout    3m;


    #发送到客户端超时
    send_timeout           3m;






    #捕捉代理端的http错误
    #proxy_intercept_errors  on;


    jvm_path '/wls/appsystems/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so';


    jvm_classpath '/wls/appsystems/jdk1.8.0_25/lib/*:/wls/appsystems/nginx/libs/nginx-clojure/openapi-nginx-java.jar';


#init初始化handle
    jvm_handler_type 'java';
    jvm_init_handler_name 'com.pa.openapi.nginx.JVMInitHandler';




    #日志文件格式
    log_format main '$remote_addr $http_x_forwarded_for $remote_user $time_iso8601 $status '
                           '$server_protocol $comp_sign $request_method $reSetReqUri $uri $http_referer $gzip_ratio '
                           '"$http_user_agent" '
                           '$body_bytes_sent $bytes_sent $request_length "$upstream_addr" "$upstream_header_time" "$upstream_response_time" $request_time';   
    log_format  requestBody  '$remote_addr - $remote_user [$time_local] "$request" '
                      '"$status" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_body"'
                      '$upstream_addr $bytes_sent $request_length "$upstream_response_time" "$request_time"';
    #日志文件(不记录)
    #access_log  /dev/null;
    #access_log   logs/access.log main;


include /wls/appsystems/nginx/nginx/conf/servers/respCodeMap.map;
#api映射配置
lua_shared_dict apiMappingShared 50m;
lua_shared_dict healthStatus 1m;
client_body_buffer_size 8m;
client_max_body_size 8m;
init_by_lua_file /wls/appsystems/nginx/nginx/conf/scripts/luas/init.lua;
#获取访问客户的真实IP
map $http_x_forwarded_for  $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr;
}




    #默认主机配置
    #include default_host.conf;

upstream SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS
{   
  #tomcat的地址和端口
server 10.25.174.28:32050;
}

    server
{
#设置监听端口
listen 37775 default;

#设置服务器域名(IP访问和多域名访问可不设置)
#server_name _*;
#server_name 192.168.23.23;
#server_name  www.test.com;



error_log  /wls/appsystems/nginx/nginx/logs/error.log debug;



set $comp_sign "";
set $reSetReqUri $request_uri;


#设定根目录(若全部请求转发到后端服务器则不需要设置) 
 
error_page 404 = /httpStatusRewrite?apiRespCodeParam=-10201;
error_page 403 = /httpStatusRewrite?apiRespCodeParam=-5;
error_page 503 = /httpStatusRewrite?apiRespCodeParam=-6;
error_page 500 502 504  = /httpStatusRewrite?apiRespCodeParam=-1;


location /httpStatusRewrite{
default_type "text/plain";
set $apiRespCode  $arg_apiRespCodeParam;
if ( $apiRespMsg = '' ) {
return 200 '{"resCode":"-1","resMsg":"请求失败"}';
}
return 200 '{"resCode":"$apiRespCode","resMsg":"$apiRespMsg"}';
}



location /
{
  加上他会读取POST请求数据,不需要的时候建议关掉
 always_read_body on;
 web根目录,根据实际情况调整
 proxy_set_header Host $host;
 proxy_set_header            X-real-ip $remote_addr;
 proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;


 rewrite_handler_type 'java';
 rewrite_handler_name 'com.pa.openapi.nginx.RewriteHandler';

 proxy_pass         http://$comp_sign/AuthApp$reSetReqUri;
}

}

    #包含其它虚拟主机配置;
    #include servers/*.com;
    include servers/*.net;
    include servers/*.org;
    include servers/*.cn;
}

3.lua+springboot-rest+ngx.location.capture方式

两个类,一个初始化,一个实时rest调用
初始化(com.pa.openapi.nginx.run.Application):
实时rest调用(com.pa.openapi.nginx.controller.CacheController):


com.pa.openapi.nginx.run.Application:


package com.pa.openapi.nginx.run;


import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.context.annotation.ImportResource;
import org.springframework.http.HttpStatus;


import com.pa.openapi.nginx.util.PropertiesUtils;
/**
 * 
 * @author DENGXINTAO073
 *
 */
@SpringBootApplication
@ImportResource(locations = {"classpath*:applicationContext.xml"})
public class Application implements EmbeddedServletContainerCustomizer {


public static Map<String, String> NODES_MAP = new ConcurrentHashMap<String,String>();
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        NODES_MAP.putAll(PropertiesUtils.propertiesToMap());
    }


@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
        ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
        ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
container.setPort(8888);
container.addErrorPages(error401Page, error404Page, error500Page);
}
}


com.pa.openapi.nginx.controller.CacheController:


package com.pa.openapi.nginx.controller;


import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


import com.pa.openapi.cache.core.framework.realize.CacheUtil;
import com.pa.openapi.nginx.run.Application;
/**
 * 
 * @author DENGXINTAO073
 *
 */
@Controller
@RequestMapping(value = "/nginx")
public class CacheController {

private static final Logger LOGGER = LoggerFactory.getLogger(CacheController.class); 


private static final String CACHE_VALUE_NULL = "CACHE_VALUE_NULL";//redis返回null值
private static final String CACHE_VALUE_ERROR = "CACHE_VALUE_ERROR";//redis抛异常啦


@RequestMapping(value="/redis/{cacheKey}")
@ResponseBody
public String getCacheValue(@PathVariable String cacheKey) {
String cacheValue = "";
try {
//cacheValue = Application.NODES_MAP.get(cacheKey);
//1.cacheValue 抛异常
//2.cacheValue=null
cacheValue = CacheUtil.get(cacheKey);
cacheValue = "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS";
if (StringUtils.isBlank(cacheValue)) {
cacheValue = CACHE_VALUE_NULL;
}
} catch (Exception e) {
cacheValue = CACHE_VALUE_ERROR;
LOGGER.error(e.getMessage(), e);
}
return cacheValue ;
}
}

提前启动jar包

java -cp openapi-nginx-cache.jar com.pa.openapi.nginx.run.Application


nginx.conf配置:


#运行用户和组,缺省为nobody,若改为别的用户和组,则需要先创建用户和组
#user wls81 wls; 


#开启进程数,一般与CPU核数等同
worker_processes  4;


#设置进程到cpu(四cpu:0001 0010 0100 1000)
#worker_cpu_affinity 0001 0010 0100 1000;


#每个进程最大打开文件数
worker_rlimit_nofile 8000;


#进程号保存文件
#pid        /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/nginx.pid;
error_log  /wls/appsystems/nginx/nginx/logs/error.log;
pid        /wls/appsystems/nginx/nginx/logs/nginx.pid;


#设置错误日志
#error_log  /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
error_log  logs/error.log  debug;


events
{
    #运行模式设置[ kqueue | rtsig | epoll | /dev/poll | select | poll ];
    #使用epoll(linux2.6的高性能方式)
    use epoll;

    #每个进程最大连接数(最大连接=连接数x进程数)
    worker_connections  8000;
}


http
{


    #文件扩展名与文件类型映射表
    #include       mime.types;


    #默认文件类型
    #default_type  text/html;
    default_type  application/octet-stream;
    
    #服务器名称相关设置
    server_names_hash_max_size    256;
    server_names_hash_bucket_size 512;


    #默认编码
    charset UTF-8;


    #开启高效文件传输模式,直接从系统级别传输(Linux 2.4以上支持,纯文件服务器才能打开)
    sendfile   off;


    #网络TCP_NOPUSH和TCP_NODELAY参数设置
    #tcp_nopush on;
    tcp_nodelay on;


    #设置保留链接超时时间为75秒 设置header超时时间为20秒
    keepalive_timeout 75 20;


    #打开gzip压缩
    gzip  on;


    #最小压缩文件大小
    gzip_min_length  1K;


    #压缩缓冲区
    gzip_buffers     4 8k;


    #压缩类型
    gzip_types       text/* text/css application/javascript application/x-javascript application/xml;


    #压缩级别 1-9 1最快 9最慢
    gzip_comp_level  9;


    #压缩通过代理的所有文件
    gzip_proxied     any;


    #vary header支持
    gzip_vary        on;


    #压缩版本(默认1.1,前端为squid2.5使用1.0)
    gzip_http_version 1.1;
    


    #输出缓冲区
    output_buffers   4  32k;


    #输出拆包大小
    postpone_output  1460;


    #接收header的缓冲区大小
    client_header_buffer_size 128k;
    large_client_header_buffers 4 256k;


    #客户端发送header超时
    client_header_timeout  3m;


    #客户端发送内容超时
    client_body_timeout    3m;


    #发送到客户端超时
    send_timeout           3m;






    #捕捉代理端的http错误
    #proxy_intercept_errors  on;





    #日志文件格式
    log_format main '$remote_addr $http_x_forwarded_for $remote_user $time_iso8601 $status '
                           '$server_protocol $comp_sign $request_method $reSetReqUri $uri $http_referer $gzip_ratio '
                           '"$http_user_agent" '
                           '$body_bytes_sent $bytes_sent $request_length "$upstream_addr" "$upstream_header_time" "$upstream_response_time" $request_time';   
    log_format  requestBody  '$remote_addr - $remote_user [$time_local] "$request" '
                      '"$status" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_body"'
                      '$upstream_addr $bytes_sent $request_length "$upstream_response_time" "$request_time"';
    #日志文件(不记录)
    #access_log  /dev/null;
    #access_log   logs/access.log main;


include /wls/appsystems/nginx/nginx/conf/servers/respCodeMap.map;
#api映射配置
lua_shared_dict apiMappingShared 50m;
lua_shared_dict healthStatus 1m;
client_body_buffer_size 8m;
client_max_body_size 8m;
init_by_lua_file /wls/appsystems/nginx/nginx/conf/scripts/luas/init.lua;
#获取访问客户的真实IP
map $http_x_forwarded_for  $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr;
}




    #默认主机配置
    #include default_host.conf;

upstream SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS
{   
  #tomcat的地址和端口
server 10.25.174.28:32050;
}

    server
{
#设置监听端口
listen 37775 default;

#设置服务器域名(IP访问和多域名访问可不设置)
#server_name _*;
#server_name 192.168.23.23;
#server_name  www.test.com;


error_log  /wls/appsystems/nginx/nginx/logs/error.log debug;


set $comp_sign "";
set $reSetReqUri $request_uri;

#设定根目录(若全部请求转发到后端服务器则不需要设置) 
 
error_page 404 = /httpStatusRewrite?apiRespCodeParam=-10201;
error_page 403 = /httpStatusRewrite?apiRespCodeParam=-5;
error_page 503 = /httpStatusRewrite?apiRespCodeParam=-6;
error_page 500 502 504  = /httpStatusRewrite?apiRespCodeParam=-1;


location /httpStatusRewrite{
default_type "text/plain";
set $apiRespCode  $arg_apiRespCodeParam;
if ( $apiRespMsg = '' ) {
return 200 '{"resCode":"-1","resMsg":"请求失败"}';
}
return 200 '{"resCode":"$apiRespCode","resMsg":"$apiRespMsg"}';
}
location /springboot
{
default_type "text/plain";
set $apiSign $arg_apiSign;
#proxy_pass         http://localhost:8888/nginx/redis/forward_sbtpsboa_IPOsOrderCancel;
proxy_pass         http://localhost:8888/nginx/redis/$apiSign;
}


#设定根目录(若全部请求转发到后端服务器则不需要设置) 
location /
{
 #web根目录,根据实际情况调整
 proxy_set_header Host $host;
 proxy_set_header            X-real-ip $remote_addr;
 proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
 set $comp_sign AUTH2;
 set $reSetReqUri $request_uri;
 rewrite_by_lua  'apiMapping.getCompSign()';  
 proxy_pass         http://$comp_sign/AuthApp$reSetReqUri;
}
}

    #包含其它虚拟主机配置;
    #include servers/*.com;
    include servers/*.net;
    include servers/*.org;
    include servers/*.cn;
}


apiMapping.lua脚本:


apiMapping={};


apiMapping.mappingJsonFile=SCRIPT_ROOT_PATH.."scripts/luas/modules/apimapping/apiMapping.json";


function apiMapping.init()
--local cjson = require "cjson";
local apiMappingShared = ngx.shared.apiMappingShared;
local file = io.open(apiMapping.mappingJsonFile, "r");
local ret,pcallBack=pcall(parseJson,file:read("*all"));
file:close();
if ret then
apiMappingShared:flush_all();
for name, value in pairs(pcallBack) do
apiMappingShared:set(name, value);
end
else
ngx.log(ngx.ERR,"init method,JSON PARSE apiMapping.json error.");
end


end


function parseJson(jsonString)
if jsonString then
--local cjson = require "cjson"
--parse json
local data= cjson.decode(jsonString);
--ngx.say(data["appId"])
return data;
else
return nil;
end
end


function httpPostParamReader()
-- read post data
ngx.req.read_body()
local data = ngx.req.get_body_data()
local postData = nil;
local ret,backData=pcall(parseJson,data);
if ret then
postData = backData;
else
ngx.log(ngx.ERR,"reloadApiMapping JSON PARSE apiMapping post json data error.");
end
return postData;
end


function copyfile(source,destination)
sourcefile = io.open(source,"r")
destinationfile = io.open(destination,"w")
for line in sourcefile:lines() do
destinationfile:write(line)
end
sourcefile:close()
destinationfile:close()
end


function printCaptureResult(code)
local responseBody =ngx.location.capture("/httpStatusRewrite?apiRespCodeParam="..code);
ngx.say(responseBody['body'])
ngx.exit(ngx.HTTP_OK)
--ngx.say(msg)
end


function routeLocation(apiSign)
--local responseBody =ngx.location.capture("/springboot/"..apiSign);
local responseBody =ngx.location.capture("/springboot?cacheKey="..apiSign);
ngx.log(ngx.ERR,"this is routeLocation:"..apiSign);
ngx.log(ngx.ERR,"the responseBody.status is :"..responseBody.status);
ngx.log(ngx.ERR,"the responseBody is :"..responseBody.body);
return responseBody.body
end


function getRedisClusterInstance()
local config = {
name="openapi",
serv_list = {
{ip="10.25.174.28", port = 6001},
   {ip="10.25.174.28", port = 6002},
{ip="10.25.174.28", port = 6003},
{ip="10.25.174.28", port = 7001},
{ip="10.25.174.28", port = 7002},
{ip="10.25.174.28", port = 7003},
{ip="10.25.174.28", port = 6001},
{ip="10.25.174.28", port = 6002},
},
keepalive_timeout = 1000,
keepalove_cons = 20
}
local redis_cluster = require "resty.rediscluster";
local red = redis_cluster:new(config);
return red
end


function getRedisClusterCompSign(apiSign)
local red = getRedisClusterInstance();
--local res = red:init_pipeline()
ngx.log(ngx.ERR,"config.redis_keepalive_timeout is :"..red.config.keepalive_timeout)
ngx.log(ngx.ERR,"apiSign is :"..apiSign)
--red:set("dog", "an animal")
--red:set("forward_sbtpsboa_queryIPOsSecuInfo", "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
red:set(apiSign, "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
--red:get("dog")
--local results, err = red:get("forward_sbtpsboa_queryIPOsSecuInfo")
local results, err = red:get(apiSign)
--red:close()
--local results, err = red:commit_pipeline()
--local cjson = require "cjson"
--ngx.log(ngx.ERR,"result is :"..cjson.encode(results))
ngx.log(ngx.ERR,"result is :"..results)
return results

end


function apiMapping.reloadApiMapping()
local postBody = httpPostParamReader();
if postBody then
local apiMappingShared = ngx.shared.apiMappingShared


local confJson = {};
for apiSign, compSign in pairs(postBody) do
--ngx.say(table2str(mapping))
confJson[apiSign]=compSign;
apiMappingShared:set(apiSign,compSign)
end
local bakFile=apiMapping.mappingJsonFile..".bak";
copyfile(apiMapping.mappingJsonFile,bakFile);
local f=io.open(apiMapping.mappingJsonFile,"w+")
f:write("{\n");
if next(confJson) ~=nil then
local idx =1;
for key, value in pairs(confJson) do
if idx>1 then
f:write(",\n");
end
f:write("\""..key.."\":".."\""..value.."\"");
f:flush()
idx = idx+1;
end
end
f:write("\n}");
f:close();

printCaptureResult(0);
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=0");

--ngx.say("success");
else
printCaptureResult(-10000)
 
--ngx.say("empty request data");
end
end




function readGetTypeParam(source)
local nSplitArray = {}
for match in (source):gmatch("(.-)" .. "&" .. "()" ) do
local equalIdx = string.find(match,"=");
if equalIdx then
local paramName = string.sub(match, 1, equalIdx-1) ;
local paramValue = string.sub(match, equalIdx+1, string.len(match)) ;
--ngx.say("paramName:"..paramName)
--ngx.say("paramValue:"..paramValue)
if paramName then
paramName = string.match(paramName,"%s*(.-)%s*$");
if paramValue then
paramValue = string.match(paramValue,"%s*(.-)%s*$");
end
--ngx.say("put param :"..paramName.."|"..paramValue)
nSplitArray[paramName] = paramValue;
else
return false,nil;
end
end
end
return true,nSplitArray;
end
function decodeURI(s)
    s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
    return s
end
function httpPostParamReader()
-- read post data
ngx.req.read_body()
local data = ngx.req.get_body_data()
if data == nil then 
printCaptureResult(-10000)
 
--return 
end
data  = ngx.unescape_uri(data)
local contentType = ngx.req.get_headers()["content-type"] ;
local postData = nil;
local resCode = nil;
if contentType and string.find(contentType,"application/json") then
--json reader
--ngx.log(ngx.INFO,data);
local ret,backData=pcall(parseJson,data);
if ret then
postData = backData;
else
printCaptureResult(-1006)
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");
--ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");
end
else
-- array reader
local code,backData = readGetTypeParam(data);
if code then
postData = backData;
else
printCaptureResult(-1006)
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");
--ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");
end
end
return postData;
end
function endwith(str, substr)
        if str == nil or substr == nil then
            return nil, "the string or the sub-string parameter is nil"
        end
        str_tmp = string.reverse(str)
        substr_tmp = string.reverse(substr)
        if string.find(str_tmp, substr_tmp) ~= 1 then
            return false
        else
            return true
        end
end 
function apiMapping.getCompSign()
--ngx.log(ngx.ERR,"getCompSign..................");
local request_method = ngx.var.request_method
--获取参数的值
if "GET" == request_method then
--ngx.header.content_type = "application/json";
printCaptureResult(-1013)
end
local postBody = httpPostParamReader();
if postBody then
--ngx.say("ngx.var.uri:"..ngx.var.uri);
local reqUri = ngx.var.uri;
if endwith(reqUri,"/") then 
reqUri = string.sub(reqUri,1,string.len(reqUri)-1)
end
local apiSign = nil;
if(string.find(reqUri, "/AuthApp/")==1) then 
reqUri = string.sub(reqUri,9);
ngx.var.reSetReqUri = string.sub(ngx.var.reSetReqUri,9);
end
if(string.find(reqUri, "/file/")==1) then 
apiSign = string.gsub(string.sub(reqUri,7),"/","_") ;
else 
apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;
end
--ngx.say("apiSign:"..apiSign);
local head = postBody["head"];
if(head ==nil) then 
printCaptureResult(-1006)
end
local method = head["method"];
--ngx.log(ngx.ERR,"method"..method);
--ngx.say("method:"..cjson.encode(postBody));
if method and string.match(method,"%s*(.-)%s*$") ~= "" then
if not endwith(apiSign,"_"..method) then 
apiSign = apiSign.."_" .. string.match(method,"%s*(.-)%s*$");
end
end
--ngx.log(ngx.ERR,"apiSign:"..apiSign);
--local cjson = require "cjson"
--ngx.say("apiSign:"..apiSign);


--local apiMappingConf = ngx.shared.apiMappingShared
--local res = apiMappingConf:get(apiSign)
local res = routeLocation(apiSign)
--local res = getRedisClusterCompSign(apiSign)
--ngx.say("apiSign:"..res);
ngx.log(ngx.ERR,"res:"..res);
if res == nil then 
local openId = postBody["openId"];
if openId then 
apiSign = openId.."_"..apiSign.."_" .. string.match(openId,"%s*(.-)%s*$");
res = apiMappingConf:get(apiSign)
end
end
--ngx.log(ngx.ERR,"apiSign2"..apiSign);
--ngx.say("apiSign:"..res);
if res then
ngx.var.comp_sign = res;
--ngx.say("res:"..res);
else
ngx.log(ngx.ERR,"undefined api sign is :"..apiSign);
--ngx.say("res:"..apiSign);
--ngx.exit(ngx.HTTP_OK)
printCaptureResult(-10201)
end


end
end


return apiMapping;


4.lua+lua-resty-redis-cluster-master方式

1.添加redis2-nginx-module

redis2-nginx-module-0.13.tar.gz(https://github.com/openresty/redis2-nginx-module)

解压后安装,命令如下:
1.#make PREFIX=/wls/appsystems/nginx/nginxmodule/redis2-nginx-module/redis2-nginx-module-0.13

2.#makeinstall

注:PREFIX参数必须为redis2-nginx-module的安装路径/wls/appsystems/nginx/nginxmodule/redis2-nginx-module/redis2-nginx-module-0.13

2.确认添加模块成功

1.在/wls/appsystems/nginx/nginx/sbin下执行./nginx -V
2.configure arguments:有redis2-nginx-module-0.13模块表示成功

3.添加lua-resty-redis-cluster

lua-resty-redis-cluster-master.zip(https://github.com/cuiweixie/lua-resty-redis-cluster)

1.解压至/wls/appsystems/nginx/nginxmodule后编辑lua-resty-redis-cluster-master下的Makefile文件,改动点

    1.1更新路径

         OPENRESTY_PREFIX=/wls/appsystems/nginx

         PREFIX=/wls/appsystems/nginx/luajit

         LUA_INCLUDE_DIR=/wls/appsystems/nginx/luajit/include/luajit-2.0

         LUA_LIB_DIR=/wls/appsystems/nginx/luajit/lib/lua/5.1

         INSTALL=install

    1.2lib/redis_slot.o行命令更新为:

         lib/redis_slot.o:lib/redis_slot.c

         $(CC)-I$(LUA_INCLUDE_DIR) $(CMPFLAG) -o $@ $^

2在当前目录下执行make命令产生*.so文件

3将当前lua-resty-redis-cluster-master/lib下的libredis_slot.so文件拷贝到luajit的存放.so文件目录cp libredis_slot.so /wls/appsystems/nginx/luajit/lib/lua/5.1

4将lua-resty-redis-cluster-master\lib\resty下的rediscluster.lua拷贝到你自己业务加载的目录下/wls/appsystems/nginx/nginx/conf/scripts/luas/modules/apimapping/resty


4.添加lua-resty-redis

lua-resty-redis-master.zip(https://github.com/openresty/lua-resty-redis)

解压至/wls/appsystems/nginx/nginxmodule后直接将lua-resty-redis-master\lib\resty下的redis.lua拷贝到你自己业务加载的目录下/wls/appsystems/nginx/nginx/conf/scripts/luas/modules/apimapping/resty

5.更新nginx.conf文件以及业务脚本apiMapping.lua

apiMapping.lua脚本如下:

apiMapping={};


apiMapping.mappingJsonFile=SCRIPT_ROOT_PATH.."scripts/luas/modules/apimapping/apiMapping.json";


function apiMapping.init()
--local cjson = require "cjson";
local apiMappingShared = ngx.shared.apiMappingShared;
local file = io.open(apiMapping.mappingJsonFile, "r");
local ret,pcallBack=pcall(parseJson,file:read("*all"));
file:close();
if ret then
apiMappingShared:flush_all();
for name, value in pairs(pcallBack) do
apiMappingShared:set(name, value);
end
else
ngx.log(ngx.ERR,"init method,JSON PARSE apiMapping.json error.");
end


end


function parseJson(jsonString)
if jsonString then
--local cjson = require "cjson"
--parse json
local data= cjson.decode(jsonString);
--ngx.say(data["appId"])
return data;
else
return nil;
end
end


function httpPostParamReader()
-- read post data
ngx.req.read_body()
local data = ngx.req.get_body_data()
local postData = nil;
local ret,backData=pcall(parseJson,data);
if ret then
postData = backData;
else
ngx.log(ngx.ERR,"reloadApiMapping JSON PARSE apiMapping post json data error.");
end
return postData;
end


function copyfile(source,destination)
sourcefile = io.open(source,"r")
destinationfile = io.open(destination,"w")
for line in sourcefile:lines() do
destinationfile:write(line)
end
sourcefile:close()
destinationfile:close()
end


function printCaptureResult(code)
local responseBody =ngx.location.capture("/httpStatusRewrite?apiRespCodeParam="..code);
ngx.say(responseBody['body'])
ngx.exit(ngx.HTTP_OK)
--ngx.say(msg)
end


function routeLocation(apiSign)
--local responseBody =ngx.location.capture("/springboot/"..apiSign);
local responseBody =ngx.location.capture("/springboot?cacheKey="..apiSign);
ngx.log(ngx.ERR,"this is routeLocation:"..apiSign);
ngx.log(ngx.ERR,"the responseBody.status is :"..responseBody.status);
ngx.log(ngx.ERR,"the responseBody is :"..responseBody.body);
return responseBody.body
end


function getRedisClusterInstance()
local config = {
name="openapi",
serv_list = {
{ip="10.25.174.28", port = 6001},
{ip="10.25.174.28", port = 6002},
{ip="10.25.174.28", port = 6003},
{ip="10.25.174.28", port = 7001},
{ip="10.25.174.28", port = 7002},
{ip="10.25.174.28", port = 7003},
{ip="10.25.174.28", port = 6001},
{ip="10.25.174.28", port = 6002},
},
keepalive_timeout = 1000,
keepalove_cons = 20
}
local redis_cluster = require "resty.rediscluster";
local red = redis_cluster:new(config);
return red
end



function getRedisClusterCompSign(apiSign)
local red = getRedisClusterInstance();

--local res = red:init_pipeline()
ngx.log(ngx.ERR,"config.redis_keepalive_timeout is :"..red.config.keepalive_timeout)
ngx.log(ngx.ERR,"apiSign is :"..apiSign)
--red:set("dog", "an animal")
--red:set("forward_sbtpsboa_queryIPOsSecuInfo", "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
red:set(apiSign, "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
--red:get("dog")
--local results, err = red:get("forward_sbtpsboa_queryIPOsSecuInfo")
local results, err = red:get(apiSign)
--red:close()
--local results, err = red:commit_pipeline()
--local cjson = require "cjson"
--ngx.log(ngx.ERR,"result is :"..cjson.encode(results))
ngx.log(ngx.ERR,"result is :"..results)
return results

end


function apiMapping.reloadApiMapping()
local postBody = httpPostParamReader();
if postBody then
local apiMappingShared = ngx.shared.apiMappingShared


local confJson = {};
for apiSign, compSign in pairs(postBody) do
--ngx.say(table2str(mapping))
confJson[apiSign]=compSign;
apiMappingShared:set(apiSign,compSign)
end
local bakFile=apiMapping.mappingJsonFile..".bak";
copyfile(apiMapping.mappingJsonFile,bakFile);
local f=io.open(apiMapping.mappingJsonFile,"w+")
f:write("{\n");
if next(confJson) ~=nil then
local idx =1;
for key, value in pairs(confJson) do
if idx>1 then
f:write(",\n");
end
f:write("\""..key.."\":".."\""..value.."\"");
f:flush()
idx = idx+1;
end
end
f:write("\n}");
f:close();

printCaptureResult(0);
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=0");

--ngx.say("success");
else
printCaptureResult(-10000)
 
--ngx.say("empty request data");
end
end




function readGetTypeParam(source)
local nSplitArray = {}
for match in (source):gmatch("(.-)" .. "&" .. "()" ) do
local equalIdx = string.find(match,"=");
if equalIdx then
local paramName = string.sub(match, 1, equalIdx-1) ;
local paramValue = string.sub(match, equalIdx+1, string.len(match)) ;
--ngx.say("paramName:"..paramName)
--ngx.say("paramValue:"..paramValue)
if paramName then
paramName = string.match(paramName,"%s*(.-)%s*$");
if paramValue then
paramValue = string.match(paramValue,"%s*(.-)%s*$");
end
--ngx.say("put param :"..paramName.."|"..paramValue)
nSplitArray[paramName] = paramValue;
else
return false,nil;
end
end
end
return true,nSplitArray;
end
function decodeURI(s)
    s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
    return s
end
function httpPostParamReader()
-- read post data
ngx.req.read_body()
local data = ngx.req.get_body_data()
if data == nil then 
printCaptureResult(-10000)
 
--return 
end
data  = ngx.unescape_uri(data)
local contentType = ngx.req.get_headers()["content-type"] ;
local postData = nil;
local resCode = nil;
if contentType and string.find(contentType,"application/json") then
--json reader
--ngx.log(ngx.INFO,data);
local ret,backData=pcall(parseJson,data);
if ret then
postData = backData;
else
printCaptureResult(-1006)
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");
--ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");
end
else
-- array reader
local code,backData = readGetTypeParam(data);
if code then
postData = backData;
else
printCaptureResult(-1006)
--ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");
--ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");
end
end
return postData;
end
function endwith(str, substr)
        if str == nil or substr == nil then
            return nil, "the string or the sub-string parameter is nil"
        end
        str_tmp = string.reverse(str)
        substr_tmp = string.reverse(substr)
        if string.find(str_tmp, substr_tmp) ~= 1 then
            return false
        else
            return true
        end
end 
function apiMapping.getCompSign()
--ngx.log(ngx.ERR,"getCompSign..................");
local request_method = ngx.var.request_method
--获取参数的值
if "GET" == request_method then
--ngx.header.content_type = "application/json";
printCaptureResult(-1013)
end
local postBody = httpPostParamReader();
if postBody then
--ngx.say("ngx.var.uri:"..ngx.var.uri);
local reqUri = ngx.var.uri;
if endwith(reqUri,"/") then 
reqUri = string.sub(reqUri,1,string.len(reqUri)-1)
end
local apiSign = nil;
if(string.find(reqUri, "/AuthApp/")==1) then 
reqUri = string.sub(reqUri,9);
ngx.var.reSetReqUri = string.sub(ngx.var.reSetReqUri,9);
end
if(string.find(reqUri, "/file/")==1) then 
apiSign = string.gsub(string.sub(reqUri,7),"/","_") ;
else 
apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;
end
--ngx.say("apiSign:"..apiSign);
local head = postBody["head"];
if(head ==nil) then 
printCaptureResult(-1006)
end
local method = head["method"];
--ngx.log(ngx.ERR,"method"..method);
--ngx.say("method:"..cjson.encode(postBody));
if method and string.match(method,"%s*(.-)%s*$") ~= "" then
if not endwith(apiSign,"_"..method) then 
apiSign = apiSign.."_" .. string.match(method,"%s*(.-)%s*$");
end
end
--ngx.log(ngx.ERR,"apiSign:"..apiSign);
--local cjson = require "cjson"
--ngx.say("apiSign:"..apiSign);


--local apiMappingConf = ngx.shared.apiMappingShared
--local res = apiMappingConf:get(apiSign)
--local res = routeLocation(apiSign)
local res = getRedisClusterCompSign(apiSign)
--ngx.say("apiSign:"..res);
ngx.log(ngx.ERR,"res:"..res);
if res == nil then 
local openId = postBody["openId"];
if openId then 
apiSign = openId.."_"..apiSign.."_" .. string.match(openId,"%s*(.-)%s*$");
res = apiMappingConf:get(apiSign)
end
end
--ngx.log(ngx.ERR,"apiSign2"..apiSign);
--ngx.say("apiSign:"..res);
if res then
ngx.var.comp_sign = res;
--ngx.say("res:"..res);
else
ngx.log(ngx.ERR,"undefined api sign is :"..apiSign);
--ngx.say("res:"..apiSign);
--ngx.exit(ngx.HTTP_OK)
printCaptureResult(-10201)
end


end
end


return apiMapping;


nginx.conf文件如下:

#运行用户和组,缺省为nobody,若改为别的用户和组,则需要先创建用户和组
#user wls81 wls; 


#开启进程数,一般与CPU核数等同
worker_processes  4;


#设置进程到cpu(四cpu:0001 0010 0100 1000)
#worker_cpu_affinity 0001 0010 0100 1000;


#每个进程最大打开文件数
worker_rlimit_nofile 8000;


#进程号保存文件
#pid        /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/nginx.pid;
error_log  /wls/appsystems/nginx/nginx/logs/error.log;
pid        /wls/appsystems/nginx/nginx/logs/nginx.pid;


#设置错误日志
#error_log  /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
error_log  logs/error.log  debug;


events
{
    #运行模式设置[ kqueue | rtsig | epoll | /dev/poll | select | poll ];
    #使用epoll(linux2.6的高性能方式)
    use epoll;

    #每个进程最大连接数(最大连接=连接数x进程数)
    worker_connections  8000;
}


http
{


    #文件扩展名与文件类型映射表
    #include       mime.types;


    #默认文件类型
    #default_type  text/html;
    default_type  application/octet-stream;
    
    #服务器名称相关设置
    server_names_hash_max_size    256;
    server_names_hash_bucket_size 512;


    #默认编码
    charset UTF-8;


    #开启高效文件传输模式,直接从系统级别传输(Linux 2.4以上支持,纯文件服务器才能打开)
    sendfile   off;


    #网络TCP_NOPUSH和TCP_NODELAY参数设置
    #tcp_nopush on;
    tcp_nodelay on;


    #设置保留链接超时时间为75秒 设置header超时时间为20秒
    keepalive_timeout 75 20;


    #打开gzip压缩
    gzip  on;


    #最小压缩文件大小
    gzip_min_length  1K;


    #压缩缓冲区
    gzip_buffers     4 8k;


    #压缩类型
    gzip_types       text/* text/css application/javascript application/x-javascript application/xml;


    #压缩级别 1-9 1最快 9最慢
    gzip_comp_level  9;


    #压缩通过代理的所有文件
    gzip_proxied     any;


    #vary header支持
    gzip_vary        on;


    #压缩版本(默认1.1,前端为squid2.5使用1.0)
    gzip_http_version 1.1;
    


    #输出缓冲区
    output_buffers   4  32k;


    #输出拆包大小
    postpone_output  1460;


    #接收header的缓冲区大小
    client_header_buffer_size 128k;
    large_client_header_buffers 4 256k;


    #客户端发送header超时
    client_header_timeout  3m;


    #客户端发送内容超时
    client_body_timeout    3m;


    #发送到客户端超时
    send_timeout           3m;






    #捕捉代理端的http错误
    #proxy_intercept_errors  on;





    #日志文件格式
    log_format main '$remote_addr $http_x_forwarded_for $remote_user $time_iso8601 $status '
                           '$server_protocol $comp_sign $request_method $reSetReqUri $uri $http_referer $gzip_ratio '
                           '"$http_user_agent" '
                           '$body_bytes_sent $bytes_sent $request_length "$upstream_addr" "$upstream_header_time" "$upstream_response_time" $request_time';   
    log_format  requestBody  '$remote_addr - $remote_user [$time_local] "$request" '
                      '"$status" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_body"'
                      '$upstream_addr $bytes_sent $request_length "$upstream_response_time" "$request_time"';
    #日志文件(不记录)
    #access_log  /dev/null;
    #access_log   logs/access.log main;


include /wls/appsystems/nginx/nginx/conf/servers/respCodeMap.map;
#api映射配置
lua_shared_dict apiMappingShared 50m;
lua_shared_dict healthStatus 1m;
client_body_buffer_size 8m;
client_max_body_size 8m;
init_by_lua_file /wls/appsystems/nginx/nginx/conf/scripts/luas/init.lua;
#获取访问客户的真实IP
map $http_x_forwarded_for  $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr;
}




    #默认主机配置
    #include default_host.conf;

upstream SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS
{   
  #tomcat的地址和端口
server 10.25.174.28:32048;
server 10.25.174.28:32050;
server 10.25.174.28:32052;
server 10.25.174.28:32054;
keepalive 1024;
}

    server
{
#设置监听端口
listen 37775 default;

#设置服务器域名(IP访问和多域名访问可不设置)
#server_name _*;
#server_name 192.168.23.23;
#server_name  www.test.com;



error_log  /wls/appsystems/nginx/nginx/logs/error.log debug;



set $comp_sign "";
set $reSetReqUri $request_uri;

#设定根目录(若全部请求转发到后端服务器则不需要设置) 
 
error_page 404 = /httpStatusRewrite?apiRespCodeParam=-10201;
error_page 403 = /httpStatusRewrite?apiRespCodeParam=-5;
error_page 503 = /httpStatusRewrite?apiRespCodeParam=-6;
error_page 500 502 504  = /httpStatusRewrite?apiRespCodeParam=-1;


location /httpStatusRewrite{
default_type "text/plain";
set $apiRespCode  $arg_apiRespCodeParam;
if ( $apiRespMsg = '' ) {
return 200 '{"resCode":"-1","resMsg":"请求失败"}';
}
return 200 '{"resCode":"$apiRespCode","resMsg":"$apiRespMsg"}';
}
#设定根目录(若全部请求转发到后端服务器则不需要设置) 
location /
{
 #web根目录,根据实际情况调整
 proxy_set_header Host $host;
 proxy_set_header            X-real-ip $remote_addr;
 proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
 set $comp_sign AUTH2;
 set $reSetReqUri $request_uri;
 rewrite_by_lua  'apiMapping.getCompSign()';  
 proxy_pass         http://$comp_sign/AuthApp$reSetReqUri;
}
}

    #包含其它虚拟主机配置;
    #include servers/*.com;
    include servers/*.net;
    include servers/*.org;
    include servers/*.cn;
}

原创粉丝点击