Authored by 毕凯

Merge branch 'feature/req' into 'master'

Feature/req



See merge request !671
@@ -16,9 +16,14 @@ exports.submit = (req, res) => { @@ -16,9 +16,14 @@ exports.submit = (req, res) => {
16 16
17 remoteIp = arr[0]; 17 remoteIp = arr[0];
18 } 18 }
19 - let key = `pc:limiter:${remoteIp}`;  
20 19
21 - cache.delAsync(key).then(() => { 20 + let key = `h5:limiter:${remoteIp}`;
  21 + let key10m = `h5:limiter:10m:${remoteIp}`;
  22 +
  23 + Promise.all([
  24 + cache.delAsync(key),
  25 + cache.delAsync(key10m)
  26 + ]).then(() => {
22 return res.json({ 27 return res.json({
23 code: 200 28 code: 200
24 }); 29 });
@@ -99,6 +99,7 @@ module.exports = { @@ -99,6 +99,7 @@ module.exports = {
99 notifyUrl: domains.service + 'payment/weixin_notify', 99 notifyUrl: domains.service + 'payment/weixin_notify',
100 }, 100 },
101 maxQps: 1200, 101 maxQps: 1200,
  102 + maxQps10m: 2500,
102 geetestJs: '//static.geetest.com/static/tools/gt.js', 103 geetestJs: '//static.geetest.com/static/tools/gt.js',
103 jsSdk: '//cdn.yoho.cn/js-sdk/1.2.2/jssdk.js', 104 jsSdk: '//cdn.yoho.cn/js-sdk/1.2.2/jssdk.js',
104 redis: { 105 redis: {
@@ -5,12 +5,13 @@ const _ = require('lodash'); @@ -5,12 +5,13 @@ const _ = require('lodash');
5 5
6 const WHITE_LIST = [ 6 const WHITE_LIST = [
7 '/3party/check', 7 '/3party/check',
  8 + '/3party/check/submit',
8 '/passport/imagesNode', 9 '/passport/imagesNode',
9 '/passport/cert/headerTip', 10 '/passport/cert/headerTip',
10 '/passport/captcha/get', 11 '/passport/captcha/get',
11 '/passport/images', 12 '/passport/images',
12 '/passport/img-check.jpg', 13 '/passport/img-check.jpg',
13 - '/3party/check/submit' 14 + '/passport/geetest/register'
14 ]; 15 ];
15 16
16 module.exports = (req, res, next) => { 17 module.exports = (req, res, next) => {
@@ -5,11 +5,14 @@ const cache = global.yoho.cache.master; @@ -5,11 +5,14 @@ const cache = global.yoho.cache.master;
5 const config = global.yoho.config; 5 const config = global.yoho.config;
6 const ONE_DAY = 60 * 60 * 24; 6 const ONE_DAY = 60 * 60 * 24;
7 const MAX_QPS = config.maxQps; 7 const MAX_QPS = config.maxQps;
  8 +const MAX_QPS_10m = config.maxQps10m;
8 const _ = require('lodash'); 9 const _ = require('lodash');
9 10
10 const PAGES = { 11 const PAGES = {
11 - '/product/\\/pro_([\\d]+)_([\\d]+)\\/(.*)/': 5,  
12 - '/product/list/index': 5 12 + '/product/^\\/(\\d+)\\.html/': 5,
  13 + '/product/list/index': 5,
  14 + '/product/index/index': 5,
  15 + '/product/search/list': 5
13 }; 16 };
14 17
15 function urlJoin(a, b) { 18 function urlJoin(a, b) {
@@ -26,7 +29,8 @@ module.exports = (limiter, policy) => { @@ -26,7 +29,8 @@ module.exports = (limiter, policy) => {
26 const req = limiter.req, 29 const req = limiter.req,
27 res = limiter.res; 30 res = limiter.res;
28 31
29 - const key = `pc:limiter:${limiter.remoteIp}`; 32 + const key = `h5:limiter:${limiter.remoteIp}`;
  33 + const key10m = `h5:limiter:10m:${limiter.remoteIp}`;
30 34
31 res.on('render', function() { 35 res.on('render', function() {
32 let route = req.route ? req.route.path : ''; 36 let route = req.route ? req.route.path : '';
@@ -39,37 +43,55 @@ module.exports = (limiter, policy) => { @@ -39,37 +43,55 @@ module.exports = (limiter, policy) => {
39 let pageKey = urlJoin(appPath, route.toString()); // route may be a regexp 43 let pageKey = urlJoin(appPath, route.toString()); // route may be a regexp
40 let pageIncr = PAGES[pageKey] || 0; 44 let pageIncr = PAGES[pageKey] || 0;
41 45
42 - if (/^\/p([\d]+)/.test(req.path)) {  
43 - pageIncr = 5;  
44 - }  
45 -  
46 if (pageIncr > 0) { 46 if (pageIncr > 0) {
47 - cache.incrAsync(key, pageIncr, () => {}); 47 + cache.incrAsync(key, pageIncr);
  48 + cache.incrAsync(key10m, pageIncr);
48 } 49 }
49 }); 50 });
50 51
51 - return cache.getAsync(key).then((result) => { 52 + return cache.getMultiAsync([key, key10m]).then((results) => {
  53 + let result = results[key];
  54 + let result10m = results[key10m];
  55 +
52 logger.debug('qps limiter: ' + key + '@' + result + ' max: ' + MAX_QPS); 56 logger.debug('qps limiter: ' + key + '@' + result + ' max: ' + MAX_QPS);
  57 + logger.debug('qps limiter 10m: ' + key10m + '@' + result10m + ' max: ' + MAX_QPS_10m);
  58 +
  59 + // 默认数据设置
  60 + if (!result && !_.isNumber(result)) {
  61 + cache.setAsync(key, 1, 60); // 设置key,1m失效
  62 + }
53 63
54 - if (result && _.isNumber(result)) { 64 + if (!result10m && !_.isNumber(result10m)) {
  65 + cache.setAsync(key10m, 1, 600); // 设置key,10m失效
  66 + }
  67 +
  68 + // 第一次访问,都没计数,直接过
  69 + if (!result && !_.isNumber(result) && !result10m && !_.isNumber(result10m)) {
  70 + return Promise.resolve(true);
  71 + }
55 72
56 - if (result === -1) { 73 + if (result === -1 || result10m === -1) {
57 return Promise.resolve(true); 74 return Promise.resolve(true);
58 } 75 }
59 76
60 - if (result > MAX_QPS) { // 判断 qps 77 + // 判断 qps 10分钟
  78 + if (result10m > MAX_QPS_10m) {
  79 + cache.touch(key10m, ONE_DAY);
  80 + logger.debug('req limit', key10m);
  81 +
  82 + return Promise.resolve(policy);
  83 + }
  84 +
  85 + // 判断 qps 1分钟
  86 + if (result > MAX_QPS) {
61 cache.touch(key, ONE_DAY); 87 cache.touch(key, ONE_DAY);
62 logger.debug('req limit', key); 88 logger.debug('req limit', key);
63 89
64 return Promise.resolve(policy); 90 return Promise.resolve(policy);
65 - } else {  
66 - cache.incrAsync(key, 1); // qps + 1  
67 - return Promise.resolve(true);  
68 -  
69 } 91 }
70 - } else {  
71 - cache.setAsync(key, 1, 60); // 设置key,1m失效 92 +
  93 + cache.incrAsync(key, 1); // qps + 1
  94 + cache.incrAsync(key10m, 1); // qps + 1
72 return Promise.resolve(true); 95 return Promise.resolve(true);
73 - }  
74 }); 96 });
75 }; 97 };