菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
309
0

openresty(完整版)Lua拦截请求与响应信息日志收集及基于cjson和redis动态路径以及Prometheus监控(转)

原创
05/13 14:22
阅读数 92407

直接上文件

nginx.conf

 

[plain] view plain copy
 
  1. #运行用户和组,缺省为nobody,若改为别的用户和组,则需要先创建用户和组  
  2. #user wls81 wls;   
  3.   
  4. #开启进程数,一般与CPU核数等同  
  5. worker_processes  4;  
  6.   
  7. #设置进程到cpu(四cpu:0001 0010 0100 1000)  
  8. #worker_cpu_affinity 0001 0010 0100 1000;  
  9.   
  10. #每个进程最大打开文件数  
  11. worker_rlimit_nofile 8000;  
  12.   
  13. #进程号保存文件  
  14. #pid        /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/nginx.pid;  
  15. error_log  /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/error.log;  
  16. pid        /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/nginx.pid;  
  17.   
  18. #设置错误日志  
  19. #error_log  /wls/apache/applogs/ng_sbtps-opf-dmzweb-nginx/error.log;  
  20. error_log  logs/error.log  notice;  
  21. error_log  logs/error.log  info;  
  22.   
  23.   
  24. events  
  25. {  
  26.     #运行模式设置[ kqueue | rtsig | epoll | /dev/poll | select | poll ];  
  27.     #使用epoll(linux2.6的高性能方式)  
  28.     use epoll;  
  29.       
  30.     #每个进程最大连接数(最大连接=连接数x进程数)  
  31.     worker_connections  8000;  
  32. }  
  33.   
  34. http  
  35. {  
  36.   
  37.     #文件扩展名与文件类型映射表  
  38.     #include       mime.types;  
  39.   
  40.     #默认文件类型  
  41.     #default_type  text/html;  
  42.     default_type  application/octet-stream;  
  43.       
  44.     #服务器名称相关设置  
  45.     server_names_hash_max_size    256;  
  46.     server_names_hash_bucket_size 512;  
  47.   
  48.     #默认编码  
  49.     charset UTF-8;  
  50.   
  51.     #开启高效文件传输模式,直接从系统级别传输(Linux 2.4以上支持,纯文件服务器才能打开)  
  52.     sendfile   off;  
  53.   
  54.     #网络TCP_NOPUSH和TCP_NODELAY参数设置  
  55.     #tcp_nopush on;  
  56.     tcp_nodelay on;  
  57.   
  58.     #设置保留链接超时时间为75秒 设置header超时时间为20秒  
  59.     keepalive_timeout 75 20;  
  60.   
  61.     #打开gzip压缩  
  62.     gzip  on;  
  63.   
  64.     #最小压缩文件大小  
  65.     gzip_min_length  1K;  
  66.   
  67.     #压缩缓冲区  
  68.     gzip_buffers     4 8k;  
  69.   
  70.     #压缩类型  
  71.     gzip_types       text/* text/css application/javascript application/x-javascript application/xml;  
  72.   
  73.     #压缩级别 1-9 1最快 9最慢  
  74.     gzip_comp_level  9;  
  75.   
  76.     #压缩通过代理的所有文件  
  77.     gzip_proxied     any;  
  78.   
  79.     #vary header支持  
  80.     gzip_vary        on;  
  81.   
  82.     #压缩版本(默认1.1,前端为squid2.5使用1.0)  
  83.     gzip_http_version 1.1;  
  84.       
  85.   
  86.     #输出缓冲区  
  87.     output_buffers   4  32k;  
  88.   
  89.     #输出拆包大小  
  90.     postpone_output  1460;  
  91.   
  92.     #接收header的缓冲区大小  
  93.     client_header_buffer_size 128k;  
  94.     large_client_header_buffers 4 256k;  
  95.   
  96.     #客户端发送header超时  
  97.     client_header_timeout  3m;  
  98.   
  99.     #客户端发送内容超时  
  100.     client_body_timeout    3m;  
  101.   
  102.     #发送到客户端超时  
  103.     send_timeout           3m;  
  104.   
  105.   
  106.   
  107.     #捕捉代理端的http错误  
  108.     #proxy_intercept_errors  on;  
  109.   
  110.   
  111.   
  112.     #日志文件格式  
  113.     log_format main '$remote_addr $http_x_forwarded_for $remote_user $time_iso8601 $status '  
  114.                            '$server_protocol logTraceId:$request_id $comp_sign $request_method $reSetReqUri $uri $http_referer $gzip_ratio '  
  115.                            '"$http_user_agent" '  
  116.                            '$body_bytes_sent $bytes_sent $request_length "$upstream_addr" "$upstream_header_time" "$upstream_response_time" $request_time';     
  117.     log_format  requestBody  '$remote_addr - $remote_user [$time_local] "$request" '  
  118.                       '"$status" $body_bytes_sent "$http_referer" '  
  119.                       '"$http_user_agent" "$http_x_forwarded_for" logTraceId:$request_id req_body:"$request_body" resp_body:"$resp_body" resp_map:"$resp_map"'  
  120.                       '$upstream_addr $bytes_sent $request_length "$upstream_response_time" "$request_time"';     
  121.     lua_need_request_body on;   
  122.     #日志文件(不记录)  
  123.     #access_log  /dev/null;  
  124.     #access_log   logs/access.log main;  
  125.   
  126.   
  127.   
  128.   
  129.     #默认主机配置  
  130.     #include default_host.conf;  
  131.       
  132.       
  133.   
  134.     #包含其它虚拟主机配置;  
  135.     include servers/*.com;  
  136.     include servers/*.net;  
  137.     include servers/*.org;  
  138.     include servers/*.cn;  
  139. }  

 

 

sbtps-opf-sfweb-nginx.com

 

[plain] view plain copy
 
  1. include /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/servers/respCodeMap.map;  
  2. #api映射配置  
  3. lua_shared_dict apiMappingShared 50m;  
  4. lua_shared_dict healthStatus 1m;  
  5. lua_shared_dict redisSwitchShared 256k;  
  6. lua_shared_dict prometheus_metrics 10M;  
  7. client_body_buffer_size 8m;  
  8. client_max_body_size 8m;  
  9. init_by_lua_file /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/init.lua;  
  10. #获取访问客户的真实IP  
  11. map $http_x_forwarded_for  $clientRealIp {  
  12.         ""  $remote_addr;  
  13.         ~^(?P<firstaddr>[0-9\.]+),?.*$  $firstAddr;  
  14. }  
  15. #限制客户端的访问频次,这里限制每秒20次上限  
  16. limit_req_zone $clientRealIp zone=SF-WEB-AUTHAPP-LIMIT:10m rate=100r/s;  
  17. #配置负载均衡服务器(采用IP Hash算法,相同客户IP会转发到相同服务器)  
  18.   
  19. upstream SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS  
  20. {     
  21.     #tomcat的地址和端口  
  22.     server 10.25.174.28:32050;  
  23. }  
  24.   
  25.   
  26. server  
  27. {  
  28.     #设置监听端口  
  29.     listen 37775 default;  
  30.       
  31.     #设置服务器域名(IP访问和多域名访问可不设置)  
  32.     #server_name _*;  
  33.     #server_name  www.test.com;  
  34.       
  35.   
  36.     #开启shtml支持  
  37.     #ssi on;  
  38.     #ssi_silent_errors on;  
  39.     #ssi_types text/shtml;  
  40.       
  41.   
  42.     #设置主访问日志  
  43.     #access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/access.log main;  
  44.     #access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/requestBody.log  requestBody;  
  45.     error_log  /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/error.log error;  
  46.     access_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/access.log  main;  
  47.     error_log /wls/appsystems/nginx/openresty-1.11.2.4/nginx/logs/request.log  crit;  
  48.       
  49.     ##定义$request_trace_id的值,在1.11.x之前,我们可以使用类似的方式声明,只要能确保    
  50.     ##其值出现重复的可能性尽可能的小即可。    
  51.     set $request_trace_id trace-id-$pid-$connection-$bytes_sent-$msec;    
  52.     set $comp_sign "";  
  53.     set $reSetReqUri $request_uri;  
  54.     set $resp_body "";  
  55.     set $resp_map "";  
  56.     set $apiSign "";  
  57.       
  58.     #access_log  /dev/null;  
  59.     #fastcgi_intercept_errors on;  
  60.     #error_page  404 403  =    /404.html;  
  61.     #error_page  500 502 503 504  =  /50x.html;  
  62.     include /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/servers/server-http-error-page.err;  
  63.    #设置转发到跟投APP后端服务器的URL(正则表达式)  
  64.     #location ~ (^/pa/interface/jk/(cgi-bin|servlet|chart)/|\.jsp$)  
  65.    #{  
  66.        #proxy_pass http://backendServer;  
  67.        #include proxy.conf;  
  68.    #}  
  69.   
  70.     #设置转发到后端服务器的URL(正则表达式)  
  71.     #location ~ (^/pa/newstock/hq/(cgi-bin|servlet|chart)/|\.jsp$)  
  72.    #{  
  73.        #proxy_pass http://backendServer;  
  74.        #include proxy.conf;  
  75.    #}  
  76.       
  77.   
  78.     #设置监控nginx状态URL  
  79.     #location /__nginxstatus  
  80.     #{  
  81.     #   stub_status on;  
  82.     #   access_log off;  
  83.     #}  
  84.   
  85.     location ^~ /reloadApiMapping {  
  86.         default_type    "text/plain";  
  87.         content_by_lua '  
  88.             require("apiMapping");  
  89.             apiMapping.reloadApiMapping();  
  90.         ';  
  91.     }  
  92.     location ^~ /setRedisSwitch {  
  93.         default_type    "text/plain";  
  94.         content_by_lua '  
  95.             ngx.log(ngx.ERR,"this is setRedisSwitch routeLocation !")  
  96.             require("apiMapping");  
  97.             apiMapping.setRedisSwitch();  
  98.         ';  
  99.     }  
  100.     location /metrics {  
  101.         content_by_lua '  
  102.             metric_connections:set(ngx.var.connections_reading, {"active"})  
  103.             metric_connections:set(ngx.var.connections_reading, {"reading"})  
  104.             metric_connections:set(ngx.var.connections_waiting, {"waiting"})  
  105.             metric_connections:set(ngx.var.connections_writing, {"writing"})                      
  106.             prometheus:collect()  
  107.         ';  
  108.     }  
  109.     location /favicon.ico {  
  110.         log_not_found off;  
  111.         access_log off;  
  112.     }  
  113.       
  114.     location ^~ /beat/checkSet {  
  115.         default_type    "text/plain";  
  116.         content_by_lua '  
  117.             local reqUri = ngx.var.uri;   
  118.             local status=string.sub(reqUri,16,-1);  
  119.             local healthStatus = ngx.shared.healthStatus;  
  120.             healthStatus:set("status", status);  
  121.             local data = {};  
  122.             data["status"]=status;  
  123.             ngx.say(cjson.encode(data));  
  124.         ';  
  125.     }  
  126.       
  127.     location ^~ /beat/check {  
  128.         default_type    "text/plain";  
  129.         content_by_lua '  
  130.             local healthStatus = ngx.shared.healthStatus;  
  131.             local status = healthStatus:get("status");  
  132.             if status == nil or status=="" then  
  133.                 status ="UP"  
  134.             end  
  135.               
  136.             local data = {};  
  137.             data["status"]=status;  
  138.             ngx.say(cjson.encode(data));  
  139.         ';  
  140.     }  
  141.       
  142.     #设定根目录(若全部请求转发到后端服务器则不需要设置)   
  143.     location /  
  144.     {  
  145.         #web根目录,根据实际情况调整  
  146.        
  147.         #limit_req zone=SF-WEB-AUTHAPP-LIMIT nodelay;  
  148.         #proxy_pass http://SF-WEB-AUTHAPP/;  
  149.         proxy_set_header Host $host;  
  150.         proxy_set_header            X-real-ip $remote_addr;  
  151.         proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;  
  152.         proxy_set_header logTraceId $request_id;  
  153.         set $comp_sign AUTH2;  
  154.         set $reSetReqUri $request_uri;   
  155.         set $redisResultJson "";  
  156.         lua_need_request_body on;  
  157.         #set $resp_map "";  
  158.         rewrite_by_lua  'apiMapping.getCompSign()';  
  159.         body_filter_by_lua_file  /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/modules/apimapping/request.lua;  
  160.         proxy_set_header X-Request-ID $request_id;  
  161.         proxy_pass         http://$comp_sign/AuthApp$reSetReqUri;  
  162.         log_by_lua_file  /wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/scripts/luas/modules/apimapping/log.lua;  
  163.         #log_by_lua 'ngx.log(ngx.ERR,"resp_map is :"..ngx.var.resp_map)';  
  164.     }  
  165. }  
  166. </firstaddr>  

 

 

server-http-error-page.err

 

[plain] view plain copy
 
  1. error_page 404 = /httpStatusRewrite?apiRespCodeParam=-10201;  
  2. error_page 403 = /httpStatusRewrite?apiRespCodeParam=-5;  
  3. error_page 503 = /httpStatusRewrite?apiRespCodeParam=-6;  
  4. error_page 500 502 504  = /httpStatusRewrite?apiRespCodeParam=-1;  
  5.   
  6. location /httpStatusRewrite{  
  7.     default_type    "text/plain";  
  8.     set $apiRespCode  $arg_apiRespCodeParam;  
  9.     if ( $apiRespMsg = '' ) {  
  10.         return 200 '{"resCode":"-1","resMsg":"请求失败"}';  
  11.     }  
  12.     return 200 '{"resCode":"$apiRespCode","resMsg":"$apiRespMsg"}';  
  13. }  

 

 

respCodeMap.map

 

[plain] view plain copy
 
  1. map $apiRespCode  $apiRespMsg {   
  2.     "0" "SUCCESS。";  
  3.     "-10000" "参数不可为空。";  
  4.     "-1" "请求失败。";  
  5.     "-5" "禁止访问。";  
  6.     "-6" "访问频率过快,请稍后再试。";  
  7.     "-10201" "未定义路径。";  
  8.     "-1006" "参数格式异常。";  
  9.     "-1013" "目前仅支持POST请求方式。";  
  10. }  

 

 

 

init.lua

 

[plain] view plain copy
 
  1. function init()  
  2.     cjson = require "cjson";  
  3.     lfs = require "lfs"  
  4.     SCRIPT_ROOT_PATH = '/wls/appsystems/nginx/openresty-1.11.2.4/nginx/conf/';  
  5.     initLuaModule()  
  6.     apiMapping = require "apiMapping"  
  7.     local LATENCY_BUCKETS = {0.05, 0.2, 0.5, 1, 5, 10}  
  8.     local BYTESIZE_BUCKETS = {1, 3, 5, 10, 15 , 20}  
  9.     prometheus = require("prometheus").init("prometheus_metrics")  
  10.     --counter metrics for host+upstream  
  11.     metric_requests = prometheus:counter("nginx_http_requests_total", "Number of HTTP requests", {"host","upstream", "status"})  
  12.     --metric_ssorequests = prometheus:counter("nginx_http_sso_requests_total", "Number of HTTP sso requests", {"status"})  
  13.     --gauge metrics  
  14.     metric_connections = prometheus:gauge("nginx_http_connections", "Number of HTTP connections", {"state"})  
  15.     --histogram metrics for upstream  
  16.     metric_latency = prometheus:histogram("nginx_http_request_duration_seconds", "HTTP request latency", {"upstream"}, LATENCY_BUCKETS)  
  17.     --metric_ssolatency = prometheus:histogram("nginx_http_sso_duration_seconds", "HTTP sso request latency",{}, LATENCY_BUCKETS)  
  18.     metric_bytes = prometheus:histogram("nginx_http_request_bytes_sent", "HTTP responses size", {"upstream"}, BYTESIZE_BUCKETS)  
  19.   
  20.     apiMapping.init()  
  21.     redisClusterConfig()  
  22. end   
  23.   
  24. function initLuaModule(rootPath)  
  25.     local rootPath=SCRIPT_ROOT_PATH..'scripts/luas/';  
  26.     getpathes(rootPath, nil);  
  27. end  
  28.   
  29. function getpathes(rootpath, pathes)  
  30.     pathes = pathes or {}  
  31.     local attr = lfs.attributes(rootpath)  
  32.     if attr and attr.mode == 'directory' then         
  33.         package.path = string.format("%s?.lua;%s", rootpath, package.path)  
  34.         for entry in lfs.dir(rootpath) do  
  35.             if entry ~= '.' and entry ~= '..' then  
  36.                 getpathes(rootpath  ..  entry.. '/', pathes)  
  37.             end  
  38.         end                
  39.     end  
  40.   
  41.     return pathes  
  42. end  
  43.   
  44. function redisClusterConfig()  
  45.     local config = {  
  46.                     name="openapi",  
  47.                     serv_list = {  
  48.                             {ip="10.25.174.28", port = 6001},  
  49.                             {ip="10.25.174.28", port = 6002},  
  50.                             {ip="10.25.174.28", port = 6003},  
  51.                             {ip="10.25.174.28", port = 7001},  
  52.                             {ip="10.25.174.28", port = 7002},  
  53.                             {ip="10.25.174.28", port = 7003},  
  54.                             {ip="10.25.174.28", port = 6001},  
  55.                             {ip="10.25.174.28", port = 6002},  
  56.                         },  
  57.                         keepalive_timeout = 200,  
  58.                         keepalove_cons = 20  
  59.                     }  
  60.     ngx.shared.redisClusterConfig = config;  
  61.     networkSign = "OPENAPI_NGINX_ROUTE_NODE_LAN";--内网  
  62.     --networkSign = "OPENAPI_NGINX_ROUTE_NODE_WAN";--外网  
  63. end  
  64. init();   

 

 

apiMapping.json

 

[plain] view plain copy
 
  1. {  
  2. "forward_otc_signElectContract":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  3. "forward_test":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  4. "forward_trade_queryNewSharePayment-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  5. "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"]},  
  6. "forward_soas_findByBankText":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  7. "forward_kcxp_queryUserOccuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  8. "forward_tsp_queryFundVol":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  9. "forward_zd_historicalRevision":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  10. "L2919000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  11. "forward_kbss_signElectronicPact":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  12. "forword_kbss_getAccountByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  13. "forward_soas_getCustIDCardImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  14. "forward_xjb_getXjbProgress":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  15. "forward_khpp_insertDataBatch":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  16. "forward_soas_findThreeBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  17. "L2935000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  18. "forward_kcxp_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  19. "L2912031":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  20. "L2912022":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  21. "forward_bps_submitCustRiskAns":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  22. "forward_trade_merchandiseOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  23. "forward_qer_openQER":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  24. "forward_batch_collectionTbcBankInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  25. "forward_kcxp_custInfoCheckoptn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  26. "forward_bps_listBoodsBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  27. "forward_khpp_loadData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  28. "forward_openacc_getDZHOpenaccResultInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  29. "forward_otc_queryRiskLevel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  30. "forward_qer_submitRish":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  31. "forward_otc_queryAccountInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  32. "L2935021":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  33. "forward_bps_readImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  34. "forward_trade_queryMatched":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  35. "forward_kcxpService_zpck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  36. "forward_trade_queryBankSecurityTrans":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  37. "forward_qer_bankAuth":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  38. "forward_soas_uploadIdImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  39. "forward_push_applyPush":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  40. "L2912027":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  41. "forward_bps_bindCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  42. "forward_tsp_queryAccounts ":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  43. "forward_dubbo_returnString":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  44. "L2912006":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  45. "forward_qer_pledgeOrRepurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  46. "forward_bps_mainChangeObey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  47. "forward_qer_genSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  48. "Hello":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  49. "L2912100":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  50. "L2934007":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  51. "L2910204":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  52. "forward_otc_queryRiskMatchLevel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  53. "forward_kh_cybAdd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  54. "forward_trade_merchandiseOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  55. "forward_otc_lfexOpenAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  56. "forward_soas_finaAcceptedServiceTime":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  57. "L2912018":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  58. "forward_trade_queryExtInstInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  59. "forward_zd_tradingDay":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  60. "forward_push_changePushType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  61. "http":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  62. "forward_kcxpService_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  63. "forward_qer_checkRisks":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  64. "forward_kcxp_queryRegisterAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  65. "forward_bps_videoInvalid":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  66. "forward_kh_IdCardpromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  67. "forward_trade_queryOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  68. "forward_trade_queryOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  69. "forward_bps_appropriateInfoSave":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  70. "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"]},  
  71. "forward_bps_queryRepurchaseOffer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  72. "forward_sms_sendSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  73. "forward_qer_getSupplyPledgeList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  74. "forward_trade_queryNewShareAcctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  75. "forward_soas_pushThs":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  76. "forward_ggt_isLegalClient":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  77. "forward_account_custAgmtCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  78. "forward_xjb_getXJBAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  79. "forward_trade_login-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  80. "forward_kh_IdCardAuthentication":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  81. "forward_bps_imgReuslt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  82. "forward_otc_openAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  83. "forward_trade_bankSecurityTransOut":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  84. "forward_kcxp_queryCustAdequacyInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  85. "forward_openacc_submitOpenaccNoMaterialInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  86. "forward_OpenAcc_saveHangUpVideo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  87. "forward_xjb_setRetainShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  88. "forward_soas_queryCustSource":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  89. "forward_aoi_ApproMatching":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  90. "forward_otc_queryAssetAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  91. "forward_config_getIp":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  92. "forward_account_bjhgQualificationCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  93. "L2912001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  94. "forward_common_queryIPOChosenInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  95. "L2934000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  96. "forward_bps_getTrdCustAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  97. "forward_otc_productPurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  98. "forward_tsp_querySecuAcc":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  99. "forward_khpp_delData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  100. "forward_cts_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  101. "forward_trade_queryFundsFlow":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  102. "forward_trade_queryDeliveryOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  103. "forward_openacc_getUserQueueNo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  104. "forward_kcxp_queryCustomInfoByType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  105. "forward_kcxpService_zpqk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  106. "forward_kh_searchYmtByCardNo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  107. "forward_soas_saveAcceptedAccountTransferInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  108. "forward_trade_queryFunds-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  109. "forward_bps_validateQualifiedInvestor":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  110. "forward_zd_securitiesAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  111. "forward_push_queryPushStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  112. "L2934016":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  113. "L2912102":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  114. "forward_account_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  115. "forward_trade_pagedQueryMatched-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  116. "forward_zd_unfreeze":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  117. "forward_dubbo_returnStringdubbo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  118. "forward_zd_partnerInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  119. "forward_otc_queryProductPurchase":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  120. "L2934005":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  121. "L2930001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  122. "forward_cams_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  123. "forward_trade_bankSecurityTransIn-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  124. "forward_ggt_submitSurveyAnswers":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  125. "forward_otc_synCustPayAcctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  126. "L2912025":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  127. "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"]},  
  128. "forward_trade_queryBankSecurityTrans-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  129. "forward_tsp_getUserInfoById":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  130. "forward_trade_queryUserSecuInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  131. "forward_khpp_updateData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  132. "forward_xjb_cashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  133. "forward_t_sign":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  134. "L2912028":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  135. "forward_trade_queryNewSharePayment":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  136. "forward_xjb_checkCashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  137. "forward_tsp_querySystemStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  138. "forward_account_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  139. "forward_qer_getCustInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  140. "forward_trade_queryShareProfit":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  141. "forward_bps_uploadImage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  142. "forward_soas_addChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  143. "forward_bps_fundCodeVerification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  144. "L2933000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  145. "forward_kh_cybCanOpen":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  146. "forward_tsp_queryUserBasicInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  147. "forward_OpenAcc_checkChannelAuth":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  148. "forward_otc_fundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  149. "forward_zd_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  150. "L2932522":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  151. "L2912009":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  152. "forward_account_queryTrdacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  153. "forward_common_checkShareholderAccounts":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  154. "forward_push_cancelBind":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  155. "forward_trade_queryExtInstInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  156. "forward_batch_getTbcStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  157. "L2930003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  158. "forward_kcxp_userOccuInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  159. "L2910212":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  160. "forward_bps_fundAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  161. "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"]},  
  162. "forward_trade_queryShare":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  163. "forward_otc_cybSignResultCallBack":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  164. "forward_soas_chkCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  165. "forward_kcxp_queryHisQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  166. "forward_kh_IdCardpromotionTract":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  167. "L2934002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  168. "L2934027":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  169. "L2930002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  170. "forward_soas_verification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  171. "forward_trade_bankSecurityTransIn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  172. "forward_soas_getProtocolList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  173. "forward_bps_queryAppropriateSurveyRating":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  174. "forward_qer_openQERNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  175. "forward_zd_liftLossAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  176. "forward_trade_banksecurityTransOut":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},  
  177. "forward_aoi_querySpecialAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  178. "forward_trade_queryDeliveryOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  179. "forward_account_queryBjhgQualification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  180. "forward_aoi_batchRiskSurvey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  181. "forward_qer_getRishQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  182. "forward_otc_riskDataUpload":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  183. "forward_batch_runTbcTask":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  184. "L2912101":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  185. "forward_common_midDataPersistence":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  186. "L2912515":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  187. "forward_IPO_queryIPOChosenInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  188. "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"]},  
  189. "forward_trade_querySecuAcct-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  190. "forward_bps_getCustAgmtStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  191. "forward_tsp_login":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  192. "forward_zd_relationshipConfirmation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  193. "forward_kbss_getAccountByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  194. "forward_xjb_getAgreementInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  195. "forward_cts_zpqk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  196. "forward_openacc_queryAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  197. "forward_xjb_XjbAdd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  198. "forward_otc_synCuacctInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  199. "forward_bps_mainChangeObeyAllInOne":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  200. "forward_account_queryCustAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  201. "forward_otc_qtyFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  202. "forward_ggt_getSurveyQuestions":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  203. "forward_xjb_getAvailableNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  204. "forward_common_queryIPOChosenInfoNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  205. "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"]},  
  206. "forward_kcxp_custBatchAnswer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  207. "forward_zd_findTracctByIdno":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  208. "L2935022":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  209. "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"]},  
  210. "forward_trade_queryIPOCalendar":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  211. "forward_zd_useInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  212. "forward_bps_updateQualifiedInvestor":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  213. "forward_bps_operBoodsBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  214. "forward_kbss_synClientInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  215. "forward_soas_test2":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  216. "L2916108":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  217. "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"]},  
  218. "forward_zd_accountCancellation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  219. "forward_tsp_queryExtAccByCustCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  220. "L2932524":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  221. "forward_kcxp_queryUserByTel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  222. "forward_xjb_getRapidRedeemBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  223. "forward_soas_savaQuestionnaire":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  224. "forward_cts_zpck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  225. "forward_xjb_getRetainShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  226. "forward_common_queryPersonalAsset":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  227. "forward_openacc_antHangUp":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  228. "forward_account_operateStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  229. "forward_qer_getCanPledgeShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  230. "forward_trade_queryFundsFlow-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  231. "forward_account_queryUserBasicInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  232. "forward_zd_logonData":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  233. "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"]},  
  234. "forward_sbtpsboa_modifyIPOsOrderInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  235. "forward_trdacct_findTracctByIdno":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  236. "forward_trade_cancleOrder-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  237. "forward_kess_idVerify2":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  238. "forward_bps_repurchaseOffer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  239. "forward_aoi_queryHisRiskTest":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  240. "L2912020":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  241. "forward_kcxp_queryCustCapitalInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  242. "forward_soas_checkSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  243. "forward_kess_idVerify":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  244. "forward_openacc_queryVideoVerify":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  245. "forward_bps_savaCustomer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  246. "L2934023":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  247. "forward_bps_appropriateSet":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  248. "forward_common_IDVerifyHessian":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  249. "forward_trade_login":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  250. "forward_trade_queryNewShareAcctInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  251. "forward_kcxp_queryCustCommonInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  252. "L2912023":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  253. "forward_account_queryUserBasicInfoExt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  254. "forward_openacc_getOpenaccInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  255. "forward_kcxp_setCustAdequacyInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  256. "forward_tsp_queryRiskInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  257. "forward_soas_genSmsVerifyCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  258. "forward_soas_updateCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  259. "forward_trade_querySecuMessage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  260. "forward_soas_savaCuacctPwd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  261. "forward_zd_dataModification":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  262. "forward_aoi_queryStockCodeAppro":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  263. "L2932514":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  264. "forward_account_openQualifiedInvestorRight":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  265. "forward_kess_idVerify244":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  266. "forward_qer_canOpenQER":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  267. "forward_openacc_submitOpenaccInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  268. "forward_trade_pagedQueryMatched":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  269. "forward_trade_banksecurityTransIn":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},  
  270. "1":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  271. "L2912026":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  272. "L2912004":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  273. "L2934003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  274. "forward_soas_test":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  275. "file_lfex_preFundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  276. "L2910213":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  277. "forward_openacc_verifyAntAccount":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  278. "forward_lu_bindCode":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  279. "forward_trade_queryNewShareAssignInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  280. "L2912010":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  281. "L2912014":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  282. "L2912002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  283. "forward_soas_delChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  284. "forward_soas_savaBank":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  285. "forward_kcxp_custRiskBatchAnswer":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  286. "forward_":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  287. "forward_zd_managementInformation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  288. "L2934004":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  289. "forward_trade_queryIPOCalendar-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  290. "forward_zd_dataCheck":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  291. "forward_zd_ymtApply":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  292. "forward_kcxpService_adjustFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  293. "forward_cyb_cybSignResultCallBack":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  294. "L2912103":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  295. "SBTPS-OPF-AIO-WEB-DMZ-WEB-AUTH-APP":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},  
  296. "forward_zd_accountActivation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  297. "forward_trade_querySecuAcct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  298. "forward_kcxp_custRecordInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  299. "L2912005":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  300. "forward_qer_getPledgeSharesList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  301. "L2912024":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  302. "forward_kcxp_beneficiaryInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  303. "forward_common_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  304. "forward_kcxp_queryBeneficiaryInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  305. "forward_bps_appropriateQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  306. "forward_zd_ymtCancellation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  307. "L2930000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  308. "forward_soas_findCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  309. "forward_xjb_cashRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  310. "forward_aoi_MessageRevealSN":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  311. "forward_kh_listOfStkTrdAcct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  312. "forward_xjb_signCashRapidRedeem":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  313. "forward_ocr_readImgText":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  314. "forward_test_aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  315. "forward_soas_queryAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  316. "forward_cams_listCuacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  317. "forward_soas_findProfession":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  318. "forward_kcxp_controllerInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  319. "forward_trade_queryMatched-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  320. "forward_soas_getProtocolByID":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  321. "forward_bps_preMainChangeObey":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  322. "forward_test_testfdfdsf":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  323. "forward_soas_findQuestionnaire":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  324. "forward_bps_accountResult":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  325. "forward_soas_getCustBaseInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  326. "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"]},  
  327. "forward_xjb_updateAgmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  328. "forward_kcxp_custInfoCheckOptn":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  329. "forward_kcxp_custInfoManage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  330. "L2912029":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  331. "forward_zd_InformationInquiry":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  332. "forward_zhx_idCardAuthentication":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  333. "forward_zd_securitiesAccountCreation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  334. "forward_soas_savaCust":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  335. "forward_app_stocksearch":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  336. "forward_openacc_getOcrUserInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  337. "forward_otc_registAccountMaintain":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  338. "forward_tsp_queryShares":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  339. "forward_zd_searchYmt":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  340. "forward_zd_incidenceRelation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  341. "L2933001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  342. "forward_aoi_queryRiskTest":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  343. "forward_otc_signElectPromise":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  344. "forward_qer_signNewAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  345. "forward_bps_resultQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  346. "forward_soas_queryKhppBatchInfoByUser":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  347. "forward_tsp_queryCapital":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  348. "forward_zd_searchStkAcctBizInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  349. "forward_cts_adjustFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  350. "forward_xjb_estimateIncome":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  351. "forward_account_openDelistingStockTradeRight":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  352. "forward_ggt_openGGT":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  353. "forward_trade_querySecuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-DMZPTR-AUTH-APP"},  
  354. "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"]},  
  355. "forward_kcxp_queryControllerInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  356. "file_lfex_fundFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  357. "forward_xjb_changeCashTreasureStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  358. "forward_verify_verifyByChannel":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  359. "forward_soas_submitLicense":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  360. "forward_trade_queryNewShareAssignInfo-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  361. "forward_kcxp_custCapitalInfoMainten":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  362. "forward_kh_cybAddResultQuery":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  363. "L2912019":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  364. "forward_xjb_xjbYieldRate":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  365. "L2934024":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  366. "forward_kbss_checkShareholderAccounts":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  367. "forward_trade_queryQuotation":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  368. "forward_bps_idNumberPromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  369. "forward_kcxp_queryCustRecordInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  370. "forward_bps_uploadImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  371. "forward_trade_cancleOrder":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  372. "forward_trade_queryIPOChosenInfoNew":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  373. "forward_trade_queryMaxShareQty-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  374. "forward_trade_queryFunds":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  375. "forward_soas_findOpenAccountStatus":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  376. "forward_soas_getEnumByType":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  377. "forward_soas_readImg":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  378. "L2933002":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  379. "forward_zd_searchStkAcctBizInfoToEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  380. "forward_trade_queryQuotation-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  381. "dddgffd":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  382. "forward_soas_test3":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  383. "L2934001":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  384. "forward_soas_findRisk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  385. "L2933003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  386. "forward_xjb_historicaIncome":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  387. "L2912013":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  388. "L2912000":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  389. "forward_bps_signAgreement":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  390. "forward_trade_queryShare-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  391. "forward_ggt_getStockholderCardList":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  392. "forward_zhx_IdCardpromotion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  393. "file_lfex_qtyFile":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  394. "L2910211":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  395. "forward_common_searchStkAcctBizInfoEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  396. "forward_soas_savaRisk":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  397. "forward_soas_updateChannelSMS":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  398. "forward_trade_queryUserSecuInfo":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  399. "forward_xjb_getAvailable":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  400. "forward_soas_test4":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  401. "forward_common_queryFundsFlow":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  402. "L2912021":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  403. "forward_soas_savaBatchMessage":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  404. "L2934006":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  405. "L2912032":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  406. "forward_common_searchStkAcctBizInfoToEx":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  407. "forward_trade_bankSecurityTransOut-aa":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  408. "forward_otc_queryProductProportion":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  409. "L2912003":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  410. "forward_trade_queryMaxShareQty":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"},  
  411. "forward_account_queryGZTrdacct":{"comSign":"SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS"}  
  412. }  

 

 

apiMapping.lua

 

[plain] view plain copy
 
  1. apiMapping={};  
  2.   
  3. apiMapping.mappingJsonFile=SCRIPT_ROOT_PATH.."scripts/luas/modules/apimapping/apiMapping.json";  
  4.   
  5. function apiMapping.init()  
  6.     --local cjson = require "cjson";  
  7.     local apiMappingShared = ngx.shared.apiMappingShared;  
  8.     local redisSwitchShared = ngx.shared.redisSwitchShared;  
  9.     local file = io.open(apiMapping.mappingJsonFile, "r");  
  10.     local ret,pcallBack=pcall(parseJson,file:read("*all"));  
  11.     file:close();  
  12.     if ret then  
  13.         apiMappingShared:flush_all();  
  14.         for name, value in pairs(pcallBack) do  
  15.             --ngx.log(ngx.CRIT,"name:"..name.."||".."value:"..cjson.encode(value));  
  16.             apiMappingShared:set(name, cjson.encode(value));  
  17.         end  
  18.     else  
  19.         ngx.log(ngx.ERR,"init method,JSON PARSE apiMapping.json error.");  
  20.     end  
  21.     redisSwitchShared:set("redisSwitch",true);  
  22.   
  23. end  
  24.   
  25. function parseJson(jsonString)  
  26.     if jsonString then  
  27.         --local cjson = require "cjson"  
  28.         --parse json  
  29.         local data= cjson.decode(jsonString);  
  30.         --ngx.say(data["appId"])  
  31.         return data;  
  32.     else  
  33.         return nil;  
  34.     end  
  35. end  
  36.   
  37. function httpPostParamReaderByReloadApiMapping()--专门为apiMapping.reloadApiMapping()所用  
  38.     -- read post data  
  39.     --server中使用lua_need_request_body on; 或者在location lua代码块中使用 ngx.req.read_body(),日志中能获取$request_body  
  40.     ngx.req.read_body()  
  41.     local data = ngx.req.get_body_data()  
  42.     local postData = nil;  
  43.     local ret,backData=pcall(parseJson,data);  
  44.     if ret then  
  45.         postData = backData;  
  46.     else  
  47.         ngx.log(ngx.ERR,"reloadApiMapping JSON PARSE apiMapping post json data error.");  
  48.     end  
  49.     return postData;  
  50. end  
  51.   
  52. function copyfile(source,destination)  
  53.     sourcefile = io.open(source,"r")  
  54.     destinationfile = io.open(destination,"w")  
  55.     for line in sourcefile:lines() do  
  56.         destinationfile:write(line)  
  57.     end  
  58.     sourcefile:close()  
  59.     destinationfile:close()  
  60. end  
  61.   
  62. function printCaptureResult(code)  
  63.     local responseBody =ngx.location.capture("/httpStatusRewrite?apiRespCodeParam="..code);  
  64.     ngx.say(responseBody['body'])  
  65.     ngx.exit(ngx.HTTP_OK)  
  66.     --ngx.say(msg)  
  67. end  
  68.   
  69. function routeLocation(apiSign)  
  70.     --local responseBody =ngx.location.capture("/springboot/"..apiSign);      
  71.     local responseBody =ngx.location.capture("/springboot?cacheKey="..apiSign);  
  72.     --ngx.log(ngx.ERR,"this is routeLocation:"..apiSign);  
  73.     --ngx.log(ngx.ERR,"the responseBody.status is :"..responseBody.status);  
  74.     --ngx.log(ngx.ERR,"the responseBody.body is :"..responseBody.body);  
  75.     return responseBody.body  
  76. end  
  77.   
  78. function getRedisClusterCompSign(apiSign)  
  79.     local redis_cluster = require "resty.rediscluster";  
  80.     local red = redis_cluster:new(ngx.shared.redisClusterConfig);  
  81.     --local KEY_NAME = "OPENAPI_NGINX_ROUTE_NODE_LAN";--内网  
  82.     --local KEY_NAME = "OPENAPI_NGINX_ROUTE_NODE_WAN";--外网  
  83.     --local res = red:init_pipeline()  
  84.     --ngx.log(ngx.ERR,"config.redis_keepalive_timeout is :"..red.config.keepalive_timeout)  
  85.     --ngx.log(ngx.ERR,"apiSign is :"..apiSign)  
  86.     --ngx.log(ngx.ERR,"KEY_NAME is :"..KEY_NAME)  
  87.     --red:set("forward_sbtpsboa_queryIPOsSecuInfo", "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")  
  88.     --red:set(apiSign, "SBTPS-OPF-AIO-WEB-SF-AUTH-APP-ITS")  
  89.     --local results, err = red:get("forward_sbtpsboa_queryIPOsSecuInfo")  
  90.     --local results, err = red:get(apiSign)  
  91.     local results, err = red:hget(networkSign,apiSign)--networkSign在init.lua中定义  
  92.     --red:close()  
  93.     --local results, err = red:commit_pipeline()  
  94.     --local cjson = require "cjson"  
  95.     --ngx.log(ngx.ERR,"result is :"..cjson.encode(results))  
  96.     if not results then  
  97.         ngx.log(ngx.ERR,"failed to get apiSign: "..err)  
  98.         return  
  99.     end  
  100.     if type(results) == "userdata" then--redis get nil  
  101.         return nil  
  102.     end  
  103.     --ngx.log(ngx.ERR,"results is :"..results);  
  104.     return results  
  105.       
  106. end  
  107.   
  108. function apiMapping.setRedisSwitch()  
  109.     local args = ngx.req.get_uri_args()  
  110.     local redisSwitchShared = ngx.shared.redisSwitchShared;  
  111.     local requestArgs = {};  
  112.     for key, value in pairs(args) do  
  113.         if type(value) == "table" then  
  114.             --ngx.log(ngx.ERR,"key:"..key.."value:"..value)  
  115.             ngx.say(key, ": ", table.concat(value, ", "))  
  116.             requestArgs[key] = table.concat(value, ", ")  
  117.         else    
  118.             requestArgs[key] = value  
  119.             --ngx.log(ngx.ERR,"key:"..key.."value:"..value)  
  120.             ngx.say(key, ": ", value)    
  121.         end    
  122.     end  
  123.     --ngx.log(ngx.ERR,"requestArgs:"..cjson.encode(requestArgs))  
  124.     if next(requestArgs) ~= nil then  
  125.         for key, value in pairs(requestArgs) do  
  126.             if key == "flag" then  
  127.                 redisSwitchShared:set("redisSwitch",value);  
  128.             end  
  129.         end  
  130.     end  
  131. end  
  132.   
  133. function apiMapping.reloadApiMapping()  
  134.     --local postBody = httpPostParamReader();  
  135.     local postBody = httpPostParamReaderByReloadApiMapping();  
  136.     if postBody then  
  137.         local apiMappingShared = ngx.shared.apiMappingShared  
  138.   
  139.         local confJson = {};  
  140.         for apiSign, compSign in pairs(postBody) do  
  141.             --ngx.say(table2str(mapping))  
  142.             confJson[apiSign]=compSign;  
  143.             --ngx.log(ngx.CRIT,"name:"..apiSign.."||".."value:"..cjson.encode(compSign));  
  144.             apiMappingShared:set(apiSign,compSign)  
  145.         end  
  146.         ngx.log(ngx.CRIT,"confJson:"..cjson.encode(confJson));  
  147.         local bakFile=apiMapping.mappingJsonFile..".bak";  
  148.         copyfile(apiMapping.mappingJsonFile,bakFile);  
  149.         local f=io.open(apiMapping.mappingJsonFile,"w+")  
  150.         f:write("{\n");  
  151.         if next(confJson) ~=nil then  
  152.             local idx =1;  
  153.             for key, value in pairs(confJson) do  
  154.                 if idx>1 then  
  155.                     f:write(",\n");  
  156.                 end  
  157.                 f:write("\""..key.."\":"..cjson.encode(value));  
  158.                 --f:write("\""..key.."\":".."\""..value.."\"");  
  159.                 f:flush()  
  160.                 idx = idx+1;  
  161.             end  
  162.         end  
  163.         f:write("\n}");  
  164.         f:close();  
  165.           
  166.         printCaptureResult(0);  
  167.         --ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=0");  
  168.         --ngx.say("success");  
  169.     else  
  170.         printCaptureResult(-10000)  
  171.         --ngx.say("empty request data");  
  172.     end  
  173. end  
  174.   
  175. function readGetTypeParam(source)  
  176.     local nSplitArray = {}  
  177.     local head = {}  
  178.     local body = {}  
  179.     for match in (source):gmatch("(.-)" .. "&" .. "()" ) do  
  180.         local equalIdx = string.find(match,"=");  
  181.         if equalIdx then  
  182.             local paramName = string.sub(match, 1, equalIdx-1) ;  
  183.             local paramValue = string.sub(match, equalIdx+1, string.len(match)) ;  
  184.             if paramName == "requestParam" then  
  185.                 paramName = string.match(paramName,"%s*(.-)%s*$");  
  186.                 if paramValue then  
  187.                     paramValue = string.match(paramValue,"%s*(.-)%s*$");  
  188.                 end  
  189.                 print("put param :"..paramName.."|"..paramValue)  
  190.                 body[paramName] = paramValue;  
  191.             elseif paramName and  paramName ~= "requestParam" then  
  192.                 paramName = string.match(paramName,"%s*(.-)%s*$");  
  193.                 if paramValue then  
  194.                     paramValue = string.match(paramValue,"%s*(.-)%s*$");  
  195.                 end  
  196.                 head[paramName] = paramValue;  
  197.             else  
  198.                 return false,nil;  
  199.             end  
  200.         end  
  201.     end  
  202.     nSplitArray["head"] = head;  
  203.     nSplitArray["body"] = body;  
  204.     return true,nSplitArray;  
  205. end  
  206.   
  207. function decodeURI(s)  
  208.     if s ~= nil then  
  209.         return string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)  
  210.     else  
  211.         return nil  
  212.     end  
  213. end  
  214. --URL decode 转换  
  215. function escape(s)  
  216.     if s ~= nil then  
  217.         return string.gsub(s, "([^A-Za-z0-9_])", function(c) return string.format("%%%02x", string.byte(c)) end)  
  218.     else  
  219.         return nil  
  220.     end  
  221. end  
  222. --16进制转换为字符串  
  223. function hex2str(hex)  
  224.  local str = "";  
  225.  for i = 1, string.len(hex) do  
  226.      local charcode = tonumber(string.byte(hex, i, i));  
  227.      str = str .. string.format("%02X", charcode);  
  228.  end  
  229.  return str;  
  230. end  
  231.   
  232. function httpPostParamReader()  
  233.     -- read post data  
  234.     --server中使用lua_need_request_body on; 或者在location lua代码块中使用 ngx.req.read_body(),日志中能获取$request_body  
  235.     ngx.req.read_body()  
  236.     local data = ngx.req.get_body_data()  
  237.     if data == nil then   
  238.         printCaptureResult(-10000)  
  239.         --return   
  240.     end  
  241.     data  = ngx.unescape_uri(data)  
  242.     --ngx.log(ngx.CRIT,"data:"..data);  
  243.     local contentType = ngx.req.get_headers()["content-type"] ;  
  244.     local postData = nil;  
  245.     local resCode = nil;  
  246.     if contentType and string.find(contentType,"application/json") then  
  247.         --json reader  
  248.         --ngx.log(ngx.INFO,data);  
  249.         local ret,backData=pcall(parseJson,data);  
  250.         if ret then  
  251.             postData = backData;  
  252.         else  
  253.             printCaptureResult(-1006)  
  254.             --ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");  
  255.             --ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");  
  256.         end  
  257.     else  
  258.         -- array reader  
  259.         --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  
  260.   
  261.         local code,backData = readGetTypeParam(data);  
  262.         if code then  
  263.         postData = backData;  
  264.         else  
  265.             printCaptureResult(-1006)  
  266.             --ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");  
  267.             --ngx.say("{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常.\"}");  
  268.         end  
  269.     end  
  270.     return postData;  
  271. end  
  272. function endwith(str, substr)  
  273.         if str == nil or substr == nil then  
  274.             return nil, "the string or the sub-string parameter is nil"  
  275.         end  
  276.         str_tmp = string.reverse(str)  
  277.         substr_tmp = string.reverse(substr)  
  278.         if string.find(str_tmp, substr_tmp) ~= 1 then  
  279.             return false  
  280.         else  
  281.             return true  
  282.         end  
  283. end   
  284.   
  285. --切割字符串,返回字符串数组  
  286. function strSplit(delimeter, str)    
  287.     local find, sub, insert = string.find, string.sub, table.insert    
  288.     local res = {}    
  289.     local start, start_pos, end_pos = 1, 1, 1    
  290.     while true do    
  291.         start_pos, end_pos = find(str, delimeter, start, true)    
  292.         if not start_pos then    
  293.             break    
  294.         end    
  295.         insert(res, sub(str, start, start_pos - 1))    
  296.         start = end_pos + 1      
  297.     end    
  298.     insert(res, sub(str,start))    
  299.     return res    
  300. end  
  301. --desensitizeStr 备份,调用在log.lua中  
  302. function desensitizeStr(source,desensitizeKeyArray)  
  303.     for i=1,#desensitizeKeyArray do  
  304.         local regex = "(%A*)"..desensitizeKeyArray[i].."(%D*)".."(%d+)"  
  305.         local m = string.match(source, regex)  
  306.         if m then  
  307.             --source = string.gsub(source,regex,replaceStr(%5))  
  308.             source = string.gsub(source,regex,"%1"..desensitizeKeyArray[i].."%2".."***")  
  309.             --print("source:"..source)  
  310.             return source  
  311.             --break  
  312.         end  
  313.     end  
  314. end  
  315.   
  316. function apiMapping.getCompSign()  
  317.     local request_method = ngx.var.request_method  
  318.     --获取参数的值  
  319.     if "GET" == request_method then  
  320.         --ngx.header.content_type = "application/json";  
  321.         printCaptureResult(-1013)  
  322.     end  
  323.     local postBody = httpPostParamReader();  
  324.     if postBody then  
  325.         --ngx.say("ngx.var.uri:"..ngx.var.uri);  
  326.         local reqUri = ngx.var.uri;  
  327.         if endwith(reqUri,"/") then   
  328.             reqUri = string.sub(reqUri,1,string.len(reqUri)-1)  
  329.         end  
  330.         local apiSign = nil;  
  331.         if(string.find(reqUri, "/AuthApp/")==1) then   
  332.             reqUri = string.sub(reqUri,9);  
  333.             ngx.var.reSetReqUri = string.sub(ngx.var.reSetReqUri,9);  
  334.         end  
  335.         if(string.find(reqUri, "/file/")==1) then   
  336.             apiSign = string.gsub(string.sub(reqUri,7),"/","_") ;  
  337.         else   
  338.             local apiSignArr = strSplit("/",reqUri);  
  339.             if #apiSignArr > 4 then  
  340.                 --ngx.log(ngx.ERR,"apiSignArr:"..#apiSignArr.."  if apiSignArr.len >4 then not get request_body’s method");  
  341.                 apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;  
  342.             else  
  343.                 --ngx.say("apiSign:"..apiSign);  
  344.                 apiSign = string.gsub(string.sub(reqUri,10),"/","_") ;  
  345.                 local head = postBody["head"];  
  346.                 if(head ==nil) then   
  347.                     printCaptureResult(-1006)  
  348.                 end   
  349.                 local method = head["method"];  
  350.                 --ngx.say("method:"..cjson.encode(postBody));  
  351.                 if method and string.match(method,"%s*(.-)%s*$") ~= "" then  
  352.                     if not endwith(apiSign,"_"..method) then   
  353.                         apiSign = apiSign.."_" .. string.match(method,"%s*(.-)%s*$");  
  354.                     end           
  355.                 end  
  356.             end   
  357.             --ngx.log(ngx.ERR,"apiSign:"..apiSign);  
  358.             --ngx.say("apiSign:"..apiSign);  
  359.             local apiMappingConf = ngx.shared.apiMappingShared  
  360.             --local res = apiMappingConf:get(apiSign)  
  361.             --local res = routeLocation(apiSign)  
  362.             local resTable = {}  
  363.             local res = nil;  
  364.             local redisResultJson = nil;  
  365.             local localApiMappingJson = nil;  
  366.             --local localApiMappingJson = apiMappingConf:get("forward_sbtpsboa_queryIPOsOrderInfo");  
  367.             --local localApiMappingJsonComSign = cjson.decode(localApiMappingJson)["comSign"];  
  368.             --ngx.log(ngx.ERR,"localApiMappingJsonComSign.apiSign is :"..localApiMappingJsonComSign);  
  369.             --("forward_sbtpsboa_queryIPOsOrderInfo")  
  370.             --redisResultJson = getRedisClusterCompSign(apiSign);--返回一个json串  
  371.             local redisSwitch = ngx.shared.redisSwitchShared;  
  372.             local redisSwitchFlag =redisSwitch:get("redisSwitch")   
  373.             if redisSwitchFlag == "true" then  
  374.                 local ret,backData = pcall(getRedisClusterCompSign,apiSign);  
  375.                 if ret then  
  376.                     redisResultJson = backData;  
  377.                     --ngx.log(ngx.CRIT,"redisResultJson is :"..redisResultJson);  
  378.                 else  
  379.                     ngx.log(ngx.ERR,"获取redis缓存数据失败!");  
  380.                 end  
  381.             end  
  382.               
  383.             --ngx.log(ngx.CRIT,"redisResultJson is :"..redisResultJson);  
  384.             --redisResultJson = nil;--测试读取本地  
  385.             if redisResultJson ~= nil then  
  386.                 ngx.var.redisResultJson = redisResultJson;  
  387.                 --ngx.log(ngx.CRIT,"ngx.var.redisResultJson is :"..ngx.var.redisResultJson);  
  388.                 if cjson.decode(redisResultJson) ~= nil then  
  389.                     resTable = cjson.decode(redisResultJson)--返回一个json串转为table  
  390.                 else  
  391.                     ngx.log(ngx.ERR,"redis 数据格式错误! ", err)  
  392.                     return   
  393.                 end  
  394.             else--redis返回为空,做兜底操作(apiMapping.json)  
  395.                 --local openId = postBody["openId"];  
  396.                 --if openId then   
  397.                 --  apiSign = openId.."_"..apiSign.."_" .. string.match(openId,"%s*(.-)%s*$");  
  398.                 --end  
  399.                 localApiMappingJson = apiMappingConf:get(apiSign)  
  400.                 --ngx.log(ngx.ERR,"localApiMappingJson is :"..localApiMappingJson);  
  401.                 if localApiMappingJson == nil then  
  402.                     ngx.log(ngx.ERR,"undefined api sign is :"..apiSign);  
  403.                     printCaptureResult(-10201)  
  404.                 end  
  405.                 ngx.var.redisResultJson = localApiMappingJson;  
  406.                 if cjson.decode(localApiMappingJson) ~= nil then--返回一个json串转为table  
  407.                     local resTableTemp = cjson.decode(localApiMappingJson);  
  408.                     if type(resTableTemp)=="string" then  
  409.                         resTable = cjson.decode(resTableTemp)  
  410.                     end  
  411.                     if type(resTableTemp)=="table" then  
  412.                         resTable = resTableTemp  
  413.                     end  
  414.                 else  
  415.                     ngx.log(ngx.ERR,"this localApiMappingJson api sign has not set", err)  
  416.                     return  
  417.                 end  
  418.             end  
  419.             if next(resTable) ~= nil then  
  420.                 --ngx.log(ngx.INFO,"resTable.comSign is :"..resTable["comSign"])  
  421.                 res = resTable["comSign"]  
  422.             end  
  423.             --ngx.log(ngx.ERR,"apiSign is :"..apiSign);  
  424.             ngx.var.apiSign = apiSign;  
  425.             if res and res ~= nil then  
  426.                 ngx.var.comp_sign = res;  
  427.                 --ngx.say("res:"..res);  
  428.             else  
  429.                 ngx.log(ngx.ERR,"undefined api sign is :"..apiSign);  
  430.                 --ngx.say("res:"..apiSign);  
  431.                 --ngx.exit(ngx.HTTP_OK)  
  432.                 printCaptureResult(-10201)  
  433.             end   
  434.         end  
  435.     end  
  436. end  
  437.   
  438. return apiMapping;  

 

 

log.lua

 

[plain] view plain copy
 
  1. function desensitizeStr(source,desensitizeKeyArray)--string,table  
  2.     if source == nil or source == "" then  
  3.         return nil  
  4.     end  
  5.     if desensitizeKeyArray == nil or desensitizeKeyArray == "" then  
  6.         return source  
  7.     end  
  8.     for i=1,#desensitizeKeyArray do  
  9.         local regex = "(%A*)"..desensitizeKeyArray[i].."(%D*)".."(%d+)"  
  10.         local m = string.match(source, regex)  
  11.         if m then  
  12.             --source = string.gsub(source,regex,replaceStr(%5))  
  13.             source = string.gsub(source,regex,"%1"..desensitizeKeyArray[i].."%2".."***")  
  14.             --print("source:"..source)  
  15.             return source  
  16.             --break  
  17.         end  
  18.     end  
  19.     return source--执行到这里表示没有一次做string.gsub(没有一次做正则替换)  
  20. end  
  21. --ngx.log(ngx.CRIT,"request_body is :"..ngx.var.request_body)  
  22. --local source = "pwd\":\"12333123ad\"}\"apwd\":\"1233sd3123\"pwd:123321,adpwd1233fgfsdgs"  
  23.   
  24. function parseJson(jsonString)  
  25.     if jsonString then  
  26.         --local cjson = require "cjson"  
  27.         --parse json  
  28.         local data= cjson.decode(jsonString);  
  29.         --ngx.say(data["appId"])  
  30.         return data;  
  31.     else  
  32.         return nil;  
  33.     end  
  34. end  
  35.   
  36. -- 删除table中的元素    
  37. function removeElementByKey(sourceJson,key)   
  38.     if sourceJson == nil then  
  39.         return nil  
  40.     end  
  41.     if key == nil then  
  42.         return sourceJson  
  43.     end  
  44.     local tempTable = nil;  
  45.     local ret,backData=pcall(parseJson,sourceJson);  
  46.     if ret then  
  47.         tempTable = backData;  
  48.     else  
  49.         --处理请求和响应信息中的超大字段request_body&resp_body  
  50.         --ngx.log(ngx.ERR,"{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}");  
  51.         return "{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}"  
  52.     end  
  53.     if tempTable == nil then  
  54.         return nil  
  55.     end  
  56.     --新建一个临时的table    
  57.     local tmp ={}    
  58.     
  59.     --把每个key做一个下标,保存到临时的table中,转换成{1=a,2=c,3=b}     
  60.     --组成一个有顺序的table,才能在while循环准备时使用#table    
  61.     for i in pairs(tempTable) do    
  62.         table.insert(tmp,i)    
  63.     end    
  64.     
  65.     local newTbl = {}    
  66.     --使用while循环剔除不需要的元素    
  67.     local i = 1    
  68.     while i <= #tmp do    
  69.         local val = tmp [i]    
  70.         if val == key then    
  71.             --如果是需要剔除则remove     
  72.             table.remove(tmp,i)    
  73.          else    
  74.             --如果不是剔除,放入新的tabl中    
  75.             newTbl[val] = tempTable[val]    
  76.             i = i + 1    
  77.          end    
  78.      end    
  79.     return cjson.encode(newTbl)  
  80.     --return newTbl    
  81. end    
  82.   
  83. function replaceJson(jsonString,replaceKey,replaceValue)  
  84.     if jsonString == nil or jsonString == "" then  
  85.         return nil  
  86.     end  
  87.     if replaceKey == nil or replaceValue == nil then  
  88.         return jsonString  
  89.     end  
  90.     local tempTable = nil;  
  91.     local ret,backData=pcall(parseJson,jsonString);  
  92.     if ret then  
  93.         tempTable = backData;  
  94.     else  
  95.         ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");  
  96.     end  
  97.     if tempTable == nil then  
  98.         return nil  
  99.     end  
  100.     if tempTable[replaceKey] == nil then  
  101.         return jsonString  
  102.     end  
  103.     --处理请求和响应信息中的超大字段request_body&resp_body  
  104.     if ngx.var.apiSign == "forward_soas_uploadIdImg" and replaceKey == "request_body" then  
  105.         tempTable[replaceKey] = "{\"resCode\":\"-1007\",\"resMsg\":\"json转换失败或者数据量过大无法转换成json\"}"  
  106.     else  
  107.         tempTable[replaceKey] = replaceValue  
  108.     end  
  109.     return cjson.encode(tempTable)  
  110.     --return jsonString  
  111. end  
  112.   
  113. function getJsonValueToTable(jsonString,stringKey)--返回table  
  114.     if jsonString == nil or jsonString == "" then  
  115.         return nil  
  116.     end  
  117.     if stringKey == nil then  
  118.         return jsonString  
  119.     end  
  120.     local tempTable = nil;  
  121.     local ret,backData=pcall(parseJson,jsonString);  
  122.     if ret then  
  123.         tempTable = backData;  
  124.     else  
  125.         --printCaptureResult(-1006)  
  126.         --ngx.location.capture("/httpStatusRewrite?apiRespCodeParam=-1006");  
  127.         ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");  
  128.         return nil  
  129.     end  
  130.           
  131.     if type(tempTable)=="string" then  
  132.         local ret,backData=pcall(parseJson,tempTable);  
  133.         if ret then  
  134.             tempTable = backData;  
  135.         else  
  136.             ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");  
  137.             return nil  
  138.         end  
  139.     end  
  140.     if tempTable == nil then  
  141.         return nil  
  142.     end  
  143.     if tempTable[stringKey] == nil then  
  144.         return nil  
  145.     end  
  146.     if type(tempTable[stringKey]) =="string" then  
  147.         local ret,backData=pcall(parseJson,tempTable[stringKey]);  
  148.         if ret then  
  149.             return backData;  
  150.         else  
  151.             ngx.log(ngx.ERR,"{\"resCode\":\"-1006\",\"resMsg\":\"参数格式异常。\"}");  
  152.             return nil  
  153.         end  
  154.     end  
  155.     if type(tempTable[stringKey]) =="table" then  
  156.         return tempTable[stringKey]  
  157.     end  
  158. end  
  159.   
  160.   
  161. if(ngx.var.uri ~= "/metrics") then  
  162.     local host = ngx.var.host:gsub("^www.", "")  
  163.     local upstream_addr = ngx.var.upstream_addr  
  164.     if(upstream_addr == nil or upstream_addr == "") then  
  165.         upstream_addr = "localhost"  
  166.     end  
  167.     metric_requests:inc(1, {host, upstream_addr, ngx.var.status})  
  168.     metric_latency:observe(ngx.now() - ngx.req.start_time(), {upstream_addr})  
  169.     metric_bytes:observe(tonumber(ngx.var.bytes_sent)/1024,{upstream_addr})  
  170. end  
  171.   
  172. local source = ngx.unescape_uri(ngx.var.request_body)--获取到request_body的字符串  
  173. --local responseSrc = ngx.var.resp_body--获取到resp_body的字符串  
  174. local responseDesc = removeElementByKey(ngx.var.resp_body,"resBody")  
  175. --ngx.log(ngx.CRIT,"responseDesc is :"..responseDesc)  
  176. --ngx.log(ngx.CRIT,"redisResultJson is :"..ngx.var.redisResultJson)  
  177. local desensitizeKeyArray = getJsonValueToTable(ngx.var.redisResultJson,"desensitizeKeyArray")--获取到desensitizeKeyArray的table  
  178. source = desensitizeStr(source,desensitizeKeyArray)--替换后的request_body字符串  
  179. --ngx.log(ngx.CRIT,"source is :"..source)  
  180. --ngx.log(ngx.CRIT,"before replace resp_map is :"..ngx.var.resp_map)  
  181. ngx.var.resp_map = replaceJson(ngx.var.resp_map,"request_body",source)  
  182. ngx.var.resp_map = replaceJson(ngx.var.resp_map,"resp_body",responseDesc)  
  183. --ngx.log(ngx.CRIT,"after replace resp_map is :"..ngx.var.resp_map)  
  184. ngx.log(ngx.CRIT,"resp_map is :"..ngx.var.resp_map)  

 

 

prometheus.lua

 

[plain] view plain copy
 
  1. -- vim: ts=2:sw=2:sts=2:expandtab  
  2. --  
  3. -- This module uses a single dictionary shared between Nginx workers to keep  
  4. -- all metrics. Each counter is stored as a separate entry in that dictionary,  
  5. -- which allows us to increment them using built-in `incr` method.  
  6. --  
  7. -- Prometheus requires that (a) all samples for a given metric are presented  
  8. -- as one uninterrupted group, and (b) buckets of a histogram appear in  
  9. -- increasing numerical order. We satisfy that by carefully constructing full  
  10. -- metric names (i.e. metric name along with all labels) so that they meet  
  11. -- those requirements while being sorted alphabetically. In particular:  
  12. --  
  13. --  * all labels for a given metric are presented in reproducible order (the one  
  14. --    used when labels were declared). "le" label for histogram metrics always  
  15. --    goes last;  
  16. --  * bucket boundaries (which are exposed as values of the "le" label) are  
  17. --    presented as floating point numbers with leading and trailing zeroes.  
  18. --    Number of of zeroes is determined for each bucketer automatically based on  
  19. --    bucket boundaries;  
  20. --  * internally "+Inf" bucket is stored as "Inf" (to make it appear after  
  21. --    all numeric buckets), and gets replaced by "+Inf" just before we  
  22. --    expose the metrics.  
  23. --  
  24. -- For example, if you define your bucket boundaries as {0.00005, 10, 1000}  
  25. -- then we will keep the following samples for a metric `m1` with label  
  26. -- `site` set to `site1`:  
  27. --  
  28. --   m1_bucket{site="site1",le="0000.00005"}  
  29. --   m1_bucket{site="site1",le="0010.00000"}  
  30. --   m1_bucket{site="site1",le="1000.00000"}  
  31. --   m1_bucket{site="site1",le="Inf"}  
  32. --   m1_count{site="site1"}  
  33. --   m1_sum{site="site1"}  
  34. --  
  35. -- "Inf" will be replaced by "+Inf" while publishing metrics.  
  36. --  
  37. -- You can find the latest version and documentation at  
  38. -- https://github.com/knyar/nginx-lua-prometheus  
  39. -- Released under MIT license.  
  40.   
  41.   
  42. -- Default set of latency buckets, 5ms to 10s:  
  43. local DEFAULT_BUCKETS = {0.005, 0.01, 0.02, 0.03, 0.05, 0.075, 0.1, 0.2, 0.3,  
  44.                          0.4, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 10}  
  45.   
  46. -- Metric is a "parent class" for all metrics.  
  47. local Metric = {}  
  48. function Metric:new(o)  
  49.   o = o or {}  
  50.   setmetatable(o, self)  
  51.   self.__index = self  
  52.   return o  
  53. end  
  54.   
  55. -- Checks that the right number of labels values have been passed.  
  56. --  
  57. -- Args:  
  58. --   label_values: an array of label values.  
  59. --  
  60. -- Returns:  
  61. --   an error message or nil  
  62. function Metric:check_label_values(label_values)  
  63.   if self.label_names == nil and label_values == nil then  
  64.     return  
  65.   elseif self.label_names == nil and label_values ~= nil then  
  66.     return "Expected no labels for " .. self.name .. ", got " ..  #label_values  
  67.   elseif label_values == nil and self.label_names ~= nil then  
  68.     return "Expected " .. #self.label_names .. " labels for " ..  
  69.            self.name .. ", got none"  
  70.   elseif #self.label_names ~= #label_values then  
  71.     return "Wrong number of labels for " .. self.name .. ". Expected " ..  
  72.            #self.label_names .. ", got " .. #label_values  
  73.   else  
  74.     for i, k in ipairs(self.label_names) do  
  75.       if label_values[i] == nil then  
  76.         return "Unexpected nil value for label " .. k ..  " of " .. self.name  
  77.       end  
  78.     end  
  79.   end  
  80. end  
  81.   
  82. local Counter = Metric:new()  
  83. -- Increase a given counter by `value`  
  84. --  
  85. -- Args:  
  86. --   value: (number) a value to add to the counter. Defaults to 1 if skipped.  
  87. --   label_values: an array of label values. Can be nil (i.e. not defined) for  
  88. --     metrics that have no labels.  
  89. function Counter:inc(value, label_values)  
  90.   local err = self:check_label_values(label_values)  
  91.   if err ~= nil then  
  92.     self.prometheus:log_error(err)  
  93.     return  
  94.   end  
  95.   self.prometheus:inc(self.name, self.label_names, label_values, value or 1)  
  96. end  
  97.   
  98. local Gauge = Metric:new()  
  99. -- Set a given gauge to `value`  
  100. --  
  101. -- Args:  
  102. --   value: (number) a value to set the gauge to. Should be defined.  
  103. --   label_values: an array of label values. Can be nil (i.e. not defined) for  
  104. --     metrics that have no labels.  
  105. function Gauge:set(value, label_values)  
  106.   if value == nil then  
  107.     self.prometheus:log_error("No value passed for " .. self.name)  
  108.     return  
  109.   end  
  110.   local err = self:check_label_values(label_values)  
  111.   if err ~= nil then  
  112.     self.prometheus:log_error(err)  
  113.     return  
  114.   end  
  115.   self.prometheus:set(self.name, self.label_names, label_values, value)  
  116. end  
  117.   
  118. local Histogram = Metric:new()  
  119. -- Record a given value in a histogram.  
  120. --  
  121. -- Args:  
  122. --   value: (number) a value to record. Should be defined.  
  123. --   label_values: an array of label values. Can be nil (i.e. not defined) for  
  124. --     metrics that have no labels.  
  125. function Histogram:observe(value, label_values)  
  126.   if value == nil then  
  127.     self.prometheus:log_error("No value passed for " .. self.name)  
  128.     return  
  129.   end  
  130.   local err = self:check_label_values(label_values)  
  131.   if err ~= nil then  
  132.     self.prometheus:log_error(err)  
  133.     return  
  134.   end  
  135.   self.prometheus:histogram_observe(self.name, self.label_names, label_values, value)  
  136. end  
  137.   
  138. local Prometheus = {}  
  139. Prometheus.__index = Prometheus  
  140. Prometheus.initialized = false  
  141.   
  142. -- Generate full metric name that includes all labels.  
  143. --  
  144. -- Args:  
  145. --   name: string  
  146. --   label_names: (array) a list of label keys.  
  147. --   label_values: (array) a list of label values.  
  148. -- Returns:  
  149. --   (string) full metric name.  
  150. local function full_metric_name(name, label_names, label_values)  
  151.   if not label_names then  
  152.     return name  
  153.   end  
  154.   local label_parts = {}  
  155.   for idx, key in ipairs(label_names) do  
  156.     local label_value = (string.format("%s", label_values[idx])  
  157.       :gsub("[^\032-\126]", "")  -- strip non-printable characters  
  158.       :gsub("\\", "\\\\")  
  159.       :gsub('"', '\\"'))  
  160.     table.insert(label_parts, key .. '="' .. label_value .. '"')  
  161.   end  
  162.   return name .. "{" .. table.concat(label_parts, ",") .. "}"  
  163. end  
  164.   
  165. -- Construct bucket format for a list of buckets.  
  166. --  
  167. -- This receives a list of buckets and returns a sprintf template that should  
  168. -- be used for bucket boundaries to make them come in increasing order when  
  169. -- sorted alphabetically.  
  170. --  
  171. -- To re-phrase, this is where we detect how many leading and trailing zeros we  
  172. -- need.  
  173. --  
  174. -- Args:  
  175. --   buckets: a list of buckets  
  176. --  
  177. -- Returns:  
  178. --   (string) a sprintf template.  
  179. local function construct_bucket_format(buckets)  
  180.   local max_order = 1  
  181.   local max_precision = 1  
  182.   for _, bucket in ipairs(buckets) do  
  183.     assert(type(bucket) == "number", "bucket boundaries should be numeric")  
  184.     -- floating point number with all trailing zeros removed  
  185.     local as_string = string.format("%f", bucket):gsub("0*$", "")  
  186.     local dot_idx = as_string:find(".", 1, true)  
  187.     max_order = math.max(max_order, dot_idx - 1)  
  188.     max_precision = math.max(max_precision, as_string:len() - dot_idx)  
  189.   end  
  190.   return "%0" .. (max_order + max_precision + 1) .. "." .. max_precision .. "f"  
  191. end  
  192.   
  193. -- Extract short metric name from the full one.  
  194. --  
  195. -- Args:  
  196. --   full_name: (string) full metric name that can include labels.  
  197. --  
  198. -- Returns:  
  199. --   (string) short metric name with no labels. For a `*_bucket` metric of  
  200. --     histogram the _bucket suffix will be removed.  
  201. local function short_metric_name(full_name)  
  202.   local labels_start, _ = full_name:find("{")  
  203.   if not labels_start then  
  204.     -- no labels  
  205.     return full_name  
  206.   end  
  207.   local suffix_idx, _ = full_name:find("_bucket{")  
  208.   if suffix_idx and full_name:find("le=") then  
  209.     -- this is a histogram metric  
  210.     return full_name:sub(1, suffix_idx - 1)  
  211.   end  
  212.   -- this is not a histogram metric  
  213.   return full_name:sub(1, labels_start - 1)  
  214. end  
  215.   
  216. -- Makes a shallow copy of a table  
  217. local function copy_table(table)  
  218.   local new = {}  
  219.   if table ~= nil then  
  220.     for k, v in ipairs(table) do  
  221.       new[k] = v  
  222.     end  
  223.   end  
  224.   return new  
  225. end  
  226.   
  227. -- Check metric name and label names for correctness.  
  228. --  
  229. -- Regular expressions to validate metric and label names are  
  230. -- documented in https://prometheus.io/docs/concepts/data_model/  
  231. --  
  232. -- Args:  
  233. --   metric_name: (string) metric name.  
  234. --   label_names: label names (array of strings).  
  235. --  
  236. -- Returns:  
  237. --   Either an error string, or nil of no errors were found.  
  238. local function check_metric_and_label_names(metric_name, label_names)  
  239.   if not metric_name:match("^[a-zA-Z_:][a-zA-Z0-9_:]*$") then  
  240.     return "Metric name '" .. metric_name ..  
  241.            "' contains invalid characters"  
  242.   end  
  243.   for _, label_name in ipairs(label_names or {}) do  
  244.     if label_name == "le" then  
  245.       return "Invalid label name 'le' in " .. metric_name  
  246.     end  
  247.     if not label_name:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then  
  248.       return "Metric '" .. metric_name .. "' label name '" .. label_name ..  
  249.              "' contains invalid characters"  
  250.     end  
  251.   end  
  252. end  
  253.   
  254. -- Initialize the module.  
  255. --  
  256. -- This should be called once from the `init_by_lua` section in nginx  
  257. -- configuration.  
  258. --  
  259. -- Args:  
  260. --   dict_name: (string) name of the nginx shared dictionary which will be  
  261. --     used to store all metrics  
  262. --   prefix: (optional string) if supplied, prefix is added to all  
  263. --   metric names on output  
  264. --  
  265. -- Returns:  
  266. --   an object that should be used to register metrics.  
  267. function Prometheus.init(dict_name, prefix)  
  268.   local self = setmetatable({}, Prometheus)  
  269.   self.dict = ngx.shared[dict_name or "prometheus_metrics"]  
  270.   self.help = {}  
  271.   if prefix then  
  272.     self.prefix = prefix  
  273.   else  
  274.     self.prefix = ''  
  275.   end  
  276.   self.type = {}  
  277.   self.registered = {}  
  278.   self.buckets = {}  
  279.   self.bucket_format = {}  
  280.   self.initialized = true  
  281.   
  282.   self:counter("nginx_metric_errors_total",  
  283.     "Number of nginx-lua-prometheus errors")  
  284.   self.dict:set("nginx_metric_errors_total", 0)  
  285.   return self  
  286. end  
  287.   
  288. function Prometheus:log_error(...)  
  289.   ngx.log(ngx.ERR, ...)  
  290.   self.dict:incr("nginx_metric_errors_total", 1)  
  291. end  
  292.   
  293. function Prometheus:log_error_kv(key, value, err)  
  294.   self:log_error(  
  295.     "Error while setting '", key, "' to '", value, "': '", err, "'")  
  296. end  
  297.   
  298. -- Register a counter.  
  299. --  
  300. -- Args:  
  301. --   name: (string) name of the metric. Required.  
  302. --   description: (string) description of the metric. Will be used for the HELP  
  303. --     comment on the metrics page. Optional.  
  304. --   label_names: array of strings, defining a list of metrics. Optional.  
  305. --  
  306. -- Returns:  
  307. --   a Counter object.  
  308. function Prometheus:counter(name, description, label_names)  
  309.   if not self.initialized then  
  310.     ngx.log(ngx.ERR, "Prometheus module has not been initialized")  
  311.     return  
  312.   end  
  313.   
  314.   local err = check_metric_and_label_names(name, label_names)  
  315.   if err ~= nil then  
  316.     self:log_error(err)  
  317.     return  
  318.   end  
  319.   
  320.   if self.registered[name] then  
  321.     self:log_error("Duplicate metric " .. name)  
  322.     return  
  323.   end  
  324.   self.registered[name] = true  
  325.   self.help[name] = description  
  326.   self.type[name] = "counter"  
  327.   
  328.   return Counter:new{name=name, label_names=label_names, prometheus=self}  
  329. end  
  330.   
  331. -- Register a gauge.  
  332. --  
  333. -- Args:  
  334. --   name: (string) name of the metric. Required.  
  335. --   description: (string) description of the metric. Will be used for the HELP  
  336. --     comment on the metrics page. Optional.  
  337. --   label_names: array of strings, defining a list of metrics. Optional.  
  338. --  
  339. -- Returns:  
  340. --   a Gauge object.  
  341. function Prometheus:gauge(name, description, label_names)  
  342.   if not self.initialized then  
  343.     ngx.log(ngx.ERR, "Prometheus module has not been initialized")  
  344.     return  
  345.   end  
  346.   
  347.   local err = check_metric_and_label_names(name, label_names)  
  348.   if err ~= nil then  
  349.     self:log_error(err)  
  350.     return  
  351.   end  
  352.   
  353.   if self.registered[name] then  
  354.     self:log_error("Duplicate metric " .. name)  
  355.     return  
  356.   end  
  357.   self.registered[name] = true  
  358.   self.help[name] = description  
  359.   self.type[name] = "gauge"  
  360.   
  361.   return Gauge:new{name=name, label_names=label_names, prometheus=self}  
  362. end  
  363.   
  364.   
  365. -- Register a histogram.  
  366. --  
  367. -- Args:  
  368. --   name: (string) name of the metric. Required.  
  369. --   description: (string) description of the metric. Will be used for the HELP  
  370. --     comment on the metrics page. Optional.  
  371. --   label_names: array of strings, defining a list of metrics. Optional.  
  372. --   buckets: array if numbers, defining bucket boundaries. Optional.  
  373. --  
  374. -- Returns:  
  375. --   a Histogram object.  
  376. function Prometheus:histogram(name, description, label_names, buckets)  
  377.   if not self.initialized then  
  378.     ngx.log(ngx.ERR, "Prometheus module has not been initialized")  
  379.     return  
  380.   end  
  381.   
  382.   local err = check_metric_and_label_names(name, label_names)  
  383.   if err ~= nil then  
  384.     self:log_error(err)  
  385.     return  
  386.   end  
  387.   
  388.   for _, suffix in ipairs({"", "_bucket", "_count", "_sum"}) do  
  389.     if self.registered[name .. suffix] then  
  390.       self:log_error("Duplicate metric " .. name .. suffix)  
  391.       return  
  392.     end  
  393.     self.registered[name .. suffix] = true  
  394.   end  
  395.   self.help[name] = description  
  396.   self.type[name] = "histogram"  
  397.   
  398.   self.buckets[name] = buckets or DEFAULT_BUCKETS  
  399.   self.bucket_format[name] = construct_bucket_format(self.buckets[name])  
  400.   
  401.   return Histogram:new{name=name, label_names=label_names, prometheus=self}  
  402. end  
  403.   
  404. -- Set a given dictionary key.  
  405. -- This overwrites existing values, so it should only be used when initializing  
  406. -- metrics or when explicitely overwriting the previous value of a metric.  
  407. function Prometheus:set_key(key, value)  
  408.   local ok, err = self.dict:safe_set(key, value)  
  409.   if not ok then  
  410.     self:log_error_kv(key, value, err)  
  411.   end  
  412. end  
  413.   
  414. -- Increment a given counter by `value`.  
  415. --  
  416. -- Args:  
  417. --   name: (string) short metric name without any labels.  
  418. --   label_names: (array) a list of label keys.  
  419. --   label_values: (array) a list of label values.  
  420. --   value: (number) value to add. Optional, defaults to 1.  
  421. function Prometheus:inc(name, label_names, label_values, value)  
  422.   local key = full_metric_name(name, label_names, label_values)  
  423.   if value == nil then value = 1 end  
  424.   if value < 0 then  
  425.     self:log_error_kv(key, value, "Value should not be negative")  
  426.     return  
  427.   end  
  428.   
  429.   local newval, err = self.dict:incr(key, value)  
  430.   if newval then  
  431.     return  
  432.   end  
  433.   -- Yes, this looks like a race, so I guess we might under-report some values  
  434.   -- when multiple workers simultaneously try to create the same metric.  
  435.   -- Hopefully this does not happen too often (shared dictionary does not get  
  436.   -- reset during configuation reload).  
  437.   if err == "not found" then  
  438.     self:set_key(key, value)  
  439.     return  
  440.   end  
  441.   -- Unexpected error  
  442.   self:log_error_kv(key, value, err)  
  443. end  
  444.   
  445. -- Set the current value of a gauge to `value`  
  446. --  
  447. -- Args:  
  448. --   name: (string) short metric name without any labels.  
  449. --   label_names: (array) a list of label keys.  
  450. --   label_values: (array) a list of label values.  
  451. --   value: (number) the new value for the gauge.  
  452. function Prometheus:set(name, label_names, label_values, value)  
  453.   local key = full_metric_name(name, label_names, label_values)  
  454.   self:set_key(key, value)  
  455. end  
  456.   
  457. -- Record a given value into a histogram metric.  
  458. --  
  459. -- Args:  
  460. --   name: (string) short metric name without any labels.  
  461. --   label_names: (array) a list of label keys.  
  462. --   label_values: (array) a list of label values.  
  463. --   value: (number) value to observe.  
  464. function Prometheus:histogram_observe(name, label_names, label_values, value)  
  465.   self:inc(name .. "_count", label_names, label_values, 1)  
  466.   self:inc(name .. "_sum", label_names, label_values, value)  
  467.   
  468.   -- we are going to mutate arrays of label names and values, so create a copy.  
  469.   local l_names = copy_table(label_names)  
  470.   local l_values = copy_table(label_values)  
  471.   
  472.   -- Last bucket. Note, that the label value is "Inf" rather than "+Inf"  
  473.   -- required by Prometheus. This is necessary for this bucket to be the last  
  474.   -- one when all metrics are lexicographically sorted. "Inf" will get replaced  
  475.   -- by "+Inf" in Prometheus:collect().  
  476.   table.insert(l_names, "le")  
  477.   table.insert(l_values, "Inf")  
  478.   self:inc(name .. "_bucket", l_names, l_values, 1)  
  479.   
  480.   local label_count = #l_names  
  481.   for _, bucket in ipairs(self.buckets[name]) do  
  482.     if value <= bucket then  
  483.       -- last label is now "le"  
  484.       l_values[label_count] = self.bucket_format[name]:format(bucket)  
  485.       self:inc(name .. "_bucket", l_names, l_values, 1)  
  486.     end  
  487.   end  
  488. end  
  489.   
  490. -- Present all metrics in a text format compatible with Prometheus.  
  491. --  
  492. -- This function should be used to expose the metrics on a separate HTTP page.  
  493. -- It will get the metrics from the dictionary, sort them, and expose them  
  494. -- aling with TYPE and HELP comments.  
  495. function Prometheus:collect()  
  496.   ngx.header.content_type = "text/plain"  
  497.   if not self.initialized then  
  498.     ngx.log(ngx.ERR, "Prometheus module has not been initialized")  
  499.     return  
  500.   end  
  501.   
  502.   local keys = self.dict:get_keys(0)  
  503.   -- Prometheus server expects buckets of a histogram to appear in increasing  
  504.   -- numerical order of their label values.  
  505.   table.sort(keys)  
  506.   
  507.   local seen_metrics = {}  
  508.   for _, key in ipairs(keys) do  
  509.     local value, err = self.dict:get(key)  
  510.     if value then  
  511.       local short_name = short_metric_name(key)  
  512.       if not seen_metrics[short_name] then  
  513.         if self.help[short_name] then  
  514.           ngx.say("# HELP " .. self.prefix .. short_name .. " " .. self.help[short_name])  
  515.         end  
  516.         if self.type[short_name] then  
  517.           ngx.say("# TYPE " .. self.prefix .. short_name .. " " .. self.type[short_name])  
  518.         end  
  519.         seen_metrics[short_name] = true  
  520.       end  
  521.       -- Replace "Inf" with "+Inf" in each metric's last bucket 'le' label.  
  522.       ngx.say(self.prefix .. key:gsub('le="Inf"', 'le="+Inf"'), " ", value)  
  523.     else  
  524.       self:log_error("Error getting '", key, "': ", err)  
  525.     end  
  526.   end  
  527. end  
  528.   
  529. return Prometheus  

 

 

request.lua

 

[plain] view plain copy
 
  1. local resp_body = string.sub(ngx.arg[1], 1, 1000)  
  2. ngx.ctx.buffered = (ngx.ctx.buffered or"") .. resp_body  
  3. if ngx.arg[2] then  
  4.     ngx.var.resp_body = ngx.ctx.buffered  
  5.       
  6.     local map = {}  
  7.     map["logTraceId"] = ngx.var.request_id;  
  8.     map["remote_addr"] = ngx.var.remote_addr;  
  9.     map["remote_user"] = ngx.var.remote_user;  
  10.   
  11.     map["time_local"] = ngx.unescape_uri(ngx.var.time_local);  
  12.     map["request_method"] = ngx.var.request_method;  
  13.     map["apiSign"] = ngx.var.apiSign;  
  14.     map["comp_sign"] = ngx.var.comp_sign;  
  15.     map["request"] = ngx.unescape_uri(ngx.var.request);  
  16.   
  17.     map["status"] = ngx.var.status;  
  18.     map["body_bytes_sent"] = ngx.var.body_bytes_sent;  
  19.     map["http_referer"] = ngx.var.http_referer;  
  20.     map["http_user_agent"] = ngx.var.http_user_agent;  
  21.     map["http_x_forwarded_for"] = ngx.var.http_x_forwarded_for;  
  22.   
  23.     map["request_body"] = ngx.unescape_uri(ngx.var.request_body);  
  24.   
  25.     map["resp_body"] = ngx.unescape_uri(ngx.var.resp_body);  
  26.   
  27.     map["upstream_addr"] = ngx.var.upstream_addr;  
  28.     map["bytes_sent"] = ngx.var.bytes_sent;  
  29.     map["request_length"] = ngx.var.request_length;  
  30.     map["upstream_response_time"] = ngx.var.upstream_response_time;  
  31.     map["request_time"] = ngx.var.request_time;  
  32.     ngx.var.resp_map = cjson.encode(map);  
  33. end  

 

 

rediscluster.lua

 

[plain] view plain copy
 
  1. local ffi = require 'ffi'  
  2.   
  3.   
  4. local ffi_new = ffi.new  
  5. local C = ffi.C  
  6. local crc32 = ngx.crc32_short  
  7. local setmetatable = setmetatable  
  8. local floor = math.floor  
  9. local pairs = pairs  
  10. local tostring = tostring  
  11. local tonumber = tonumber  
  12.   
  13.   
  14. ffi.cdef[[  
  15. int lua_redis_crc16(char *key, int keylen);  
  16. ]]  
  17.   
  18.   
  19. local ok, new_tab = pcall(require, "table.new")  
  20. if not ok or type(new_tab) ~= "function" then  
  21.     new_tab = function (narr, nrec) return {} end  
  22. end  
  23.   
  24.   
  25. --  
  26. -- Find shared object file package.cpath, obviating the need of setting  
  27. -- LD_LIBRARY_PATH  
  28. -- Or we should add a little patch for ffi.load ?  
  29. --  
  30. local function load_shared_lib(so_name)  
  31.     local string_gmatch = string.gmatch  
  32.     local string_match = string.match  
  33.     local io_open = io.open  
  34.     local io_close = io.close  
  35.   
  36.     local cpath = package.cpath  
  37.   
  38.     for k, _ in string_gmatch(cpath, "[^;]+") do  
  39.         local fpath = string_match(k, "(.*/)")  
  40.         fpath = fpath .. so_name  
  41.   
  42.         -- Don't get me wrong, the only way to know if a file exist is trying  
  43.         -- to open it.  
  44.         local f = io_open(fpath)  
  45.         if f ~= nil then  
  46.             io_close(f)  
  47.             return ffi.load(fpath)  
  48.         end  
  49.     end  
  50. end  
  51.   
  52.   
  53. local _M = {}  
  54. local mt = { __index = _M }  
  55.   
  56.   
  57. local clib = load_shared_lib("libredis_slot.so")  
  58. if not clib then  
  59.     error("can not load libredis_slot.so")  
  60. end  
  61.   
  62. local function redis_slot(str)  
  63.     return clib.lua_redis_crc16(ffi.cast("char *", str), #str)  
  64. end  
  65.   
  66. local function ip_string(ip)  
  67.     if ip:match(":") then  
  68.         return "[" .. ip .. "]"  
  69.     end  
  70.   
  71.     return ip  
  72. end  
  73.   
  74. local redis = require "resty.redis"  
  75.   
  76. redis.add_commands("cluster")  
  77. local commands = {  
  78.     "append",            --[["auth",]]        --[["bgrewriteaof",]]  
  79.     --[["bgsave",]]      --[["blpop",]]    --[["brpop",]]  
  80.     --[["brpoplpush",]]  --[["config", ]]   --[["dbsize",]]  
  81.     --[["debug", ]]      "decr",              "decrby",  
  82.     --[["del",]]         --[["discard",           "echo",]]  
  83.     --[["eval",]]              "exec",              "exists",  
  84.     --[["expire",            "expireat",          "flushall",  
  85.     "flushdb",]]           "get",               "getbit",  
  86.     "getrange",          "getset",            "hdel",  
  87.     "hexists",           "hget",              "hgetall",  
  88.     "hincrby",           "hkeys",             "hlen",  
  89.     "hmget",             "hmset",             "hset",  
  90.     "hsetnx",            "hvals",             "incr",  
  91.     "incrby",           --[["info",]]         --[["keys",]]  
  92.     --[["lastsave", ]]  "lindex",            "linsert",  
  93.     "llen",              "lpop",              "lpush",  
  94.     "lpushx",            "lrange",            "lrem",  
  95.     "lset",              "ltrim",             "mget",  
  96.     "monitor",           --[["move",]]        "mset",  
  97.     "msetnx",            --[[["multi",]]      --[["object",]]  
  98.     --[["persist",]]     --[["ping",]]        --[["psubscribe",]]  
  99.    --[[ "publish",           "punsubscribe",      "quit",]]  
  100.     --[["randomkey",         "rename",            "renamenx",]]  
  101.     "rpop",              --[["rpoplpush",]]   "rpush",  
  102.     "rpushx",            "sadd",              --[["save",]]  
  103.     "scard",             --[["script",]]  
  104.     --[["sdiff",             "sdiffstore",]]  
  105.     --[["select",]]            "set",               "setbit",  
  106.     "setex",             "setnx",             "setrange",  
  107.     --[["shutdown",          "sinter",            "sinterstore",  
  108.     "sismember",         "slaveof",           "slowlog",]]  
  109.     "smembers",          "smove",             "sort",  
  110.     "spop",              "srandmember",       "srem",  
  111.     "strlen",            --[["subscribe",]]         "sunion",  
  112.     "sunionstore",       --[["sync",]]              "ttl",  
  113.     "type",              --[["unsubscribe",]]       --[["unwatch",  
  114.     "watch",]]             "zadd",              "zcard",  
  115.     "zcount",            "zincrby",           "zinterstore",  
  116.     "zrange",            "zrangebyscore",     "zrank",  
  117.     "zrem",              "zremrangebyrank",   "zremrangebyscore",  
  118.     "zrevrange",         "zrevrangebyscore",  "zrevrank",  
  119.     "zscore",            --[["zunionstore",    "evalsha"]]  
  120. }  
  121.   
  122. local _M = {}  
  123. local mt = { __index = _M }  
  124.   
  125. local slot_cache = {}  
  126. --local slot_state = {}  
  127. --local WAIT = 0  
  128. --local FIN = 1  
  129.   
  130.   
  131. function _M.fetch_slots(self)  
  132.     local serv_list = self.config.serv_list  
  133.     local red = redis:new()  
  134.     for i=1,#serv_list do  
  135.         local ip = serv_list[i].ip  
  136.         local port = serv_list[i].port  
  137.         local ok, err = red:connect(ip_string(ip), port)  
  138.         if ok then  
  139.             local slot_info, err = red:cluster("slots")  
  140.             if slot_info then  
  141.                 local slots = {}  
  142.                 for i=1,#slot_info do  
  143.                     local item = slot_info[i]  
  144.                     for slot = item[1],item[2] do  
  145.                         local list = {serv_list={}, cur = 1}  
  146.                        for j = 3,#item do  
  147.                             list.serv_list[#list.serv_list + 1] = {ip = item[j][1], port = item[j][2]}  
  148.                             slots[slot] = list  
  149.                         end  
  150.                     end  
  151.                 end  
  152.                 slot_cache[self.config.name] = slots  
  153.                 --self.slots = slots  
  154.                 --debug_log("fetch_slots", self)  
  155.             end  
  156.         end  
  157.     end  
  158. end  
  159.   
  160.   
  161.   
  162. function _M.init_slots(self)  
  163.     if slot_cache[self.config.name] then  
  164.         return  
  165.     end  
  166.     self:fetch_slots()  
  167. end  
  168.   
  169. function _M.new(self, config)  
  170.     local inst = {}  
  171.     inst.config = config  
  172.     inst = setmetatable(inst, mt)  
  173.     inst:init_slots()  
  174.     return inst  
  175. end  
  176.   
  177. function _M.close(self)  
  178.   
  179. end  
  180.   
  181. local function next_index(cur, size)  
  182.     cur = cur + 1  
  183.     if cur > size then  
  184.         cur = 1  
  185.     end  
  186.     return cur  
  187. end  
  188.   
  189. local MAGIC_TRY = 3  
  190. local DEFUALT_KEEPALIVE_TIMEOUT = 1000  
  191. local DEFAULT_KEEPALIVE_CONS = 200  
  192.   
  193. local function _do_cmd(self, cmd, key, ...)  
  194.     if self._reqs then  
  195.         local args = {...}  
  196.         local t = {cmd = cmd, key=key, args=args}  
  197.         table.insert(self._reqs, t)  
  198.         return  
  199.     end  
  200.     local config = self.config  
  201.   
  202.     key = tostring(key)  
  203.     local slot = redis_slot(key)  
  204.   
  205.     for k=1, MAGIC_TRY do  
  206.         local slots = slot_cache[self.config.name]  
  207.         local serv_list = slots[slot].serv_list  
  208.         local index =slots[slot].cur  
  209.         for i=1,#serv_list do  
  210.             local ip = serv_list[index].ip  
  211.             local port = serv_list[index].port  
  212.             local redis_client = redis:new()  
  213.             local ok, err = redis_client:connect(ip_string(ip), port)  
  214.             if ok then  
  215.                 slots[slot].cur = index  
  216.                 local res, err = redis_client[cmd](redis_client, key, ...)  
  217.                 redis_client:set_keepalive(config.keepalive_timeout or DEFUALT_KEEPALIVE_TIMEOUT,  
  218.                                            config.keepalove_cons or DEFAULT_KEEPALIVE_CONS)  
  219.                 if err and string.sub(err, 1, 5) == "MOVED" then  
  220.                     self:fetch_slots()  
  221.                     break  
  222.                 end  
  223.                 return res, err  
  224.             else  
  225.                 index = next_index(index, #serv_list)  
  226.             end  
  227.         end  
  228.     end  
  229.     return nil, "oops! please contact cuiweixie"  
  230. end  
  231.   
  232. for i = 1, #commands do  
  233.     local cmd = commands[i]  
  234.   
  235.     _M[cmd] =  
  236.         function (self, ...)  
  237.             return _do_cmd(self, cmd, ...)  
  238.         end  
  239. end  
  240.   
  241. function _M.init_pipeline(self)  
  242.     self._reqs = {}  
  243. end  
  244.   
  245. local INTIT = 0  
  246. local FIND = 1  
  247. local FIN  = 2  
  248. function _M.commit_pipeline(self)  
  249.     if not self._reqs or #self._reqs == 0 then return end  
  250.     local reqs = self._reqs  
  251.     self._reqs = nil  
  252.     local config = self.config  
  253.     local slots = slot_cache[config.name]  
  254.     local map_ret = {}  
  255.     local map = {}  
  256.     for i=1,#reqs do  
  257.         reqs[i].origin_index = i  
  258.         local key = reqs[i].key  
  259.         local slot = redis_slot(tostring(key))  
  260.         local slot_item = slots[slot]  
  261.         local ip = slot_item.serv_list[slot_item.cur].ip  
  262.         local port = slot_item.serv_list[slot_item.cur].port  
  263.         local inst_key = ip..tostring(port)  
  264.         if not map[inst_key] then  
  265.             map[inst_key] = {ip=ip,port=port,reqs={}}  
  266.             map_ret[inst_key] = {}  
  267.         end  
  268.         local ins_req = map[inst_key].reqs  
  269.         ins_req[#ins_req+1] = reqs[i]  
  270.     end  
  271.     for k, v in pairs(map) do  
  272.         local ip = v.ip  
  273.         local port = v.port  
  274.         local ins_reqs = v.reqs  
  275.         local ins = redis:new()  
  276.         local ok, err = ins:connect(ip_string(ip), port)  
  277.   
  278.         if ok then  
  279.             ins:init_pipeline()  
  280.             for i=1,#ins_reqs do  
  281.                 local req = ins_reqs[i]  
  282.                 if #req.args > 0 then  
  283.                     ins[req.cmd](ins, req.key, unpack(req.args))  
  284.                 else  
  285.                     ins[req.cmd](ins, req.key)  
  286.                 end  
  287.             end  
  288.             local res, err = ins:commit_pipeline()  
  289.             ins:set_keepalive(config.keepalive_timeout or DEFUALT_KEEPALIVE_TIMEOUT,  
  290.                                            config.keepalove_cons or DEFAULT_KEEPALIVE_CONS)  
  291.             if err then  
  292.                 return nil, err.." return from "..tostring(ip)..":"..tostring(port)  
  293.             end  
  294.             map_ret[k] = res  
  295.         else  
  296.             return nil, "commit failed while connecting to "..tostring(ip)..":"..tostring(port)  
  297.         end  
  298.     end  
  299.     local ret = {}  
  300.     for k,v in pairs(map_ret) do  
  301.         local ins_reqs = map[k].reqs  
  302.         local res = v  
  303.         for i=1,#ins_reqs do  
  304.             ret[ins_reqs[i].origin_index] =res[i]  
  305.         end  
  306.     end  
  307.     return ret  
  308. end  
  309.   
  310. function _M.cancel_pipeline(self)  
  311.     self._reqs = nil  
  312. end  
  313.   
  314. return _M  

 

 

redis.lua

 

[plain] view plain copy
 
  1. -- Copyright (C) Yichun Zhang (agentzh)  
  2.   
  3.   
  4. local sub = string.sub  
  5. local byte = string.byte  
  6. local tcp = ngx.socket.tcp  
  7. local null = ngx.null  
  8. local type = type  
  9. local pairs = pairs  
  10. local unpack = unpack  
  11. local setmetatable = setmetatable  
  12. local tonumber = tonumber  
  13. local tostring = tostring  
  14. local rawget = rawget  
  15. --local error = error  
  16.   
  17.   
  18. local ok, new_tab = pcall(require, "table.new")  
  19. if not ok or type(new_tab) ~= "function" then  
  20.     new_tab = function (narr, nrec) return {} end  
  21. end  
  22.   
  23.   
  24. local _M = new_tab(0, 54)  
  25.   
  26. _M._VERSION = '0.26'  
  27.   
  28.   
  29. local common_cmds = {  
  30.     "get",      "set",          "mget",     "mset",  
  31.     "del",      "incr",         "decr",                 -- Strings  
  32.     "llen",     "lindex",       "lpop",     "lpush",  
  33.     "lrange",   "linsert",                              -- Lists  
  34.     "hexists",  "hget",         "hset",     "hmget",  
  35.     --[[ "hmset", ]]            "hdel",                 -- Hashes  
  36.     "smembers", "sismember",    "sadd",     "srem",  
  37.     "sdiff",    "sinter",       "sunion",               -- Sets  
  38.     "zrange",   "zrangebyscore", "zrank",   "zadd",  
  39.     "zrem",     "zincrby",                              -- Sorted Sets  
  40.     "auth",     "eval",         "expire",   "script",  
  41.     "sort"                                              -- Others  
  42. }  
  43.   
  44.   
  45. local sub_commands = {  
  46.     "subscribe", "psubscribe"  
  47. }  
  48.   
  49.   
  50. local unsub_commands = {  
  51.     "unsubscribe", "punsubscribe"  
  52. }  
  53.   
  54.   
  55. local mt = { __index = _M }  
  56.   
  57.   
  58. function _M.new(self)  
  59.     local sock, err = tcp()  
  60.     if not sock then  
  61.         return nil, err  
  62.     end  
  63.     return setmetatable({ _sock = sock, _subscribed = false }, mt)  
  64. end  
  65.   
  66.   
  67. function _M.set_timeout(self, timeout)  
  68.     local sock = rawget(self, "_sock")  
  69.     if not sock then  
  70.         return nil, "not initialized"  
  71.     end  
  72.   
  73.     return sock:settimeout(timeout)  
  74. end  
  75.   
  76.   
  77. function _M.connect(self, ...)  
  78.     local sock = rawget(self, "_sock")  
  79.     if not sock then  
  80.         return nil, "not initialized"  
  81.     end  
  82.   
  83.     self._subscribed = false  
  84.   
  85.     return sock:connect(...)  
  86. end  
  87.   
  88.   
  89. function _M.set_keepalive(self, ...)  
  90.     local sock = rawget(self, "_sock")  
  91.     if not sock then  
  92.         return nil, "not initialized"  
  93.     end  
  94.   
  95.     if rawget(self, "_subscribed") then  
  96.         return nil, "subscribed state"  
  97.     end  
  98.   
  99.     return sock:setkeepalive(...)  
  100. end  
  101.   
  102.   
  103. function _M.get_reused_times(self)  
  104.     local sock = rawget(self, "_sock")  
  105.     if not sock then  
  106.         return nil, "not initialized"  
  107.     end  
  108.   
  109.     return sock:getreusedtimes()  
  110. end  
  111.   
  112.   
  113. local function close(self)  
  114.     local sock = rawget(self, "_sock")  
  115.     if not sock then  
  116.         return nil, "not initialized"  
  117.     end  
  118.   
  119.     return sock:close()  
  120. end  
  121. _M.close = close  
  122.   
  123.   
  124. local function _read_reply(self, sock)  
  125.     local line, err = sock:receive()  
  126.     if not line then  
  127.         if err == "timeout" and not rawget(self, "_subscribed") then  
  128.             sock:close()  
  129.         end  
  130.         return nil, err  
  131.     end  
  132.   
  133.     local prefix = byte(line)  
  134.   
  135.     if prefix == 36 then    -- char '$'  
  136.         -- print("bulk reply")  
  137.   
  138.         local size = tonumber(sub(line, 2))  
  139.         if size < 0 then  
  140.             return null  
  141.         end  
  142.   
  143.         local data, err = sock:receive(size)  
  144.         if not data then  
  145.             if err == "timeout" then  
  146.                 sock:close()  
  147.             end  
  148.             return nil, err  
  149.         end  
  150.   
  151.         local dummy, err = sock:receive(2) -- ignore CRLF  
  152.         if not dummy then  
  153.             return nil, err  
  154.         end  
  155.   
  156.         return data  
  157.   
  158.     elseif prefix == 43 then    -- char '+'  
  159.         -- print("status reply")  
  160.   
  161.         return sub(line, 2)  
  162.   
  163.     elseif prefix == 42 then -- char '*'  
  164.         local n = tonumber(sub(line, 2))  
  165.   
  166.         -- print("multi-bulk reply: ", n)  
  167.         if n < 0 then  
  168.             return null  
  169.         end  
  170.   
  171.         local vals = new_tab(n, 0)  
  172.         local nvals = 0  
  173.         for i = 1, n do  
  174.             local res, err = _read_reply(self, sock)  
  175.             if res then  
  176.                 nvals = nvals + 1  
  177.                 vals[nvals] = res  
  178.   
  179.             elseif res == nil then  
  180.                 return nil, err  
  181.   
  182.             else  
  183.                 -- be a valid redis error value  
  184.                 nvals = nvals + 1  
  185.                 vals[nvals] = {false, err}  
  186.             end  
  187.         end  
  188.   
  189.         return vals  
  190.   
  191.     elseif prefix == 58 then    -- char ':'  
  192.         -- print("integer reply")  
  193.         return tonumber(sub(line, 2))  
  194.   
  195.     elseif prefix == 45 then    -- char '-'  
  196.         -- print("error reply: ", n)  
  197.   
  198.         return false, sub(line, 2)  
  199.   
  200.     else  
  201.         -- when `line` is an empty string, `prefix` will be equal to nil.  
  202.         return nil, "unkown prefix: \"" .. tostring(prefix) .. "\""  
  203.     end  
  204. end  
  205.   
  206.   
  207. local function _gen_req(args)  
  208.     local nargs = #args  
  209.   
  210.     local req = new_tab(nargs * 5 + 1, 0)  
  211.     req[1] = "*" .. nargs .. "\r\n"  
  212.     local nbits = 2  
  213.   
  214.     for i = 1, nargs do  
  215.         local arg = args[i]  
  216.         if type(arg) ~= "string" then  
  217.             arg = tostring(arg)  
  218.         end  
  219.   
  220.         req[nbits] = "$"  
  221.         req[nbits + 1] = #arg  
  222.         req[nbits + 2] = "\r\n"  
  223.         req[nbits + 3] = arg  
  224.         req[nbits + 4] = "\r\n"  
  225.   
  226.         nbits = nbits + 5  
  227.     end  
  228.   
  229.     -- it is much faster to do string concatenation on the C land  
  230.     -- in real world (large number of strings in the Lua VM)  
  231.     return req  
  232. end  
  233.   
  234.   
  235. local function _do_cmd(self, ...)  
  236.     local args = {...}  
  237.   
  238.     local sock = rawget(self, "_sock")  
  239.     if not sock then  
  240.         return nil, "not initialized"  
  241.     end  
  242.   
  243.     local req = _gen_req(args)  
  244.   
  245.     local reqs = rawget(self, "_reqs")  
  246.     if reqs then  
  247.         reqs[#reqs + 1] = req  
  248.         return  
  249.     end  
  250.   
  251.     -- print("request: ", table.concat(req))  
  252.   
  253.     local bytes, err = sock:send(req)  
  254.     if not bytes then  
  255.         return nil, err  
  256.     end  
  257.   
  258.     return _read_reply(self, sock)  
  259. end  
  260.   
  261.   
  262. local function _check_subscribed(self, res)  
  263.     if type(res) == "table"  
  264.        and (res[1] == "unsubscribe" or res[1] == "punsubscribe")  
  265.        and res[3] == 0  
  266.    then  
  267.         self._subscribed = false  
  268.     end  
  269. end  
  270.   
  271.   
  272. function _M.read_reply(self)  
  273.     local sock = rawget(self, "_sock")  
  274.     if not sock then  
  275.         return nil, "not initialized"  
  276.     end  
  277.   
  278.     if not rawget(self, "_subscribed") then  
  279.         return nil, "not subscribed"  
  280.     end  
  281.   
  282.     local res, err = _read_reply(self, sock)  
  283.     _check_subscribed(self, res)  
  284.   
  285.     return res, err  
  286. end  
  287.   
  288.   
  289. for i = 1, #common_cmds do  
  290.     local cmd = common_cmds[i]  
  291.   
  292.     _M[cmd] =  
  293.         function (self, ...)  
  294.             return _do_cmd(self, cmd, ...)  
  295.         end  
  296. end  
  297.   
  298.   
  299. for i = 1, #sub_commands do  
  300.     local cmd = sub_commands[i]  
  301.   
  302.     _M[cmd] =  
  303.         function (self, ...)  
  304.             self._subscribed = true  
  305.             return _do_cmd(self, cmd, ...)  
  306.         end  
  307. end  
  308.   
  309.   
  310. for i = 1, #unsub_commands do  
  311.     local cmd = unsub_commands[i]  
  312.   
  313.     _M[cmd] =  
  314.         function (self, ...)  
  315.             local res, err = _do_cmd(self, cmd, ...)  
  316.             _check_subscribed(self, res)  
  317.             return res, err  
  318.         end  
  319. end  
  320.   
  321.   
  322. function _M.hmset(self, hashname, ...)  
  323.     if select('#', ...) == 1 then  
  324.         local t = select(1, ...)  
  325.   
  326.         local n = 0  
  327.         for k, v in pairs(t) do  
  328.             n = n + 2  
  329.         end  
  330.   
  331.         local array = new_tab(n, 0)  
  332.   
  333.         local i = 0  
  334.         for k, v in pairs(t) do  
  335.             array[i + 1] = k  
  336.             array[i + 2] = v  
  337.             i = i + 2  
  338.         end  
  339.         -- print("key", hashname)  
  340.         return _do_cmd(self, "hmset", hashname, unpack(array))  
  341.     end  
  342.   
  343.     -- backwards compatibility  
  344.     return _do_cmd(self, "hmset", hashname, ...)  
  345. end  
  346.   
  347.   
  348. function _M.init_pipeline(self, n)  
  349.     self._reqs = new_tab(n or 4, 0)  
  350. end  
  351.   
  352.   
  353. function _M.cancel_pipeline(self)  
  354.     self._reqs = nil  
  355. end  
  356.   
  357.   
  358. function _M.commit_pipeline(self)  
  359.     local reqs = rawget(self, "_reqs")  
  360.     if not reqs then  
  361.         return nil, "no pipeline"  
  362.     end  
  363.   
  364.     self._reqs = nil  
  365.   
  366.     local sock = rawget(self, "_sock")  
  367.     if not sock then  
  368.         return nil, "not initialized"  
  369.     end  
  370.   
  371.     local bytes, err = sock:send(reqs)  
  372.     if not bytes then  
  373.         return nil, err  
  374.     end  
  375.   
  376.     local nvals = 0  
  377.     local nreqs = #reqs  
  378.     local vals = new_tab(nreqs, 0)  
  379.     for i = 1, nreqs do  
  380.         local res, err = _read_reply(self, sock)  
  381.         if res then  
  382.             nvals = nvals + 1  
  383.             vals[nvals] = res  
  384.   
  385.         elseif res == nil then  
  386.             if err == "timeout" then  
  387.                 close(self)  
  388.             end  
  389.             return nil, err  
  390.   
  391.         else  
  392.             -- be a valid redis error value  
  393.             nvals = nvals + 1  
  394.             vals[nvals] = {false, err}  
  395.         end  
  396.     end  
  397.   
  398.     return vals  
  399. end  
  400.   
  401.   
  402. function _M.array_to_hash(self, t)  
  403.     local n = #t  
  404.     -- print("n = ", n)  
  405.     local h = new_tab(0, n / 2)  
  406.     for i = 1, n, 2 do  
  407.         h[t[i]] = t[i + 1]  
  408.     end  
  409.     return h  
  410. end  
  411.   
  412.   
  413. -- this method is deperate since we already do lazy method generation.  
  414. function _M.add_commands(...)  
  415.     local cmds = {...}  
  416.     for i = 1, #cmds do  
  417.         local cmd = cmds[i]  
  418.         _M[cmd] =  
  419.             function (self, ...)  
  420.                 return _do_cmd(self, cmd, ...)  
  421.             end  
  422.     end  
  423. end  
  424.   
  425.   
  426. setmetatable(_M, {__index = function(self, cmd)  
  427.     local method =  
  428.         function (self, ...)  
  429.             return _do_cmd(self, cmd, ...)  
  430.         end  
  431.   
  432.     -- cache the lazily generated method in our  
  433.     -- module table  
  434.     _M[cmd] = method  
  435.     return method  
  436. end})  
  437.   
  438.   
  439. return _M  

 

http://blog.csdn.net/deng_xintao/article/details/75441992

发表评论

0/200
309 点赞
0 评论
收藏