Authored by 毕凯

Merge branch 'feature/req' into 'master'

Feature/req



See merge request !671
... ... @@ -16,9 +16,14 @@ exports.submit = (req, res) => {
remoteIp = arr[0];
}
let key = `pc:limiter:${remoteIp}`;
cache.delAsync(key).then(() => {
let key = `h5:limiter:${remoteIp}`;
let key10m = `h5:limiter:10m:${remoteIp}`;
Promise.all([
cache.delAsync(key),
cache.delAsync(key10m)
]).then(() => {
return res.json({
code: 200
});
... ...
... ... @@ -99,6 +99,7 @@ module.exports = {
notifyUrl: domains.service + 'payment/weixin_notify',
},
maxQps: 1200,
maxQps10m: 2500,
geetestJs: '//static.geetest.com/static/tools/gt.js',
jsSdk: '//cdn.yoho.cn/js-sdk/1.2.2/jssdk.js',
redis: {
... ...
... ... @@ -5,12 +5,13 @@ const _ = require('lodash');
const WHITE_LIST = [
'/3party/check',
'/3party/check/submit',
'/passport/imagesNode',
'/passport/cert/headerTip',
'/passport/captcha/get',
'/passport/images',
'/passport/img-check.jpg',
'/3party/check/submit'
'/passport/geetest/register'
];
module.exports = (req, res, next) => {
... ...
... ... @@ -5,11 +5,14 @@ const cache = global.yoho.cache.master;
const config = global.yoho.config;
const ONE_DAY = 60 * 60 * 24;
const MAX_QPS = config.maxQps;
const MAX_QPS_10m = config.maxQps10m;
const _ = require('lodash');
const PAGES = {
'/product/\\/pro_([\\d]+)_([\\d]+)\\/(.*)/': 5,
'/product/list/index': 5
'/product/^\\/(\\d+)\\.html/': 5,
'/product/list/index': 5,
'/product/index/index': 5,
'/product/search/list': 5
};
function urlJoin(a, b) {
... ... @@ -26,7 +29,8 @@ module.exports = (limiter, policy) => {
const req = limiter.req,
res = limiter.res;
const key = `pc:limiter:${limiter.remoteIp}`;
const key = `h5:limiter:${limiter.remoteIp}`;
const key10m = `h5:limiter:10m:${limiter.remoteIp}`;
res.on('render', function() {
let route = req.route ? req.route.path : '';
... ... @@ -39,37 +43,55 @@ module.exports = (limiter, policy) => {
let pageKey = urlJoin(appPath, route.toString()); // route may be a regexp
let pageIncr = PAGES[pageKey] || 0;
if (/^\/p([\d]+)/.test(req.path)) {
pageIncr = 5;
}
if (pageIncr > 0) {
cache.incrAsync(key, pageIncr, () => {});
cache.incrAsync(key, pageIncr);
cache.incrAsync(key10m, pageIncr);
}
});
return cache.getAsync(key).then((result) => {
return cache.getMultiAsync([key, key10m]).then((results) => {
let result = results[key];
let result10m = results[key10m];
logger.debug('qps limiter: ' + key + '@' + result + ' max: ' + MAX_QPS);
logger.debug('qps limiter 10m: ' + key10m + '@' + result10m + ' max: ' + MAX_QPS_10m);
// 默认数据设置
if (!result && !_.isNumber(result)) {
cache.setAsync(key, 1, 60); // 设置key,1m失效
}
if (result && _.isNumber(result)) {
if (!result10m && !_.isNumber(result10m)) {
cache.setAsync(key10m, 1, 600); // 设置key,10m失效
}
// 第一次访问,都没计数,直接过
if (!result && !_.isNumber(result) && !result10m && !_.isNumber(result10m)) {
return Promise.resolve(true);
}
if (result === -1) {
if (result === -1 || result10m === -1) {
return Promise.resolve(true);
}
if (result > MAX_QPS) { // 判断 qps
// 判断 qps 10分钟
if (result10m > MAX_QPS_10m) {
cache.touch(key10m, ONE_DAY);
logger.debug('req limit', key10m);
return Promise.resolve(policy);
}
// 判断 qps 1分钟
if (result > MAX_QPS) {
cache.touch(key, ONE_DAY);
logger.debug('req limit', key);
return Promise.resolve(policy);
} else {
cache.incrAsync(key, 1); // qps + 1
return Promise.resolve(true);
}
} else {
cache.setAsync(key, 1, 60); // 设置key,1m失效
cache.incrAsync(key, 1); // qps + 1
cache.incrAsync(key10m, 1); // qps + 1
return Promise.resolve(true);
}
});
};
... ...