Authored by 周少峰

Merge branch 'hotfix/limit'

... ... @@ -15,9 +15,13 @@ const index = co(function* (channel) {
});
const removeBlack = (remoteIp) => {
let key = `pc:limiter:${remoteIp}`;
let key = `pc:limiter:${remoteIp}`,
key10m = `pc:limiter:10m:${remoteIp}`;
return cache.delAsync(key);
return Promise.all([
cache.delAsync(key),
cache.delAsync(key10m)
]);
};
module.exports = {
... ...
... ... @@ -134,6 +134,7 @@ module.exports = {
},
zookeeperServer: '192.168.102.168:2188',
maxQps: 1200,
maxQps10m: 2500,
sessionMemcachedPrefix: 'yohobuy_session:',
redis: {
connect: {
... ...
... ... @@ -5,11 +5,13 @@ 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; // eslint-disable-line
const _ = require('lodash');
const PAGES = {
'/product/\\/pro_([\\d]+)_([\\d]+)\\/(.*)/': 5,
'/product/list/index': 5
'/product/\\/([\\d]+)(.*)/': 5,
'/product/list/index': 5,
'/product/search/index': 5
};
function urlJoin(a, b) {
... ... @@ -28,6 +30,7 @@ module.exports = (limiter, policy) => {
next = limiter.next; // eslint-disable-line
const key = `pc:limiter:${limiter.remoteIp}`;
const key10m = `pc:limiter:10m:${limiter.remoteIp}`;
res.on('render', function() {
let route = req.route ? req.route.path : '';
... ... @@ -40,38 +43,61 @@ 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.incr(key, pageIncr, (err) => {}); // eslint-disable-line
cache.incr(key10m, pageIncr, (err) => {}); // eslint-disable-line
}
});
return cache.getAsync(key).then((result) => {
logger.debug('qps limiter: ' + key + '@' + result + ' max: ' + MAX_QPS);
if (result && _.isNumber(result)) {
if (result === -1) {
return Promise.resolve(true);
}
if (result === 9999) {
res.statusCode = 403;
return Promise.resolve(policy);
} else if (result > MAX_QPS) { // 判断 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失效
return cache.getMultiAsync([key, key10m]).then((results) => {
let result = results[key];
let result10m = results[key10m];
logger.debug('qps limiter: ' + key + '@' + result[0] + ' max: ' + MAX_QPS);
logger.debug('qps limiter:10m ' + key10m + '@' + result10m + ' max: ' + MAX_QPS_10m); // eslint-disable-line
// 默认数据设置
if (!result && !_.isNumber(result)) {
cache.setAsync(key, 1, 60); // 设置key,1m失效
}
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 || result10m === -1) {
return Promise.resolve(true);
}
// 判断 qps 10分钟
if (result10m === 9999) {
res.statusCode = 403;
return Promise.resolve(policy);
} else if (result10m > MAX_QPS_10m) { // eslint-disable-line
cache.touch(key10m, ONE_DAY);
logger.debug('req limit', key10m);
return Promise.resolve(policy);
}
// 判断 qps 1分钟
if (result === 9999) {
res.statusCode = 403;
return Promise.resolve(policy);
} else if (result > MAX_QPS) { // 判断 qps
cache.touch(key, ONE_DAY);
logger.debug('req limit', key);
return Promise.resolve(policy);
}
cache.incrAsync(key, 1); // qps + 1
cache.incrAsync(key10m, 1); // qps + 1
return Promise.resolve(true);
});
};
... ...
{
"name": "yohobuy-node",
"version": "5.8.1",
"version": "5.8.2",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ...
... ... @@ -114,7 +114,7 @@ function getShoppingKey() {
a.src = j;
m.parentNode.insertBefore(a, m);
}(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//' + // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/2.2.3/yas.js', '_yas')); // eslint-disable-line
'cdn.yoho.cn/yas-jssdk/2.4.1/yas.js', '_yas')); // eslint-disable-line
(function() {
var uid = getUid();
... ... @@ -124,7 +124,7 @@ function getShoppingKey() {
window._ozuid = uid; // 暴露ozuid
if (window._yas) {
window._yas(1 * new Date(), '2.2.3', 'yohobuy_web', uid, '', '');
window._yas(1 * new Date(), '2.4.1', 'yohobuy_web', uid, '', '');
}
}());
... ...