直接上文件

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

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

  1. .net core MVC 通过 Filters 过滤器拦截请求及响应内容

    前提: 需要nuget   Microsoft.Extensions.Logging.Log4Net.AspNetCore   2.2.6: Swashbuckle.AspNetCore 我暂时用的是 ...

  2. Spring Boot使用AOP在控制台打印请求、响应信息

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等. AOP简介 AOP全称Aspect Oriented Programming,面向切面,AOP主要实现的 ...

  3. springboot+aop切点记录请求和响应信息

    本篇主要分享的是springboot中结合aop方式来记录请求参数和响应的数据信息:这里主要讲解两种切入点方式,一种方法切入,一种注解切入:首先创建个springboot测试工程并通过maven添加如 ...

  4. 第14.14节 爬虫实战准备:csdn博文点赞过程http请求和响应信息分析

    如果要对csdn博文点赞,首先要登录CSDN,然后打开一篇需要点赞的文章,如<第14.1节 通过Python爬取网页的学习步骤>按<第14.3节 使用google浏览器获取网站访问的 ...

  5. 使用RestTemplate,显示请求信息,响应信息

    使用RestTemplate,显示请求信息,响应信息 这里不讲怎么用RestTemplate具体细节用法,就是一个学习中的过程记录 一个简单的例子 public class App { public ...

  6. VUE 数据请求和响应(axios)

    1. 概述 1.1 简介 axios是一个基于Promise(本机支持ES6 Promise实现) 的HTTP库,用于浏览器和 nodejs 的 HTTP 客户端.具有以下特征: 从浏览器中创建 XM ...

  7. Java Servlet (1) —— Filter过滤请求与响应

    Java Servlet (1) -- Filter过滤请求与响应 版本: Java EE 6 参考来源: Oracle:The Java EE 6 Tutorial: Filtering Reque ...

  8. Fiddler如何自动修改请求和响应包

    Charles的Map功能可以将某个请求进行重定向,用重定向的内容响应请求的内容.这个功能非常方便.在抓包过程当中,有时候为了调试方便,需要将线上的服务定位到内网.比如我们线上的服务器域名为 api. ...

  9. openresty+lua劫持请求,有点意思

    0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了一些邪恶的东西:反代既然是所有流量走我的服务器,那我是不是能够在中途做些手脚,达到一些有趣的目的. op ...

随机推荐

  1. 00002 - echo命令详解

    用于字符串的输出 格式 echo string 使用echo实现更复杂的输出格式控制 1.显示普通字符串: echo "It is a test" 这里的双引号完全可以省略,以下命 ...

  2. Find the peace with yourself

    The purpose of being mature is to find the real calm and peace with yourself. Or you can say the tur ...

  3. dict函数

    增 fromkeys(iterable, value) 用可迭代对象生成键,创建默认值相同的字典(value默认None) 删 pop(k) 通过k来删除字典元素, 找不到就会报错, 返回被删除字典元 ...

  4. U3D学习004——核心类和代码运行

    1.U3D核心类 2.变量 只有public变量才可以显示在inspector面板中,[serializeField]可以使private和protected变量显示在inspector面板中. 3. ...

  5. CS229 7.1应用机器学习中的一些技巧

    本文所讲述的是怎么样去在实践中更好的应用机器学习算法,比如如下经验风险最小化问题: 当求解最优的  后,发现他的预测误差非常之大,接下来如何处理来使得当前的误差尽可能的小呢?这里给出以下几个选项,下面 ...

  6. 升级cordova

    node -v npm -vcordova -v npm install npm -g --force npm install -g n --force n stable npm install -g ...

  7. three.js学习:三维空间下的直线

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  8. web中的集群与分布式

    面试中经常会提到 集群 和 分布式.下面就来分别说说这两个在web开发中经常用到的开发方式. 集群: 集群是一组协同工作的服务实体,用以提供比单一服务实体更具扩展性与可用性的服务平台.在客户端看来,一 ...

  9. [转]asp+oracle分页

    PageSize:每页显示的记录数.PageCount:根据用户设定好的PageSize和表中的总记录数,系统自动算出总页数.RecordCount:表中的总记录数.AbsolutePage:表示当前 ...

  10. Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息

    </pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...