Authored by 陈峰

limit

... ... @@ -156,9 +156,9 @@ try {
app.use(user());
// 请求限制中间件
if (!app.locals.devEnv) {
// if (!app.locals.devEnv) {
app.use(require('./doraemon/middleware/limiter'));
}
// }
app.use(seo());
app.use(setPageInfo());
... ...
... ... @@ -17,8 +17,12 @@ const index = co(function* (channel) {
});
const removeBlack = (remoteIp) => {
let operations = [cache.delAsync(`${config.app}:limiter:${remoteIp}`)];
let operations = [];
operations.push(cache.delAsync(`${config.app}:limiter:${remoteIp}`));
// 验证码之后一小时之内不再限制qps
operations.push(cache.setAsync(`${config.app}:limiter:ishuman:${remoteIp}`, 1, 3600));
_.forEach(config.REQUEST_LIMIT, (val, key) => {
operations.push(cache.delAsync(`${config.app}:limiter:${key}:max:${remoteIp}`));
});
... ...
... ... @@ -21,13 +21,13 @@ module.exports = {
cookieDomain: '.yohobuy.com',
domains: {
// test3
singleApi: 'http://api-test3.yohops.com:9999/',
api: 'http://api-test3.yohops.com:9999/',
service: 'http://api-test3.yohops.com:9999/',
serviceNotify: 'http://api-test3.yohops.com:9999/',
global: 'http://global-test-soa.yohops.com:9999/',
platformApi: 'http://192.168.102.48:8088/',
yohoNowApi: 'http://yohonow-test.yohops.com:9999/',
// singleApi: 'http://api-test3.yohops.com:9999/',
// api: 'http://api-test3.yohops.com:9999/',
// service: 'http://api-test3.yohops.com:9999/',
// serviceNotify: 'http://api-test3.yohops.com:9999/',
// global: 'http://global-test-soa.yohops.com:9999/',
// platformApi: 'http://192.168.102.48:8088/',
// yohoNowApi: 'http://yohonow-test.yohops.com:9999/',
// test2
// singleApi: 'http://api-test2.yohops.com:9999/',
... ... @@ -38,11 +38,11 @@ module.exports = {
// platformApi: 'http://192.168.102.48:8088/',
// prod
// singleApi: 'http://api.yoho.cn/',
// api: 'http://api.yoho.cn/',
// service: 'http://api.yoho.cn/',
// serviceNotify: 'http://service.yoho.cn/',
// platformApi: 'http://172.16.6.210:8088/',
singleApi: 'http://api.yoho.cn/',
api: 'http://api.yoho.cn/',
service: 'http://api.yoho.cn/',
serviceNotify: 'http://service.yoho.cn/',
platformApi: 'http://172.16.6.210:8088/',
// gray
// singleApi: 'http://apigray.yoho.cn/',
... ... @@ -175,15 +175,15 @@ module.exports = {
},
REQUEST_LIMIT: {
// 10s 最多访问5次
10: 10,
10: 5,
// 30s 最多访问15次
30: 20,
// 30s 最多访问10次
30: 10,
// 60s 最多访问15次
60: 30,
60: 15,
// 100s 最多访问15
// 100s 最多访问100
600: 100
}
};
... ...
... ... @@ -4,8 +4,10 @@
*/
const headerModel = require('../models/header');
const logger = global.yoho.logger;
const cache = global.yoho.cache.master;
const helpers = global.yoho.helpers;
const sender = global.yoho.apmSender;
const config = global.yoho.config;
const hostname = require('os').hostname();
const routeEncode = require('./route-encode');
const _ = require('lodash');
... ... @@ -54,7 +56,13 @@ exports.serverError = () => {
const uid = req.user ? req.user.uid : 0;
const udid = _.get(req, 'cookies.udid', 'yoho');
if (req.isApmReport) {
err = err || {
code: 500
};
err.code = err.code || err.statusCode || 500;
if (req.isApmReport && !err.apiError && err.code !== 401) {
// 上报服务端错误
sender.addMessage({
measurement: 'error-report',
... ... @@ -79,7 +87,7 @@ exports.serverError = () => {
logger.error(`error at path: ${req.url}`);
logger.error(err);
if (err && err.code === 401) {
if (err.code === 401) {
if (req.xhr) {
err.data = {refer: helpers.urlFormat('/signin.html', {refer: req.get('Referer') || ''})};
return res.json(err);
... ... @@ -87,6 +95,30 @@ exports.serverError = () => {
return res.redirect(helpers.urlFormat('/signin.html', {refer: req.fullUrl()}));
}
}
if (err.code === 9999991 || err.code === 9999992) {
let limitAPI = helpers.urlFormat('/3party/check', {refer: req.get('Referer') || ''});
let limitPage = helpers.urlFormat('/3party/check', {
refer: req.protocol + '://' + req.get('host') + req.originalUrl
});
let remoteIp = req.yoho.clientIp;
if (remoteIp.indexOf(',') > 0) {
let arr = remoteIp.split(',');
remoteIp = arr[0];
}
cache.setAsync(`${config.app}:limiter:${remoteIp}`);
if (req.xhr) {
return res.status(510).json({
code: err.code,
data: {refer: limitAPI}
});
}
return res.redirect(limitPage);
}
if (!res.headersSent) {
if (req.xhr) {
... ...
... ... @@ -24,8 +24,7 @@ module.exports = (req, res, next) => {
}
if (req.xhr) {
return res.json({
code: 400,
return res.status(510).json({
data: {refer: limitAPI}
});
}
... ...
... ... @@ -27,12 +27,18 @@ module.exports = (limiter, policy) => {
getOp[key] = cache.getAsync(ruleKeys[key]);
});
getOp.human = cache.getAsync(`${config.app}:limiter:ishuman:${limiter.remoteIp}`);
return Promise.props(getOp).then((results) => {
logger.debug(MAX_TIMES);
logger.debug(_.values(ruleKeys));
logger.debug(results);
if (results.human) { // 经过验证码之后1小时有效期内不再验证qps
return Promise.resolve(true);
}
// 遍历限制规则,若满足返回相应处理策略, 否则页面访问次数加1
let operation = [];
... ...
... ... @@ -66,7 +66,8 @@ const getEntries = () => {
'yoho-slider',
'yoho-jquery-pjax',
'yoho-jquery-dotdotdot',
'regenerator-runtime/runtime'
'regenerator-runtime/runtime',
path.join(__dirname, '../js/global.js')
],
base: path.join(__dirname, '../scss/base.css')
};
... ...
const $ = require('yoho-jquery');
// 注册ajaxError处理服务端异常
$(document).ajaxError((event, xhr) => {
if (xhr.responseJSON) {
if (xhr.status === 510) {
window.location.href = xhr.responseJSON.data.refer;
}
}
});
... ...