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

时间:2022-03-16 04:10:42

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

直接上文件

nginx.conf

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

sbtps-opf-sfweb-nginx.com

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

server-http-error-page.err

  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. location /httpStatusRewrite{
  6. default_type    "text/plain";
  7. set $apiRespCode  $arg_apiRespCodeParam;
  8. if ( $apiRespMsg = '' ) {
  9. return 200 '{"resCode":"-1","resMsg":"请求失败"}';
  10. }
  11. return 200 '{"resCode":"$apiRespCode","resMsg":"$apiRespMsg"}';
  12. }

respCodeMap.map

  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

  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. apiMapping.init()
  20. redisClusterConfig()
  21. end
  22. function initLuaModule(rootPath)
  23. local rootPath=SCRIPT_ROOT_PATH..'scripts/luas/';
  24. getpathes(rootPath, nil);
  25. end
  26. function getpathes(rootpath, pathes)
  27. pathes = pathes or {}
  28. local attr = lfs.attributes(rootpath)
  29. if attr and attr.mode == 'directory' then
  30. package.path = string.format("%s?.lua;%s", rootpath, package.path)
  31. for entry in lfs.dir(rootpath) do
  32. if entry ~= '.' and entry ~= '..' then
  33. getpathes(rootpath  ..  entry.. '/', pathes)
  34. end
  35. end
  36. end
  37. return pathes
  38. end
  39. function redisClusterConfig()
  40. local config = {
  41. name="openapi",
  42. serv_list = {
  43. {ip="10.25.174.28", port = 6001},
  44. {ip="10.25.174.28", port = 6002},
  45. {ip="10.25.174.28", port = 6003},
  46. {ip="10.25.174.28", port = 7001},
  47. {ip="10.25.174.28", port = 7002},
  48. {ip="10.25.174.28", port = 7003},
  49. {ip="10.25.174.28", port = 6001},
  50. {ip="10.25.174.28", port = 6002},
  51. },
  52. keepalive_timeout = 200,
  53. keepalove_cons = 20
  54. }
  55. ngx.shared.redisClusterConfig = config;
  56. networkSign = "OPENAPI_NGINX_ROUTE_NODE_LAN";--内网
  57. --networkSign = "OPENAPI_NGINX_ROUTE_NODE_WAN";--外网
  58. end
  59. init();

apiMapping.json

  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

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

log.lua

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

prometheus.lua

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

request.lua

  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. local map = {}
  6. map["logTraceId"] = ngx.var.request_id;
  7. map["remote_addr"] = ngx.var.remote_addr;
  8. map["remote_user"] = ngx.var.remote_user;
  9. map["time_local"] = ngx.unescape_uri(ngx.var.time_local);
  10. map["request_method"] = ngx.var.request_method;
  11. map["apiSign"] = ngx.var.apiSign;
  12. map["comp_sign"] = ngx.var.comp_sign;
  13. map["request"] = ngx.unescape_uri(ngx.var.request);
  14. map["status"] = ngx.var.status;
  15. map["body_bytes_sent"] = ngx.var.body_bytes_sent;
  16. map["http_referer"] = ngx.var.http_referer;
  17. map["http_user_agent"] = ngx.var.http_user_agent;
  18. map["http_x_forwarded_for"] = ngx.var.http_x_forwarded_for;
  19. map["request_body"] = ngx.unescape_uri(ngx.var.request_body);
  20. map["resp_body"] = ngx.unescape_uri(ngx.var.resp_body);
  21. map["upstream_addr"] = ngx.var.upstream_addr;
  22. map["bytes_sent"] = ngx.var.bytes_sent;
  23. map["request_length"] = ngx.var.request_length;
  24. map["upstream_response_time"] = ngx.var.upstream_response_time;
  25. map["request_time"] = ngx.var.request_time;
  26. ngx.var.resp_map = cjson.encode(map);
  27. end

rediscluster.lua

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

redis.lua

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

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