直接上文件
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