openresty(完整版)Lua拦截请求与响应信息日志收集及基于cjson和redis动态路径以及Prometheus监控(转)
直接上文件
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/openresty-1.11.2.4/nginx/logs/error.log;
 - pid /wls/appsystems/nginx/openresty-1.11.2.4/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;
 - 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 logTraceId:$request_id $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" logTraceId:$request_id req_body:"$request_body" resp_body:"$resp_body" resp_map:"$resp_map"'
 - '$upstream_addr $bytes_sent $request_length "$upstream_response_time" "$request_time"';
 - lua_need_request_body on;
 - #日志文件(不记录)
 - #access_log /dev/null;
 - #access_log logs/access.log main;
 - #默认主机配置
 - #include default_host.conf;
 - #包含其它虚拟主机配置;
 - include servers/*.com;
 - include servers/*.net;
 - include servers/*.org;
 - include servers/*.cn;
 - }
 
sbtps-opf-sfweb-nginx.com
- include /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/servers/respCodeMap.map;
 - #api映射配置
 - lua_shared_dict apiMappingShared 50m;
 - lua_shared_dict healthStatus 1m;
 - lua_shared_dict redisSwitchShared 256k;
 - lua_shared_dict prometheus_metrics 10M;
 - client_body_buffer_size 8m;
 - client_max_body_size 8m;
 - init_by_lua_file /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/init.lua;
 - #获取访问客户的真实IP
 - map $http_x_forwarded_for $clientRealIp {
 - "" $remote_addr;
 - ~^(?P<firstaddr>[0-9\.]+),?.*$ $firstAddr;
 - }
 - #限制客户端的访问频次,这里限制每秒20次上限
 - limit_req_zone $clientRealIp zone=SF-WEB-AUTHAPP-LIMIT:10m rate=100r/s;
 - #配置负载均衡服务器(采用IP Hash算法,相同客户IP会转发到相同服务器)
 - 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 www.test.com;
 - #开启shtml支持
 - #ssi on;
 - #ssi_silent_errors on;
 - #ssi_types text/shtml;
 - #设置主访问日志
 - #access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/access.log main;
 - #access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/requestBody.log requestBody;
 - error_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/error.log error;
 - access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/access.log main;
 - error_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/request.log crit;
 - ##定义$request_trace_id的值,在1.11.x之前,我们可以使用类似的方式声明,只要能确保
 - ##其值出现重复的可能性尽可能的小即可。
 - set $request_trace_id trace-id-$pid-$connection-$bytes_sent-$msec;
 - set $comp_sign "";
 - set $reSetReqUri $request_uri;
 - set $resp_body "";
 - set $resp_map "";
 - set $apiSign "";
 - #access_log /dev/null;
 - #fastcgi_intercept_errors on;
 - #error_page 404 403 = /404.html;
 - #error_page 500 502 503 504 = /50x.html;
 - include /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/servers/server-http-error-page.err;
 - #设置转发到跟投APP后端服务器的URL(正则表达式)
 - #location ~ (^/pa/interface/jk/(cgi-bin|servlet|chart)/|\.jsp$)
 - #{
 - #proxy_pass http://backendServer;
 - #include proxy.conf;
 - #}
 - #设置转发到后端服务器的URL(正则表达式)
 - #location ~ (^/pa/newstock/hq/(cgi-bin|servlet|chart)/|\.jsp$)
 - #{
 - #proxy_pass http://backendServer;
 - #include proxy.conf;
 - #}
 - #设置监控nginx状态URL
 - #location /__nginxstatus
 - #{
 - # stub_status on;
 - # access_log off;
 - #}
 - location ^~ /reloadApiMapping {
 - default_type "text/plain";
 - content_by_lua '
 - require("apiMapping");
 - apiMapping.reloadApiMapping();
 - ';
 - }
 - location ^~ /setRedisSwitch {
 - default_type "text/plain";
 - content_by_lua '
 - ngx.log(ngx.ERR,"this is setRedisSwitch routeLocation !")
 - require("apiMapping");
 - apiMapping.setRedisSwitch();
 - ';
 - }
 - location /metrics {
 - content_by_lua '
 - metric_connections:set(ngx.var.connections_reading, {"active"})
 - metric_connections:set(ngx.var.connections_reading, {"reading"})
 - metric_connections:set(ngx.var.connections_waiting, {"waiting"})
 - metric_connections:set(ngx.var.connections_writing, {"writing"})
 - prometheus:collect()
 - ';
 - }
 - location /favicon.ico {
 - log_not_found off;
 - access_log off;
 - }
 - location ^~ /beat/checkSet {
 - default_type "text/plain";
 - content_by_lua '
 - local reqUri = ngx.var.uri;
 - local status=string.sub(reqUri,16,-1);
 - local healthStatus = ngx.shared.healthStatus;
 - healthStatus:set("status", status);
 - local data = {};
 - data["status"]=status;
 - ngx.say(cjson.encode(data));
 - ';
 - }
 - location ^~ /beat/check {
 - default_type "text/plain";
 - content_by_lua '
 - local healthStatus = ngx.shared.healthStatus;
 - local status = healthStatus:get("status");
 - if status == nil or status=="" then
 - status ="UP"
 - end
 - local data = {};
 - data["status"]=status;
 - ngx.say(cjson.encode(data));
 - ';
 - }
 - #设定根目录(若全部请求转发到后端服务器则不需要设置)
 - location /
 - {
 - #web根目录,根据实际情况调整
 - #limit_req zone=SF-WEB-AUTHAPP-LIMIT nodelay;
 - #proxy_pass http://SF-WEB-AUTHAPP/;
 - 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 logTraceId $request_id;
 - set $comp_sign AUTH2;
 - set $reSetReqUri $request_uri;
 - set $redisResultJson "";
 - lua_need_request_body on;
 - #set $resp_map "";
 - rewrite_by_lua 'apiMapping.getCompSign()';
 - body_filter_by_lua_file /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/modules/apimapping/request.lua;
 - proxy_set_header X-Request-ID $request_id;
 - proxy_pass http://$comp_sign/AuthApp$reSetReqUri;
 - log_by_lua_file /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/modules/apimapping/log.lua;
 - #log_by_lua 'ngx.log(ngx.ERR,"resp_map is :"..ngx.var.resp_map)';
 - }
 - }
 - </firstaddr>
 
server-http-error-page.err
- 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"}';
 - }
 
respCodeMap.map
- map $apiRespCode $apiRespMsg {
 - "0" "SUCCESS。";
 - "-10000" "参数不可为空。";
 - "-1" "请求失败。";
 - "-5" "禁止访问。";
 - "-6" "访问频率过快,请稍后再试。";
 - "-10201" "未定义路径。";
 - "-1006" "参数格式异常。";
 - "-1013" "目前仅支持POST请求方式。";
 - }
 
init.lua
- function init()
 - cjson = require "cjson";
 - lfs = require "lfs"
 - SCRIPT_ROOT_PATH = '/wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/';
 - initLuaModule()
 - apiMapping = require "apiMapping"
 - local LATENCY_BUCKETS = {0.05, 0.2, 0.5, 1, 5, 10}
 - local BYTESIZE_BUCKETS = {1, 3, 5, 10, 15 , 20}
 - prometheus = require("prometheus").init("prometheus_metrics")
 - --counter metrics for host+upstream
 - metric_requests = prometheus:counter("nginx_http_requests_total", "Number of HTTP requests", {"host","upstream", "status"})
 - --metric_ssorequests = prometheus:counter("nginx_http_sso_requests_total", "Number of HTTP sso requests", {"status"})
 - --gauge metrics
 - metric_connections = prometheus:gauge("nginx_http_connections", "Number of HTTP connections", {"state"})
 - --histogram metrics for upstream
 - metric_latency = prometheus:histogram("nginx_http_request_duration_seconds", "HTTP request latency", {"upstream"}, LATENCY_BUCKETS)
 - --metric_ssolatency = prometheus:histogram("nginx_http_sso_duration_seconds", "HTTP sso request latency",{}, LATENCY_BUCKETS)
 - metric_bytes = prometheus:histogram("nginx_http_request_bytes_sent", "HTTP responses size", {"upstream"}, BYTESIZE_BUCKETS)
 - apiMapping.init()
 - redisClusterConfig()
 - end
 - function initLuaModule(rootPath)
 - local rootPath=SCRIPT_ROOT_PATH..'scripts/luas/';
 - getpathes(rootPath, nil);
 - end
 - function getpathes(rootpath, pathes)
 - pathes = pathes or {}
 - local attr = lfs.attributes(rootpath)
 - if attr and attr.mode == 'directory' then
 - package.path = string.format("%s?.lua;%s", rootpath, package.path)
 - for entry in lfs.dir(rootpath) do
 - if entry ~= '.' and entry ~= '..' then
 - getpathes(rootpath .. entry.. '/', pathes)
 - end
 - end
 - end
 - return pathes
 - end
 - function redisClusterConfig()
 - 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 = 200,
 - keepalove_cons = 20
 - }
 - ngx.shared.redisClusterConfig = config;
 - networkSign = "OPENAPI_NGINX_ROUTE_NODE_LAN";--内网
 - --networkSign = "OPENAPI_NGINX_ROUTE_NODE_WAN";--外网
 - end
 - init();
 
apiMapping.json
- {
 - "forward_otc_signElectContract":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_test":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewSharePayment-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_queryIPOsSecuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_soas_findByBankText":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryUserOccuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryFundVol":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_historicalRevision":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2919000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kbss_signElectronicPact":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forword_kbss_getAccountByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_getCustIDCardImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getXjbProgress":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_khpp_insertDataBatch":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findThreeBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2935000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912031":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912022":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_submitCustRiskAns":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_merchandiseOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_openQER":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_batch_collectionTbcBankInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custInfoCheckoptn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_listBoodsBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_khpp_loadData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_getDZHOpenaccResultInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryRiskLevel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_submitRish":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryAccountInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2935021":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_readImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryMatched":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxpService_zpck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryBankSecurityTrans":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_bankAuth":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_uploadIdImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_push_applyPush":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912027":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_bindCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryAccounts ":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_dubbo_returnString":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912006":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_pledgeOrRepurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_mainChangeObey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_genSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "Hello":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912100":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934007":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2910204":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryRiskMatchLevel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_cybAdd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_merchandiseOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_lfexOpenAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_finaAcceptedServiceTime":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912018":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryExtInstInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_tradingDay":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_push_changePushType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "http":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxpService_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_checkRisks":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryRegisterAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_videoInvalid":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_IdCardpromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_appropriateInfoSave":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_entrustOrderCancel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_bps_queryRepurchaseOffer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sms_sendSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_getSupplyPledgeList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewShareAcctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_pushThs":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ggt_isLegalClient":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_custAgmtCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getXJBAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_login-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_IdCardAuthentication":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_imgReuslt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_openAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_bankSecurityTransOut":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryCustAdequacyInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_submitOpenaccNoMaterialInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_OpenAcc_saveHangUpVideo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_setRetainShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_queryCustSource":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_ApproMatching":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryAssetAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_config_getIp":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_bjhgQualificationCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_queryIPOChosenInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_getTrdCustAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_productPurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_querySecuAcc":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_khpp_delData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cts_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryFundsFlow":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryDeliveryOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_getUserQueueNo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryCustomInfoByType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxpService_zpqk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_searchYmtByCardNo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_saveAcceptedAccountTransferInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryFunds-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_validateQualifiedInvestor":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_securitiesAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_push_queryPushStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934016":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912102":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_pagedQueryMatched-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_unfreeze":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_dubbo_returnStringdubbo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_partnerInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryProductPurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934005":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2930001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cams_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_bankSecurityTransIn-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ggt_submitSurveyAnswers":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_synCustPayAcctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912025":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_placeReservedIPOsOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_trade_queryBankSecurityTrans-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryUserSecuInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_khpp_updateData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_cashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_t_sign":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912028":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewSharePayment":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_checkCashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_querySystemStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_getCustInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryShareProfit":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_uploadImage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_addChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_fundCodeVerification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2933000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_cybCanOpen":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryUserBasicInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_OpenAcc_checkChannelAuth":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_fundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2932522":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912009":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryTrdacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_checkShareholderAccounts":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_push_cancelBind":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryExtInstInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_batch_getTbcStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2930003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_userOccuInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2910212":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_fundAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_CancelIPOsTodayOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_trade_queryShare":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_cybSignResultCallBack":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_chkCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryHisQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_IdCardpromotionTract":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934027":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2930002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_verification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_bankSecurityTransIn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_getProtocolList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_queryAppropriateSurveyRating":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_openQERNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_liftLossAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_banksecurityTransOut":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},
 - "forward_aoi_querySpecialAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryDeliveryOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryBjhgQualification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_batchRiskSurvey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_getRishQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_riskDataUpload":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_batch_runTbcTask":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912101":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_midDataPersistence":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912515":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_IPO_queryIPOChosenInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_boa_queryIPOsOrderInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_trade_querySecuAcct-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_getCustAgmtStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_login":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_relationshipConfirmation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kbss_getAccountByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getAgreementInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cts_zpqk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_queryAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_XjbAdd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_synCuacctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_mainChangeObeyAllInOne":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryCustAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_qtyFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ggt_getSurveyQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getAvailableNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_queryIPOChosenInfoNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_placeReservedOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_kcxp_custBatchAnswer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_findTracctByIdno":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2935022":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_app_search":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_trade_queryIPOCalendar":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_useInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_updateQualifiedInvestor":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_operBoodsBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kbss_synClientInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_test2":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2916108":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_queryIPOsOrderInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_zd_accountCancellation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryExtAccByCustCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2932524":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryUserByTel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getRapidRedeemBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaQuestionnaire":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cts_zpck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getRetainShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_queryPersonalAsset":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_antHangUp":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_operateStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_getCanPledgeShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryFundsFlow-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryUserBasicInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_logonData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_IPOsOrderCancel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_sbtpsboa_modifyIPOsOrderInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trdacct_findTracctByIdno":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_cancleOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kess_idVerify2":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_repurchaseOffer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_queryHisRiskTest":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912020":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryCustCapitalInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_checkSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kess_idVerify":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_queryVideoVerify":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_savaCustomer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934023":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_appropriateSet":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_IDVerifyHessian":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_login":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewShareAcctInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryCustCommonInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912023":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryUserBasicInfoExt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_getOpenaccInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_setCustAdequacyInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryRiskInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_genSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_updateCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_querySecuMessage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaCuacctPwd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_dataModification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_queryStockCodeAppro":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2932514":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_openQualifiedInvestorRight":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kess_idVerify244":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_canOpenQER":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_submitOpenaccInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_pagedQueryMatched":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_banksecurityTransIn":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},
 - "1":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912026":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912004":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_test":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "file_lfex_preFundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2910213":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_verifyAntAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_lu_bindCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewShareAssignInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912010":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912014":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_delChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custRiskBatchAnswer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_managementInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934004":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryIPOCalendar-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_dataCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_ymtApply":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxpService_adjustFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cyb_cybSignResultCallBack":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912103":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "SBTPS-OPF-AIO-WEB-DMZ-WEB-AUTH-APP":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},
 - "forward_zd_accountActivation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_querySecuAcct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custRecordInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912005":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_getPledgeSharesList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912024":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_beneficiaryInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryBeneficiaryInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_appropriateQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_ymtCancellation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2930000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_cashRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_MessageRevealSN":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_listOfStkTrdAcct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_signCashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ocr_readImgText":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_test_aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_queryAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cams_listCuacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findProfession":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_controllerInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryMatched-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_getProtocolByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_preMainChangeObey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_test_testfdfdsf":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findQuestionnaire":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_accountResult":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_getCustBaseInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_sbtpsboa_queryOrderInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_xjb_updateAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custInfoCheckOptn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custInfoManage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912029":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_InformationInquiry":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zhx_idCardAuthentication":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_securitiesAccountCreation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_app_stocksearch":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_openacc_getOcrUserInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_registAccountMaintain":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_searchYmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_incidenceRelation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2933001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_aoi_queryRiskTest":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_signElectPromise":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_qer_signNewAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_resultQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_queryKhppBatchInfoByUser":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_tsp_queryCapital":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_cts_adjustFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_estimateIncome":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_openDelistingStockTradeRight":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ggt_openGGT":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_querySecuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},
 - "forward_sbtpsboa_queryIPOsSetExpDataInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS","desensitizeKeyArray":["PWD","USER_PWD","pwd","AUTH_INFO","REQ_AUTH_INFO","REQ_EXT_ACC_PWD","EXT_ACC_PWD"]},
 - "forward_kcxp_queryControllerInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "file_lfex_fundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_changeCashTreasureStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_verify_verifyByChannel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_submitLicense":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryNewShareAssignInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_custCapitalInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kh_cybAddResultQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912019":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_xjbYieldRate":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934024":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kbss_checkShareholderAccounts":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryQuotation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_idNumberPromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_kcxp_queryCustRecordInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_uploadImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_cancleOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryIPOChosenInfoNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryMaxShareQty-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findOpenAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_getEnumByType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_readImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2933002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zd_searchStkAcctBizInfoToEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryQuotation-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "dddgffd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_test3":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_findRisk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2933003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_historicaIncome":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912013":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_bps_signAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryShare-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_ggt_getStockholderCardList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_zhx_IdCardpromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "file_lfex_qtyFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2910211":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaRisk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_updateChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryUserSecuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_xjb_getAvailable":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_test4":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_queryFundsFlow":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912021":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_soas_savaBatchMessage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2934006":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912032":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_common_searchStkAcctBizInfoToEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_bankSecurityTransOut-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_otc_queryProductProportion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "L2912003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_trade_queryMaxShareQty":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},
 - "forward_account_queryGZTrdacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"}
 - }
 
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 redisSwitchShared = ngx.shared.redisSwitchShared;
 - 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
 - --ngx.log(ngx.CRIT,"name:"..name.."||".."value:"..cjson.encode(value));
 - apiMappingShared:set(name, cjson.encode(value));
 - end
 - else
 - ngx.log(ngx.ERR,"init method,JSON PARSE apiMapping.json error.");
 - end
 - redisSwitchShared:set("redisSwitch",true);
 - 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 httpPostParamReaderByReloadApiMapping()--专门为apiMapping.reloadApiMapping()所用
 - -- read post data
 - --server中使用lua_need_request_body on; 或者在location lua代码块中使用 ngx.req.read_body(),日志中能获取$request_body
 - 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.body is :"..responseBody.body);
 - return responseBody.body
 - end
 - function getRedisClusterCompSign(apiSign)
 - local redis_cluster = require "resty.rediscluster";
 - local red = redis_cluster:new(ngx.shared.redisClusterConfig);
 - --local KEY_NAME = "OPENAPI_NGINX_ROUTE_NODE_LAN";--内网
 - --local KEY_NAME = "OPENAPI_NGINX_ROUTE_NODE_WAN";--外网
 - --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)
 - --ngx.log(ngx.ERR,"KEY_NAME is :"..KEY_NAME)
 - --red:set("forward_sbtpsboa_queryIPOsSecuInfo", "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
 - --red:set(apiSign, "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")
 - --local results, err = red:get("forward_sbtpsboa_queryIPOsSecuInfo")
 - --local results, err = red:get(apiSign)
 - local results, err = red:hget(networkSign,apiSign)--networkSign在init.lua中定义
 - --red:close()
 - --local results, err = red:commit_pipeline()
 - --local cjson = require "cjson"
 - --ngx.log(ngx.ERR,"result is :"..cjson.encode(results))
 - if not results then
 - ngx.log(ngx.ERR,"failed to get apiSign: "..err)
 - return
 - end
 - if type(results) == "userdata" then--redis get nil
 - return nil
 - end
 - --ngx.log(ngx.ERR,"results is :"..results);
 - return results
 - end
 - function apiMapping.setRedisSwitch()
 - local args = ngx.req.get_uri_args()
 - local redisSwitchShared = ngx.shared.redisSwitchShared;
 - local requestArgs = {};
 - for key, value in pairs(args) do
 - if type(value) == "table" then
 - --ngx.log(ngx.ERR,"key:"..key.."value:"..value)
 - ngx.say(key, ": ", table.concat(value, ", "))
 - requestArgs[key] = table.concat(value, ", ")
 - else
 - requestArgs[key] = value
 - --ngx.log(ngx.ERR,"key:"..key.."value:"..value)
 - ngx.say(key, ": ", value)
 - end
 - end
 - --ngx.log(ngx.ERR,"requestArgs:"..cjson.encode(requestArgs))
 - if next(requestArgs) ~= nil then
 - for key, value in pairs(requestArgs) do
 - if key == "flag" then
 - redisSwitchShared:set("redisSwitch",value);
 - end
 - end
 - end
 - end
 - function apiMapping.reloadApiMapping()
 - --local postBody = httpPostParamReader();
 - local postBody = httpPostParamReaderByReloadApiMapping();
 - if postBody then
 - local apiMappingShared = ngx.shared.apiMappingShared
 - local confJson = {};
 - for apiSign, compSign in pairs(postBody) do
 - --ngx.say(table2str(mapping))
 - confJson[apiSign]=compSign;
 - --ngx.log(ngx.CRIT,"name:"..apiSign.."||".."value:"..cjson.encode(compSign));
 - apiMappingShared:set(apiSign,compSign)
 - end
 - ngx.log(ngx.CRIT,"confJson:"..cjson.encode(confJson));
 - 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.."\":"..cjson.encode(value));
 - --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 = {}
 - local head = {}
 - local body = {}
 - 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)) ;
 - if paramName == "requestParam" then
 - paramName = string.match(paramName,"%s*(.-)%s*$");
 - if paramValue then
 - paramValue = string.match(paramValue,"%s*(.-)%s*$");
 - end
 - print("put param :"..paramName.."|"..paramValue)
 - body[paramName] = paramValue;
 - elseif paramName and paramName ~= "requestParam" then
 - paramName = string.match(paramName,"%s*(.-)%s*$");
 - if paramValue then
 - paramValue = string.match(paramValue,"%s*(.-)%s*$");
 - end
 - head[paramName] = paramValue;
 - else
 - return false,nil;
 - end
 - end
 - end
 - nSplitArray["head"] = head;
 - nSplitArray["body"] = body;
 - return true,nSplitArray;
 - end
 - function decodeURI(s)
 - if s ~= nil then
 - return string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
 - else
 - return nil
 - end
 - end
 - --URL decode 转换
 - function escape(s)
 - if s ~= nil then
 - return string.gsub(s, "([^A-Za-z0-9_])", function(c) return string.format("%%%02x", string.byte(c)) end)
 - else
 - return nil
 - end
 - end
 - --16进制转换为字符串
 - function hex2str(hex)
 - local str = "";
 - for i = 1, string.len(hex) do
 - local charcode = tonumber(string.byte(hex, i, i));
 - str = str .. string.format("%02X", charcode);
 - end
 - return str;
 - end
 - function httpPostParamReader()
 - -- read post data
 - --server中使用lua_need_request_body on; 或者在location lua代码块中使用 ngx.req.read_body(),日志中能获取$request_body
 - ngx.req.read_body()
 - local data = ngx.req.get_body_data()
 - if data == nil then
 - printCaptureResult(-10000)
 - --return
 - end
 - data = ngx.unescape_uri(data)
 - --ngx.log(ngx.CRIT,"data:"..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
 - --demo :method=method=placeReservedOrder&openId=MACS&appId=7982088765&format=json&sign=7bb98a054081b48f404b0c5a3786d3d90ae95327&requestParam={"BRANCH":"3089","DIRECTION":"0","DUEDATE":"2017-07-11","F_OP_SRC":"X","HD_ID":"39737FD2-B467-4581-B322-561404F504D5","MAC_ADDR":"","MARKET":"00","ORDER_MODE":"3","PRICE":"0","QTY":"100","SECURITIESNAME":"平安银行","SECU_ACC":"0199171787","SECU_CODE":"000001","SECU_NAME":"","SERVERID":"10.25.175.117","STATE":"","TRD_ID":"0B","TRD_TERMCODE":"13433445656","USER_CODE":"150129599"}×tamp=2017-07-11 18:54:37
 - 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 strSplit(delimeter, str)
 - local find, sub, insert = string.find, string.sub, table.insert
 - local res = {}
 - local start, start_pos, end_pos = 1, 1, 1
 - while true do
 - start_pos, end_pos = find(str, delimeter, start, true)
 - if not start_pos then
 - break
 - end
 - insert(res, sub(str, start, start_pos - 1))
 - start = end_pos + 1
 - end
 - insert(res, sub(str,start))
 - return res
 - end
 - --desensitizeStr 备份,调用在log.lua中
 - function desensitizeStr(source,desensitizeKeyArray)
 - for i=1,#desensitizeKeyArray do
 - local regex = "(%A*)"..desensitizeKeyArray[i].."(%D*)".."(%d+)"
 - local m = string.match(source, regex)
 - if m then
 - --source = string.gsub(source,regex,replaceStr(%5))
 - source = string.gsub(source,regex,"%1"..desensitizeKeyArray[i].."%2".."***")
 - --print("source:"..source)
 - return source
 - --break
 - end
 - end
 - end
 - function apiMapping.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
 - local apiSignArr = strSplit("/",reqUri);
 - if #apiSignArr > 4 then
 - --ngx.log(ngx.ERR,"apiSignArr:"..#apiSignArr.." if apiSignArr.len >4 then not get request_body’s method");
 - apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;
 - else
 - --ngx.say("apiSign:"..apiSign);
 - apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;
 - local head = postBody["head"];
 - if(head ==nil) then
 - printCaptureResult(-1006)
 - end
 - local method = head["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
 - end
 - --ngx.log(ngx.ERR,"apiSign:"..apiSign);
 - --ngx.say("apiSign:"..apiSign);
 - local apiMappingConf = ngx.shared.apiMappingShared
 - --local res = apiMappingConf:get(apiSign)
 - --local res = routeLocation(apiSign)
 - local resTable = {}
 - local res = nil;
 - local redisResultJson = nil;
 - local localApiMappingJson = nil;
 - --local localApiMappingJson = apiMappingConf:get("forward_sbtpsboa_queryIPOsOrderInfo");
 - --local localApiMappingJsonComSign = cjson.decode(localApiMappingJson)["comSign"];
 - --ngx.log(ngx.ERR,"localApiMappingJsonComSign.apiSign is :"..localApiMappingJsonComSign);
 - --("forward_sbtpsboa_queryIPOsOrderInfo")
 - --redisResultJson = getRedisClusterCompSign(apiSign);--返回一个json串
 - local redisSwitch = ngx.shared.redisSwitchShared;
 - local redisSwitchFlag =redisSwitch:get("redisSwitch")
 - if redisSwitchFlag == "true" then
 - local ret,backData = pcall(getRedisClusterCompSign,apiSign);
 - if ret then
 - redisResultJson = backData;
 - --ngx.log(ngx.CRIT,"redisResultJson is :"..redisResultJson);
 - else
 - ngx.log(ngx.ERR,"获取redis缓存数据失败!");
 - end
 - end
 - --ngx.log(ngx.CRIT,"redisResultJson is :"..redisResultJson);
 - --redisResultJson = nil;--测试读取本地
 - if redisResultJson ~= nil then
 - ngx.var.redisResultJson = redisResultJson;
 - --ngx.log(ngx.CRIT,"ngx.var.redisResultJson is :"..ngx.var.redisResultJson);
 - if cjson.decode(redisResultJson) ~= nil then
 - resTable = cjson.decode(redisResultJson)--返回一个json串转为table
 - else
 - ngx.log(ngx.ERR,"redis 数据格式错误! ", err)
 - return
 - end
 - else--redis返回为空,做兜底操作(apiMapping.json)
 - --local openId = postBody["openId"];
 - --if openId then
 - -- apiSign = openId.."_"..apiSign.."_" .. string.match(openId,"%s*(.-)%s*$");
 - --end
 - localApiMappingJson = apiMappingConf:get(apiSign)
 - --ngx.log(ngx.ERR,"localApiMappingJson is :"..localApiMappingJson);
 - if localApiMappingJson == nil then
 - ngx.log(ngx.ERR,"undefined api sign is :"..apiSign);
 - printCaptureResult(-10201)
 - end
 - ngx.var.redisResultJson = localApiMappingJson;
 - if cjson.decode(localApiMappingJson) ~= nil then--返回一个json串转为table
 - local resTableTemp = cjson.decode(localApiMappingJson);
 - if type(resTableTemp)=="string" then
 - resTable = cjson.decode(resTableTemp)
 - end
 - if type(resTableTemp)=="table" then
 - resTable = resTableTemp
 - end
 - else
 - ngx.log(ngx.ERR,"this localApiMappingJson api sign has not set", err)
 - return
 - end
 - end
 - if next(resTable) ~= nil then
 - --ngx.log(ngx.INFO,"resTable.comSign is :"..resTable["comSign"])
 - res = resTable["comSign"]
 - end
 - --ngx.log(ngx.ERR,"apiSign is :"..apiSign);
 - ngx.var.apiSign = apiSign;
 - if res and res ~= nil 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
 - end
 - return apiMapping;
 
log.lua
- function desensitizeStr(source,desensitizeKeyArray)--string,table
 - if source == nil or source == "" then
 - return nil
 - end
 - if desensitizeKeyArray == nil or desensitizeKeyArray == "" then
 - return source
 - end
 - for i=1,#desensitizeKeyArray do
 - local regex = "(%A*)"..desensitizeKeyArray[i].."(%D*)".."(%d+)"
 - local m = string.match(source, regex)
 - if m then
 - --source = string.gsub(source,regex,replaceStr(%5))
 - source = string.gsub(source,regex,"%1"..desensitizeKeyArray[i].."%2".."***")
 - --print("source:"..source)
 - return source
 - --break
 - end
 - end
 - return source--执行到这里表示没有一次做string.gsub(没有一次做正则替换)
 - end
 - --ngx.log(ngx.CRIT,"request_body is :"..ngx.var.request_body)
 - --local source = "pwd\":\"12333123ad\"}\"apwd\":\"1233sd3123\"pwd:123321,adpwd1233fgfsdgs"
 - 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
 - -- 删除table中的元素
 - function removeElementByKey(sourceJson,key)
 - if sourceJson == nil then
 - return nil
 - end
 - if key == nil then
 - return sourceJson
 - end
 - local tempTable = nil;
 - local ret,backData=pcall(parseJson,sourceJson);
 - if ret then
 - tempTable = backData;
 - else
 - --处理请求和响应信息中的超大字段request_body&resp_body
 - --ngx.log(ngx.ERR,"{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}");
 - return "{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}"
 - end
 - if tempTable == nil then
 - return nil
 - end
 - --新建一个临时的table
 - local tmp ={}
 - --把每个key做一个下标,保存到临时的table中,转换成{1=a,2=c,3=b}
 - --组成一个有顺序的table,才能在while循环准备时使用#table
 - for i in pairs(tempTable) do
 - table.insert(tmp,i)
 - end
 - local newTbl = {}
 - --使用while循环剔除不需要的元素
 - local i = 1
 - while i <= #tmp do
 - local val = tmp [i]
 - if val == key then
 - --如果是需要剔除则remove
 - table.remove(tmp,i)
 - else
 - --如果不是剔除,放入新的tabl中
 - newTbl[val] = tempTable[val]
 - i = i + 1
 - end
 - end
 - return cjson.encode(newTbl)
 - --return newTbl
 - end
 - function replaceJson(jsonString,replaceKey,replaceValue)
 - if jsonString == nil or jsonString == "" then
 - return nil
 - end
 - if replaceKey == nil or replaceValue == nil then
 - return jsonString
 - end
 - local tempTable = nil;
 - local ret,backData=pcall(parseJson,jsonString);
 - if ret then
 - tempTable = backData;
 - else
 - ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");
 - end
 - if tempTable == nil then
 - return nil
 - end
 - if tempTable[replaceKey] == nil then
 - return jsonString
 - end
 - --处理请求和响应信息中的超大字段request_body&resp_body
 - if ngx.var.apiSign == "forward_soas_uploadIdImg" and replaceKey == "request_body" then
 - tempTable[replaceKey] = "{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}"
 - else
 - tempTable[replaceKey] = replaceValue
 - end
 - return cjson.encode(tempTable)
 - --return jsonString
 - end
 - function getJsonValueToTable(jsonString,stringKey)--返回table
 - if jsonString == nil or jsonString == "" then
 - return nil
 - end
 - if stringKey == nil then
 - return jsonString
 - end
 - local tempTable = nil;
 - local ret,backData=pcall(parseJson,jsonString);
 - if ret then
 - tempTable = backData;
 - else
 - --printCaptureResult(-1006)
 - --ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");
 - ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");
 - return nil
 - end
 - if type(tempTable)=="string" then
 - local ret,backData=pcall(parseJson,tempTable);
 - if ret then
 - tempTable = backData;
 - else
 - ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");
 - return nil
 - end
 - end
 - if tempTable == nil then
 - return nil
 - end
 - if tempTable[stringKey] == nil then
 - return nil
 - end
 - if type(tempTable[stringKey]) =="string" then
 - local ret,backData=pcall(parseJson,tempTable[stringKey]);
 - if ret then
 - return backData;
 - else
 - ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");
 - return nil
 - end
 - end
 - if type(tempTable[stringKey]) =="table" then
 - return tempTable[stringKey]
 - end
 - end
 - if(ngx.var.uri ~= "/metrics") then
 - local host = ngx.var.host:gsub("^www.", "")
 - local upstream_addr = ngx.var.upstream_addr
 - if(upstream_addr == nil or upstream_addr == "") then
 - upstream_addr = "localhost"
 - end
 - metric_requests:inc(1, {host, upstream_addr, ngx.var.status})
 - metric_latency:observe(ngx.now() - ngx.req.start_time(), {upstream_addr})
 - metric_bytes:observe(tonumber(ngx.var.bytes_sent)/1024,{upstream_addr})
 - end
 - local source = ngx.unescape_uri(ngx.var.request_body)--获取到request_body的字符串
 - --local responseSrc = ngx.var.resp_body--获取到resp_body的字符串
 - local responseDesc = removeElementByKey(ngx.var.resp_body,"resBody")
 - --ngx.log(ngx.CRIT,"responseDesc is :"..responseDesc)
 - --ngx.log(ngx.CRIT,"redisResultJson is :"..ngx.var.redisResultJson)
 - local desensitizeKeyArray = getJsonValueToTable(ngx.var.redisResultJson,"desensitizeKeyArray")--获取到desensitizeKeyArray的table
 - source = desensitizeStr(source,desensitizeKeyArray)--替换后的request_body字符串
 - --ngx.log(ngx.CRIT,"source is :"..source)
 - --ngx.log(ngx.CRIT,"before replace resp_map is :"..ngx.var.resp_map)
 - ngx.var.resp_map = replaceJson(ngx.var.resp_map,"request_body",source)
 - ngx.var.resp_map = replaceJson(ngx.var.resp_map,"resp_body",responseDesc)
 - --ngx.log(ngx.CRIT,"after replace resp_map is :"..ngx.var.resp_map)
 - ngx.log(ngx.CRIT,"resp_map is :"..ngx.var.resp_map)
 
prometheus.lua
- -- vim: ts=2:sw=2:sts=2:expandtab
 - --
 - -- This module uses a single dictionary shared between Nginx workers to keep
 - -- all metrics. Each counter is stored as a separate entry in that dictionary,
 - -- which allows us to increment them using built-in `incr` method.
 - --
 - -- Prometheus requires that (a) all samples for a given metric are presented
 - -- as one uninterrupted group, and (b) buckets of a histogram appear in
 - -- increasing numerical order. We satisfy that by carefully constructing full
 - -- metric names (i.e. metric name along with all labels) so that they meet
 - -- those requirements while being sorted alphabetically. In particular:
 - --
 - -- * all labels for a given metric are presented in reproducible order (the one
 - -- used when labels were declared). "le" label for histogram metrics always
 - -- goes last;
 - -- * bucket boundaries (which are exposed as values of the "le" label) are
 - -- presented as floating point numbers with leading and trailing zeroes.
 - -- Number of of zeroes is determined for each bucketer automatically based on
 - -- bucket boundaries;
 - -- * internally "+Inf" bucket is stored as "Inf" (to make it appear after
 - -- all numeric buckets), and gets replaced by "+Inf" just before we
 - -- expose the metrics.
 - --
 - -- For example, if you define your bucket boundaries as {0.00005, 10, 1000}
 - -- then we will keep the following samples for a metric `m1` with label
 - -- `site` set to `site1`:
 - --
 - -- m1_bucket{site="site1",le="0000.00005"}
 - -- m1_bucket{site="site1",le="0010.00000"}
 - -- m1_bucket{site="site1",le="1000.00000"}
 - -- m1_bucket{site="site1",le="Inf"}
 - -- m1_count{site="site1"}
 - -- m1_sum{site="site1"}
 - --
 - -- "Inf" will be replaced by "+Inf" while publishing metrics.
 - --
 - -- You can find the latest version and documentation at
 - -- https://github.com/knyar/nginx-lua-prometheus
 - -- Released under MIT license.
 - -- Default set of latency buckets, 5ms to 10s:
 - local DEFAULT_BUCKETS = {0.005, 0.01, 0.02, 0.03, 0.05, 0.075, 0.1, 0.2, 0.3,
 - 0.4, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 10}
 - -- Metric is a "parent class" for all metrics.
 - local Metric = {}
 - function Metric:new(o)
 - o = o or {}
 - setmetatable(o, self)
 - self.__index = self
 - return o
 - end
 - -- Checks that the right number of labels values have been passed.
 - --
 - -- Args:
 - -- label_values: an array of label values.
 - --
 - -- Returns:
 - -- an error message or nil
 - function Metric:check_label_values(label_values)
 - if self.label_names == nil and label_values == nil then
 - return
 - elseif self.label_names == nil and label_values ~= nil then
 - return "Expected no labels for " .. self.name .. ", got " .. #label_values
 - elseif label_values == nil and self.label_names ~= nil then
 - return "Expected " .. #self.label_names .. " labels for " ..
 - self.name .. ", got none"
 - elseif #self.label_names ~= #label_values then
 - return "Wrong number of labels for " .. self.name .. ". Expected " ..
 - #self.label_names .. ", got " .. #label_values
 - else
 - for i, k in ipairs(self.label_names) do
 - if label_values[i] == nil then
 - return "Unexpected nil value for label " .. k .. " of " .. self.name
 - end
 - end
 - end
 - end
 - local Counter = Metric:new()
 - -- Increase a given counter by `value`
 - --
 - -- Args:
 - -- value: (number) a value to add to the counter. Defaults to 1 if skipped.
 - -- label_values: an array of label values. Can be nil (i.e. not defined) for
 - -- metrics that have no labels.
 - function Counter:inc(value, label_values)
 - local err = self:check_label_values(label_values)
 - if err ~= nil then
 - self.prometheus:log_error(err)
 - return
 - end
 - self.prometheus:inc(self.name, self.label_names, label_values, value or 1)
 - end
 - local Gauge = Metric:new()
 - -- Set a given gauge to `value`
 - --
 - -- Args:
 - -- value: (number) a value to set the gauge to. Should be defined.
 - -- label_values: an array of label values. Can be nil (i.e. not defined) for
 - -- metrics that have no labels.
 - function Gauge:set(value, label_values)
 - if value == nil then
 - self.prometheus:log_error("No value passed for " .. self.name)
 - return
 - end
 - local err = self:check_label_values(label_values)
 - if err ~= nil then
 - self.prometheus:log_error(err)
 - return
 - end
 - self.prometheus:set(self.name, self.label_names, label_values, value)
 - end
 - local Histogram = Metric:new()
 - -- Record a given value in a histogram.
 - --
 - -- Args:
 - -- value: (number) a value to record. Should be defined.
 - -- label_values: an array of label values. Can be nil (i.e. not defined) for
 - -- metrics that have no labels.
 - function Histogram:observe(value, label_values)
 - if value == nil then
 - self.prometheus:log_error("No value passed for " .. self.name)
 - return
 - end
 - local err = self:check_label_values(label_values)
 - if err ~= nil then
 - self.prometheus:log_error(err)
 - return
 - end
 - self.prometheus:histogram_observe(self.name, self.label_names, label_values, value)
 - end
 - local Prometheus = {}
 - Prometheus.__index = Prometheus
 - Prometheus.initialized = false
 - -- Generate full metric name that includes all labels.
 - --
 - -- Args:
 - -- name: string
 - -- label_names: (array) a list of label keys.
 - -- label_values: (array) a list of label values.
 - -- Returns:
 - -- (string) full metric name.
 - local function full_metric_name(name, label_names, label_values)
 - if not label_names then
 - return name
 - end
 - local label_parts = {}
 - for idx, key in ipairs(label_names) do
 - local label_value = (string.format("%s", label_values[idx])
 - :gsub("[^\032-\126]", "") -- strip non-printable characters
 - :gsub("\\", "\\\\")
 - :gsub('"', '\\"'))
 - table.insert(label_parts, key .. '="' .. label_value .. '"')
 - end
 - return name .. "{" .. table.concat(label_parts, ",") .. "}"
 - end
 - -- Construct bucket format for a list of buckets.
 - --
 - -- This receives a list of buckets and returns a sprintf template that should
 - -- be used for bucket boundaries to make them come in increasing order when
 - -- sorted alphabetically.
 - --
 - -- To re-phrase, this is where we detect how many leading and trailing zeros we
 - -- need.
 - --
 - -- Args:
 - -- buckets: a list of buckets
 - --
 - -- Returns:
 - -- (string) a sprintf template.
 - local function construct_bucket_format(buckets)
 - local max_order = 1
 - local max_precision = 1
 - for _, bucket in ipairs(buckets) do
 - assert(type(bucket) == "number", "bucket boundaries should be numeric")
 - -- floating point number with all trailing zeros removed
 - local as_string = string.format("%f", bucket):gsub("0*$", "")
 - local dot_idx = as_string:find(".", 1, true)
 - max_order = math.max(max_order, dot_idx - 1)
 - max_precision = math.max(max_precision, as_string:len() - dot_idx)
 - end
 - return "%0" .. (max_order + max_precision + 1) .. "." .. max_precision .. "f"
 - end
 - -- Extract short metric name from the full one.
 - --
 - -- Args:
 - -- full_name: (string) full metric name that can include labels.
 - --
 - -- Returns:
 - -- (string) short metric name with no labels. For a `*_bucket` metric of
 - -- histogram the _bucket suffix will be removed.
 - local function short_metric_name(full_name)
 - local labels_start, _ = full_name:find("{")
 - if not labels_start then
 - -- no labels
 - return full_name
 - end
 - local suffix_idx, _ = full_name:find("_bucket{")
 - if suffix_idx and full_name:find("le=") then
 - -- this is a histogram metric
 - return full_name:sub(1, suffix_idx - 1)
 - end
 - -- this is not a histogram metric
 - return full_name:sub(1, labels_start - 1)
 - end
 - -- Makes a shallow copy of a table
 - local function copy_table(table)
 - local new = {}
 - if table ~= nil then
 - for k, v in ipairs(table) do
 - new[k] = v
 - end
 - end
 - return new
 - end
 - -- Check metric name and label names for correctness.
 - --
 - -- Regular expressions to validate metric and label names are
 - -- documented in https://prometheus.io/docs/concepts/data_model/
 - --
 - -- Args:
 - -- metric_name: (string) metric name.
 - -- label_names: label names (array of strings).
 - --
 - -- Returns:
 - -- Either an error string, or nil of no errors were found.
 - local function check_metric_and_label_names(metric_name, label_names)
 - if not metric_name:match("^[a-zA-Z_:][a-zA-Z0-9_:]*$") then
 - return "Metric name '" .. metric_name ..
 - "' contains invalid characters"
 - end
 - for _, label_name in ipairs(label_names or {}) do
 - if label_name == "le" then
 - return "Invalid label name 'le' in " .. metric_name
 - end
 - if not label_name:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
 - return "Metric '" .. metric_name .. "' label name '" .. label_name ..
 - "' contains invalid characters"
 - end
 - end
 - end
 - -- Initialize the module.
 - --
 - -- This should be called once from the `init_by_lua` section in nginx
 - -- configuration.
 - --
 - -- Args:
 - -- dict_name: (string) name of the nginx shared dictionary which will be
 - -- used to store all metrics
 - -- prefix: (optional string) if supplied, prefix is added to all
 - -- metric names on output
 - --
 - -- Returns:
 - -- an object that should be used to register metrics.
 - function Prometheus.init(dict_name, prefix)
 - local self = setmetatable({}, Prometheus)
 - self.dict = ngx.shared[dict_name or "prometheus_metrics"]
 - self.help = {}
 - if prefix then
 - self.prefix = prefix
 - else
 - self.prefix = ''
 - end
 - self.type = {}
 - self.registered = {}
 - self.buckets = {}
 - self.bucket_format = {}
 - self.initialized = true
 - self:counter("nginx_metric_errors_total",
 - "Number of nginx-lua-prometheus errors")
 - self.dict:set("nginx_metric_errors_total", 0)
 - return self
 - end
 - function Prometheus:log_error(...)
 - ngx.log(ngx.ERR, ...)
 - self.dict:incr("nginx_metric_errors_total", 1)
 - end
 - function Prometheus:log_error_kv(key, value, err)
 - self:log_error(
 - "Error while setting '", key, "' to '", value, "': '", err, "'")
 - end
 - -- Register a counter.
 - --
 - -- Args:
 - -- name: (string) name of the metric. Required.
 - -- description: (string) description of the metric. Will be used for the HELP
 - -- comment on the metrics page. Optional.
 - -- label_names: array of strings, defining a list of metrics. Optional.
 - --
 - -- Returns:
 - -- a Counter object.
 - function Prometheus:counter(name, description, label_names)
 - if not self.initialized then
 - ngx.log(ngx.ERR, "Prometheus module has not been initialized")
 - return
 - end
 - local err = check_metric_and_label_names(name, label_names)
 - if err ~= nil then
 - self:log_error(err)
 - return
 - end
 - if self.registered[name] then
 - self:log_error("Duplicate metric " .. name)
 - return
 - end
 - self.registered[name] = true
 - self.help[name] = description
 - self.type[name] = "counter"
 - return Counter:new{name=name, label_names=label_names, prometheus=self}
 - end
 - -- Register a gauge.
 - --
 - -- Args:
 - -- name: (string) name of the metric. Required.
 - -- description: (string) description of the metric. Will be used for the HELP
 - -- comment on the metrics page. Optional.
 - -- label_names: array of strings, defining a list of metrics. Optional.
 - --
 - -- Returns:
 - -- a Gauge object.
 - function Prometheus:gauge(name, description, label_names)
 - if not self.initialized then
 - ngx.log(ngx.ERR, "Prometheus module has not been initialized")
 - return
 - end
 - local err = check_metric_and_label_names(name, label_names)
 - if err ~= nil then
 - self:log_error(err)
 - return
 - end
 - if self.registered[name] then
 - self:log_error("Duplicate metric " .. name)
 - return
 - end
 - self.registered[name] = true
 - self.help[name] = description
 - self.type[name] = "gauge"
 - return Gauge:new{name=name, label_names=label_names, prometheus=self}
 - end
 - -- Register a histogram.
 - --
 - -- Args:
 - -- name: (string) name of the metric. Required.
 - -- description: (string) description of the metric. Will be used for the HELP
 - -- comment on the metrics page. Optional.
 - -- label_names: array of strings, defining a list of metrics. Optional.
 - -- buckets: array if numbers, defining bucket boundaries. Optional.
 - --
 - -- Returns:
 - -- a Histogram object.
 - function Prometheus:histogram(name, description, label_names, buckets)
 - if not self.initialized then
 - ngx.log(ngx.ERR, "Prometheus module has not been initialized")
 - return
 - end
 - local err = check_metric_and_label_names(name, label_names)
 - if err ~= nil then
 - self:log_error(err)
 - return
 - end
 - for _, suffix in ipairs({"", "_bucket", "_count", "_sum"}) do
 - if self.registered[name .. suffix] then
 - self:log_error("Duplicate metric " .. name .. suffix)
 - return
 - end
 - self.registered[name .. suffix] = true
 - end
 - self.help[name] = description
 - self.type[name] = "histogram"
 - self.buckets[name] = buckets or DEFAULT_BUCKETS
 - self.bucket_format[name] = construct_bucket_format(self.buckets[name])
 - return Histogram:new{name=name, label_names=label_names, prometheus=self}
 - end
 - -- Set a given dictionary key.
 - -- This overwrites existing values, so it should only be used when initializing
 - -- metrics or when explicitely overwriting the previous value of a metric.
 - function Prometheus:set_key(key, value)
 - local ok, err = self.dict:safe_set(key, value)
 - if not ok then
 - self:log_error_kv(key, value, err)
 - end
 - end
 - -- Increment a given counter by `value`.
 - --
 - -- Args:
 - -- name: (string) short metric name without any labels.
 - -- label_names: (array) a list of label keys.
 - -- label_values: (array) a list of label values.
 - -- value: (number) value to add. Optional, defaults to 1.
 - function Prometheus:inc(name, label_names, label_values, value)
 - local key = full_metric_name(name, label_names, label_values)
 - if value == nil then value = 1 end
 - if value < 0 then
 - self:log_error_kv(key, value, "Value should not be negative")
 - return
 - end
 - local newval, err = self.dict:incr(key, value)
 - if newval then
 - return
 - end
 - -- Yes, this looks like a race, so I guess we might under-report some values
 - -- when multiple workers simultaneously try to create the same metric.
 - -- Hopefully this does not happen too often (shared dictionary does not get
 - -- reset during configuation reload).
 - if err == "not found" then
 - self:set_key(key, value)
 - return
 - end
 - -- Unexpected error
 - self:log_error_kv(key, value, err)
 - end
 - -- Set the current value of a gauge to `value`
 - --
 - -- Args:
 - -- name: (string) short metric name without any labels.
 - -- label_names: (array) a list of label keys.
 - -- label_values: (array) a list of label values.
 - -- value: (number) the new value for the gauge.
 - function Prometheus:set(name, label_names, label_values, value)
 - local key = full_metric_name(name, label_names, label_values)
 - self:set_key(key, value)
 - end
 - -- Record a given value into a histogram metric.
 - --
 - -- Args:
 - -- name: (string) short metric name without any labels.
 - -- label_names: (array) a list of label keys.
 - -- label_values: (array) a list of label values.
 - -- value: (number) value to observe.
 - function Prometheus:histogram_observe(name, label_names, label_values, value)
 - self:inc(name .. "_count", label_names, label_values, 1)
 - self:inc(name .. "_sum", label_names, label_values, value)
 - -- we are going to mutate arrays of label names and values, so create a copy.
 - local l_names = copy_table(label_names)
 - local l_values = copy_table(label_values)
 - -- Last bucket. Note, that the label value is "Inf" rather than "+Inf"
 - -- required by Prometheus. This is necessary for this bucket to be the last
 - -- one when all metrics are lexicographically sorted. "Inf" will get replaced
 - -- by "+Inf" in Prometheus:collect().
 - table.insert(l_names, "le")
 - table.insert(l_values, "Inf")
 - self:inc(name .. "_bucket", l_names, l_values, 1)
 - local label_count = #l_names
 - for _, bucket in ipairs(self.buckets[name]) do
 - if value <= bucket then
 - -- last label is now "le"
 - l_values[label_count] = self.bucket_format[name]:format(bucket)
 - self:inc(name .. "_bucket", l_names, l_values, 1)
 - end
 - end
 - end
 - -- Present all metrics in a text format compatible with Prometheus.
 - --
 - -- This function should be used to expose the metrics on a separate HTTP page.
 - -- It will get the metrics from the dictionary, sort them, and expose them
 - -- aling with TYPE and HELP comments.
 - function Prometheus:collect()
 - ngx.header.content_type = "text/plain"
 - if not self.initialized then
 - ngx.log(ngx.ERR, "Prometheus module has not been initialized")
 - return
 - end
 - local keys = self.dict:get_keys(0)
 - -- Prometheus server expects buckets of a histogram to appear in increasing
 - -- numerical order of their label values.
 - table.sort(keys)
 - local seen_metrics = {}
 - for _, key in ipairs(keys) do
 - local value, err = self.dict:get(key)
 - if value then
 - local short_name = short_metric_name(key)
 - if not seen_metrics[short_name] then
 - if self.help[short_name] then
 - ngx.say("# HELP " .. self.prefix .. short_name .. " " .. self.help[short_name])
 - end
 - if self.type[short_name] then
 - ngx.say("# TYPE " .. self.prefix .. short_name .. " " .. self.type[short_name])
 - end
 - seen_metrics[short_name] = true
 - end
 - -- Replace "Inf" with "+Inf" in each metric's last bucket 'le' label.
 - ngx.say(self.prefix .. key:gsub('le="Inf"', 'le="+Inf"'), " ", value)
 - else
 - self:log_error("Error getting '", key, "': ", err)
 - end
 - end
 - end
 - return Prometheus
 
request.lua
- local resp_body = string.sub(ngx.arg[1], 1, 1000)
 - ngx.ctx.buffered = (ngx.ctx.buffered or"") .. resp_body
 - if ngx.arg[2] then
 - ngx.var.resp_body = ngx.ctx.buffered
 - local map = {}
 - map["logTraceId"] = ngx.var.request_id;
 - map["remote_addr"] = ngx.var.remote_addr;
 - map["remote_user"] = ngx.var.remote_user;
 - map["time_local"] = ngx.unescape_uri(ngx.var.time_local);
 - map["request_method"] = ngx.var.request_method;
 - map["apiSign"] = ngx.var.apiSign;
 - map["comp_sign"] = ngx.var.comp_sign;
 - map["request"] = ngx.unescape_uri(ngx.var.request);
 - map["status"] = ngx.var.status;
 - map["body_bytes_sent"] = ngx.var.body_bytes_sent;
 - map["http_referer"] = ngx.var.http_referer;
 - map["http_user_agent"] = ngx.var.http_user_agent;
 - map["http_x_forwarded_for"] = ngx.var.http_x_forwarded_for;
 - map["request_body"] = ngx.unescape_uri(ngx.var.request_body);
 - map["resp_body"] = ngx.unescape_uri(ngx.var.resp_body);
 - map["upstream_addr"] = ngx.var.upstream_addr;
 - map["bytes_sent"] = ngx.var.bytes_sent;
 - map["request_length"] = ngx.var.request_length;
 - map["upstream_response_time"] = ngx.var.upstream_response_time;
 - map["request_time"] = ngx.var.request_time;
 - ngx.var.resp_map = cjson.encode(map);
 - end
 
rediscluster.lua
- local ffi = require 'ffi'
 - local ffi_new = ffi.new
 - local C = ffi.C
 - local crc32 = ngx.crc32_short
 - local setmetatable = setmetatable
 - local floor = math.floor
 - local pairs = pairs
 - local tostring = tostring
 - local tonumber = tonumber
 - ffi.cdef[[
 - int lua_redis_crc16(char *key, int keylen);
 - ]]
 - local ok, new_tab = pcall(require, "table.new")
 - if not ok or type(new_tab) ~= "function" then
 - new_tab = function (narr, nrec) return {} end
 - end
 - --
 - -- Find shared object file package.cpath, obviating the need of setting
 - -- LD_LIBRARY_PATH
 - -- Or we should add a little patch for ffi.load ?
 - --
 - local function load_shared_lib(so_name)
 - local string_gmatch = string.gmatch
 - local string_match = string.match
 - local io_open = io.open
 - local io_close = io.close
 - local cpath = package.cpath
 - for k, _ in string_gmatch(cpath, "[^;]+") do
 - local fpath = string_match(k, "(.*/)")
 - fpath = fpath .. so_name
 - -- Don't get me wrong, the only way to know if a file exist is trying
 - -- to open it.
 - local f = io_open(fpath)
 - if f ~= nil then
 - io_close(f)
 - return ffi.load(fpath)
 - end
 - end
 - end
 - local _M = {}
 - local mt = { __index = _M }
 - local clib = load_shared_lib("libredis_slot.so")
 - if not clib then
 - error("can not load libredis_slot.so")
 - end
 - local function redis_slot(str)
 - return clib.lua_redis_crc16(ffi.cast("char *", str), #str)
 - end
 - local function ip_string(ip)
 - if ip:match(":") then
 - return "[" .. ip .. "]"
 - end
 - return ip
 - end
 - local redis = require "resty.redis"
 - redis.add_commands("cluster")
 - local commands = {
 - "append", --[["auth",]] --[["bgrewriteaof",]]
 - --[["bgsave",]] --[["blpop",]] --[["brpop",]]
 - --[["brpoplpush",]] --[["config", ]] --[["dbsize",]]
 - --[["debug", ]] "decr", "decrby",
 - --[["del",]] --[["discard", "echo",]]
 - --[["eval",]] "exec", "exists",
 - --[["expire", "expireat", "flushall",
 - "flushdb",]] "get", "getbit",
 - "getrange", "getset", "hdel",
 - "hexists", "hget", "hgetall",
 - "hincrby", "hkeys", "hlen",
 - "hmget", "hmset", "hset",
 - "hsetnx", "hvals", "incr",
 - "incrby", --[["info",]] --[["keys",]]
 - --[["lastsave", ]] "lindex", "linsert",
 - "llen", "lpop", "lpush",
 - "lpushx", "lrange", "lrem",
 - "lset", "ltrim", "mget",
 - "monitor", --[["move",]] "mset",
 - "msetnx", --[[["multi",]] --[["object",]]
 - --[["persist",]] --[["ping",]] --[["psubscribe",]]
 - --[[ "publish", "punsubscribe", "quit",]]
 - --[["randomkey", "rename", "renamenx",]]
 - "rpop", --[["rpoplpush",]] "rpush",
 - "rpushx", "sadd", --[["save",]]
 - "scard", --[["script",]]
 - --[["sdiff", "sdiffstore",]]
 - --[["select",]] "set", "setbit",
 - "setex", "setnx", "setrange",
 - --[["shutdown", "sinter", "sinterstore",
 - "sismember", "slaveof", "slowlog",]]
 - "smembers", "smove", "sort",
 - "spop", "srandmember", "srem",
 - "strlen", --[["subscribe",]] "sunion",
 - "sunionstore", --[["sync",]] "ttl",
 - "type", --[["unsubscribe",]] --[["unwatch",
 - "watch",]] "zadd", "zcard",
 - "zcount", "zincrby", "zinterstore",
 - "zrange", "zrangebyscore", "zrank",
 - "zrem", "zremrangebyrank", "zremrangebyscore",
 - "zrevrange", "zrevrangebyscore", "zrevrank",
 - "zscore", --[["zunionstore", "evalsha"]]
 - }
 - local _M = {}
 - local mt = { __index = _M }
 - local slot_cache = {}
 - --local slot_state = {}
 - --local WAIT = 0
 - --local FIN = 1
 - function _M.fetch_slots(self)
 - local serv_list = self.config.serv_list
 - local red = redis:new()
 - for i=1,#serv_list do
 - local ip = serv_list[i].ip
 - local port = serv_list[i].port
 - local ok, err = red:connect(ip_string(ip), port)
 - if ok then
 - local slot_info, err = red:cluster("slots")
 - if slot_info then
 - local slots = {}
 - for i=1,#slot_info do
 - local item = slot_info[i]
 - for slot = item[1],item[2] do
 - local list = {serv_list={}, cur = 1}
 - for j = 3,#item do
 - list.serv_list[#list.serv_list + 1] = {ip = item[j][1], port = item[j][2]}
 - slots[slot] = list
 - end
 - end
 - end
 - slot_cache[self.config.name] = slots
 - --self.slots = slots
 - --debug_log("fetch_slots", self)
 - end
 - end
 - end
 - end
 - function _M.init_slots(self)
 - if slot_cache[self.config.name] then
 - return
 - end
 - self:fetch_slots()
 - end
 - function _M.new(self, config)
 - local inst = {}
 - inst.config = config
 - inst = setmetatable(inst, mt)
 - inst:init_slots()
 - return inst
 - end
 - function _M.close(self)
 - end
 - local function next_index(cur, size)
 - cur = cur + 1
 - if cur > size then
 - cur = 1
 - end
 - return cur
 - end
 - local MAGIC_TRY = 3
 - local DEFUALT_KEEPALIVE_TIMEOUT = 1000
 - local DEFAULT_KEEPALIVE_CONS = 200
 - local function _do_cmd(self, cmd, key, ...)
 - if self._reqs then
 - local args = {...}
 - local t = {cmd = cmd, key=key, args=args}
 - table.insert(self._reqs, t)
 - return
 - end
 - local config = self.config
 - key = tostring(key)
 - local slot = redis_slot(key)
 - for k=1, MAGIC_TRY do
 - local slots = slot_cache[self.config.name]
 - local serv_list = slots[slot].serv_list
 - local index =slots[slot].cur
 - for i=1,#serv_list do
 - local ip = serv_list[index].ip
 - local port = serv_list[index].port
 - local redis_client = redis:new()
 - local ok, err = redis_client:connect(ip_string(ip), port)
 - if ok then
 - slots[slot].cur = index
 - local res, err = redis_client[cmd](redis_client, key, ...)
 - redis_client:set_keepalive(config.keepalive_timeout or DEFUALT_KEEPALIVE_TIMEOUT,
 - config.keepalove_cons or DEFAULT_KEEPALIVE_CONS)
 - if err and string.sub(err, 1, 5) == "MOVED" then
 - self:fetch_slots()
 - break
 - end
 - return res, err
 - else
 - index = next_index(index, #serv_list)
 - end
 - end
 - end
 - return nil, "oops! please contact cuiweixie"
 - end
 - for i = 1, #commands do
 - local cmd = commands[i]
 - _M[cmd] =
 - function (self, ...)
 - return _do_cmd(self, cmd, ...)
 - end
 - end
 - function _M.init_pipeline(self)
 - self._reqs = {}
 - end
 - local INTIT = 0
 - local FIND = 1
 - local FIN = 2
 - function _M.commit_pipeline(self)
 - if not self._reqs or #self._reqs == 0 then return end
 - local reqs = self._reqs
 - self._reqs = nil
 - local config = self.config
 - local slots = slot_cache[config.name]
 - local map_ret = {}
 - local map = {}
 - for i=1,#reqs do
 - reqs[i].origin_index = i
 - local key = reqs[i].key
 - local slot = redis_slot(tostring(key))
 - local slot_item = slots[slot]
 - local ip = slot_item.serv_list[slot_item.cur].ip
 - local port = slot_item.serv_list[slot_item.cur].port
 - local inst_key = ip..tostring(port)
 - if not map[inst_key] then
 - map[inst_key] = {ip=ip,port=port,reqs={}}
 - map_ret[inst_key] = {}
 - end
 - local ins_req = map[inst_key].reqs
 - ins_req[#ins_req+1] = reqs[i]
 - end
 - for k, v in pairs(map) do
 - local ip = v.ip
 - local port = v.port
 - local ins_reqs = v.reqs
 - local ins = redis:new()
 - local ok, err = ins:connect(ip_string(ip), port)
 - if ok then
 - ins:init_pipeline()
 - for i=1,#ins_reqs do
 - local req = ins_reqs[i]
 - if #req.args > 0 then
 - ins[req.cmd](ins, req.key, unpack(req.args))
 - else
 - ins[req.cmd](ins, req.key)
 - end
 - end
 - local res, err = ins:commit_pipeline()
 - ins:set_keepalive(config.keepalive_timeout or DEFUALT_KEEPALIVE_TIMEOUT,
 - config.keepalove_cons or DEFAULT_KEEPALIVE_CONS)
 - if err then
 - return nil, err.." return from "..tostring(ip)..":"..tostring(port)
 - end
 - map_ret[k] = res
 - else
 - return nil, "commit failed while connecting to "..tostring(ip)..":"..tostring(port)
 - end
 - end
 - local ret = {}
 - for k,v in pairs(map_ret) do
 - local ins_reqs = map[k].reqs
 - local res = v
 - for i=1,#ins_reqs do
 - ret[ins_reqs[i].origin_index] =res[i]
 - end
 - end
 - return ret
 - end
 - function _M.cancel_pipeline(self)
 - self._reqs = nil
 - end
 - return _M
 
redis.lua
- -- Copyright (C) Yichun Zhang (agentzh)
 - local sub = string.sub
 - local byte = string.byte
 - local tcp = ngx.socket.tcp
 - local null = ngx.null
 - local type = type
 - local pairs = pairs
 - local unpack = unpack
 - local setmetatable = setmetatable
 - local tonumber = tonumber
 - local tostring = tostring
 - local rawget = rawget
 - --local error = error
 - local ok, new_tab = pcall(require, "table.new")
 - if not ok or type(new_tab) ~= "function" then
 - new_tab = function (narr, nrec) return {} end
 - end
 - local _M = new_tab(0, 54)
 - _M._VERSION = '0.26'
 - local common_cmds = {
 - "get", "set", "mget", "mset",
 - "del", "incr", "decr", -- Strings
 - "llen", "lindex", "lpop", "lpush",
 - "lrange", "linsert", -- Lists
 - "hexists", "hget", "hset", "hmget",
 - --[[ "hmset", ]] "hdel", -- Hashes
 - "smembers", "sismember", "sadd", "srem",
 - "sdiff", "sinter", "sunion", -- Sets
 - "zrange", "zrangebyscore", "zrank", "zadd",
 - "zrem", "zincrby", -- Sorted Sets
 - "auth", "eval", "expire", "script",
 - "sort" -- Others
 - }
 - local sub_commands = {
 - "subscribe", "psubscribe"
 - }
 - local unsub_commands = {
 - "unsubscribe", "punsubscribe"
 - }
 - local mt = { __index = _M }
 - function _M.new(self)
 - local sock, err = tcp()
 - if not sock then
 - return nil, err
 - end
 - return setmetatable({ _sock = sock, _subscribed = false }, mt)
 - end
 - function _M.set_timeout(self, timeout)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - return sock:settimeout(timeout)
 - end
 - function _M.connect(self, ...)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - self._subscribed = false
 - return sock:connect(...)
 - end
 - function _M.set_keepalive(self, ...)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - if rawget(self, "_subscribed") then
 - return nil, "subscribed state"
 - end
 - return sock:setkeepalive(...)
 - end
 - function _M.get_reused_times(self)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - return sock:getreusedtimes()
 - end
 - local function close(self)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - return sock:close()
 - end
 - _M.close = close
 - local function _read_reply(self, sock)
 - local line, err = sock:receive()
 - if not line then
 - if err == "timeout" and not rawget(self, "_subscribed") then
 - sock:close()
 - end
 - return nil, err
 - end
 - local prefix = byte(line)
 - if prefix == 36 then -- char '$'
 - -- print("bulk reply")
 - local size = tonumber(sub(line, 2))
 - if size < 0 then
 - return null
 - end
 - local data, err = sock:receive(size)
 - if not data then
 - if err == "timeout" then
 - sock:close()
 - end
 - return nil, err
 - end
 - local dummy, err = sock:receive(2) -- ignore CRLF
 - if not dummy then
 - return nil, err
 - end
 - return data
 - elseif prefix == 43 then -- char '+'
 - -- print("status reply")
 - return sub(line, 2)
 - elseif prefix == 42 then -- char '*'
 - local n = tonumber(sub(line, 2))
 - -- print("multi-bulk reply: ", n)
 - if n < 0 then
 - return null
 - end
 - local vals = new_tab(n, 0)
 - local nvals = 0
 - for i = 1, n do
 - local res, err = _read_reply(self, sock)
 - if res then
 - nvals = nvals + 1
 - vals[nvals] = res
 - elseif res == nil then
 - return nil, err
 - else
 - -- be a valid redis error value
 - nvals = nvals + 1
 - vals[nvals] = {false, err}
 - end
 - end
 - return vals
 - elseif prefix == 58 then -- char ':'
 - -- print("integer reply")
 - return tonumber(sub(line, 2))
 - elseif prefix == 45 then -- char '-'
 - -- print("error reply: ", n)
 - return false, sub(line, 2)
 - else
 - -- when `line` is an empty string, `prefix` will be equal to nil.
 - return nil, "unkown prefix: \"" .. tostring(prefix) .. "\""
 - end
 - end
 - local function _gen_req(args)
 - local nargs = #args
 - local req = new_tab(nargs * 5 + 1, 0)
 - req[1] = "*" .. nargs .. "\r\n"
 - local nbits = 2
 - for i = 1, nargs do
 - local arg = args[i]
 - if type(arg) ~= "string" then
 - arg = tostring(arg)
 - end
 - req[nbits] = "$"
 - req[nbits + 1] = #arg
 - req[nbits + 2] = "\r\n"
 - req[nbits + 3] = arg
 - req[nbits + 4] = "\r\n"
 - nbits = nbits + 5
 - end
 - -- it is much faster to do string concatenation on the C land
 - -- in real world (large number of strings in the Lua VM)
 - return req
 - end
 - local function _do_cmd(self, ...)
 - local args = {...}
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - local req = _gen_req(args)
 - local reqs = rawget(self, "_reqs")
 - if reqs then
 - reqs[#reqs + 1] = req
 - return
 - end
 - -- print("request: ", table.concat(req))
 - local bytes, err = sock:send(req)
 - if not bytes then
 - return nil, err
 - end
 - return _read_reply(self, sock)
 - end
 - local function _check_subscribed(self, res)
 - if type(res) == "table"
 - and (res[1] == "unsubscribe" or res[1] == "punsubscribe")
 - and res[3] == 0
 - then
 - self._subscribed = false
 - end
 - end
 - function _M.read_reply(self)
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - if not rawget(self, "_subscribed") then
 - return nil, "not subscribed"
 - end
 - local res, err = _read_reply(self, sock)
 - _check_subscribed(self, res)
 - return res, err
 - end
 - for i = 1, #common_cmds do
 - local cmd = common_cmds[i]
 - _M[cmd] =
 - function (self, ...)
 - return _do_cmd(self, cmd, ...)
 - end
 - end
 - for i = 1, #sub_commands do
 - local cmd = sub_commands[i]
 - _M[cmd] =
 - function (self, ...)
 - self._subscribed = true
 - return _do_cmd(self, cmd, ...)
 - end
 - end
 - for i = 1, #unsub_commands do
 - local cmd = unsub_commands[i]
 - _M[cmd] =
 - function (self, ...)
 - local res, err = _do_cmd(self, cmd, ...)
 - _check_subscribed(self, res)
 - return res, err
 - end
 - end
 - function _M.hmset(self, hashname, ...)
 - if select('#', ...) == 1 then
 - local t = select(1, ...)
 - local n = 0
 - for k, v in pairs(t) do
 - n = n + 2
 - end
 - local array = new_tab(n, 0)
 - local i = 0
 - for k, v in pairs(t) do
 - array[i + 1] = k
 - array[i + 2] = v
 - i = i + 2
 - end
 - -- print("key", hashname)
 - return _do_cmd(self, "hmset", hashname, unpack(array))
 - end
 - -- backwards compatibility
 - return _do_cmd(self, "hmset", hashname, ...)
 - end
 - function _M.init_pipeline(self, n)
 - self._reqs = new_tab(n or 4, 0)
 - end
 - function _M.cancel_pipeline(self)
 - self._reqs = nil
 - end
 - function _M.commit_pipeline(self)
 - local reqs = rawget(self, "_reqs")
 - if not reqs then
 - return nil, "no pipeline"
 - end
 - self._reqs = nil
 - local sock = rawget(self, "_sock")
 - if not sock then
 - return nil, "not initialized"
 - end
 - local bytes, err = sock:send(reqs)
 - if not bytes then
 - return nil, err
 - end
 - local nvals = 0
 - local nreqs = #reqs
 - local vals = new_tab(nreqs, 0)
 - for i = 1, nreqs do
 - local res, err = _read_reply(self, sock)
 - if res then
 - nvals = nvals + 1
 - vals[nvals] = res
 - elseif res == nil then
 - if err == "timeout" then
 - close(self)
 - end
 - return nil, err
 - else
 - -- be a valid redis error value
 - nvals = nvals + 1
 - vals[nvals] = {false, err}
 - end
 - end
 - return vals
 - end
 - function _M.array_to_hash(self, t)
 - local n = #t
 - -- print("n = ", n)
 - local h = new_tab(0, n / 2)
 - for i = 1, n, 2 do
 - h[t[i]] = t[i + 1]
 - end
 - return h
 - end
 - -- this method is deperate since we already do lazy method generation.
 - function _M.add_commands(...)
 - local cmds = {...}
 - for i = 1, #cmds do
 - local cmd = cmds[i]
 - _M[cmd] =
 - function (self, ...)
 - return _do_cmd(self, cmd, ...)
 - end
 - end
 - end
 - setmetatable(_M, {__index = function(self, cmd)
 - local method =
 - function (self, ...)
 - return _do_cmd(self, cmd, ...)
 - end
 - -- cache the lazily generated method in our
 - -- module table
 - _M[cmd] = method
 - return method
 - end})
 - return _M
 
http://blog.csdn.net/deng_xintao/article/details/75441992
openresty(完整版)Lua拦截请求与响应信息日志收集及基于cjson和redis动态路径以及Prometheus监控(转)的更多相关文章
- .net core MVC 通过 Filters 过滤器拦截请求及响应内容
		
前提: 需要nuget Microsoft.Extensions.Logging.Log4Net.AspNetCore 2.2.6: Swashbuckle.AspNetCore 我暂时用的是 ...
 - Spring Boot使用AOP在控制台打印请求、响应信息
		
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等. AOP简介 AOP全称Aspect Oriented Programming,面向切面,AOP主要实现的 ...
 - springboot+aop切点记录请求和响应信息
		
本篇主要分享的是springboot中结合aop方式来记录请求参数和响应的数据信息:这里主要讲解两种切入点方式,一种方法切入,一种注解切入:首先创建个springboot测试工程并通过maven添加如 ...
 - 第14.14节  爬虫实战准备:csdn博文点赞过程http请求和响应信息分析
		
如果要对csdn博文点赞,首先要登录CSDN,然后打开一篇需要点赞的文章,如<第14.1节 通过Python爬取网页的学习步骤>按<第14.3节 使用google浏览器获取网站访问的 ...
 - 使用RestTemplate,显示请求信息,响应信息
		
使用RestTemplate,显示请求信息,响应信息 这里不讲怎么用RestTemplate具体细节用法,就是一个学习中的过程记录 一个简单的例子 public class App { public ...
 - VUE 数据请求和响应(axios)
		
1. 概述 1.1 简介 axios是一个基于Promise(本机支持ES6 Promise实现) 的HTTP库,用于浏览器和 nodejs 的 HTTP 客户端.具有以下特征: 从浏览器中创建 XM ...
 - Java Servlet (1) —— Filter过滤请求与响应
		
Java Servlet (1) -- Filter过滤请求与响应 版本: Java EE 6 参考来源: Oracle:The Java EE 6 Tutorial: Filtering Reque ...
 - Fiddler如何自动修改请求和响应包
		
Charles的Map功能可以将某个请求进行重定向,用重定向的内容响应请求的内容.这个功能非常方便.在抓包过程当中,有时候为了调试方便,需要将线上的服务定位到内网.比如我们线上的服务器域名为 api. ...
 - openresty+lua劫持请求,有点意思
		
0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了一些邪恶的东西:反代既然是所有流量走我的服务器,那我是不是能够在中途做些手脚,达到一些有趣的目的. op ...
 
随机推荐
- go中的无限极分类的问题
			
最近在开发的过程中遇到一个无限极分类的问题,这种问题在php中写过很多,想着很简单,3-5分钟就能解决,结果竟然写了半小时,既然这样,就把这个给总结下. 思路 1.循环数据,放到hash中,把标识的数 ...
 - JDK、JRE与JVM的关系
 - Abp IRepository 方法解释(1)
			
// // 摘要: // This interface is implemented by all repositories to ensure implementation of ...
 - CVE-2017-12615漏洞利用
			
Tomcat任意文件上传漏洞CVE-2017-12615复现 今天在群里听到有人讲这个CVE-2017-12615漏洞,想起自己的虚机ubuntu里面曾经装过tomcat,午休时间来瞅瞅. 漏洞利用条 ...
 - noteforjs
			
轻量高效的开源JavaScript插件和库---<!-- TOC --> - [图片](#图片)- [布局](#布局)- [轮播图](#轮播图)- [弹出层](#弹出层)- [音频视频]( ...
 - 流(Stream)与文件流(FileStream)
			
//通过流的方式添加 StreamWriter writer = new StreamWriter(@"C:\A\ca.txt", true, Encoding.Default); ...
 - LInux下的jdk环境置
			
1.Linux下使用wget下载jdk8: 进入目录/usr/local/software 2.解压 tar -zxvf jdk-8u152-linux-x64.tar.gz 3.配置环境变量 vi ...
 - 设置nginx中文件上传的大小限制度
			
通过设置nginx的client_max_body_size解决nginx+php上传大文件的问题: 用nginx来做webserver的时,上传大文件时需要特别注意client_max_body_s ...
 - 49.纯 CSS 创作一支诱人的冰棍
			
原文地址:https://segmentfault.com/a/1190000015257561 感想:重点在让色彩滚动起来->background-position: 0 1000vh; HT ...
 - 15.纯 CSS 创作条形图,不用任何图表库
			
原文代码:https://segmentfault.com/a/1190000014768534#articleHeader1 HTML代码: <html> <head> &l ...