Authored by 陈峰

comit

Showing 100 changed files with 224 additions and 0 deletions

Too many changes to show.

To preserve performance only 100 of 100+ files are displayed.

app.js 100644 → 100755
No preview for this file type
const schedule = require('node-schedule');
const _ = require('lodash');
const ZookeeperModel = require('../web/models/zookeeperModel');
const Operation = require('../logger/operation');
const {client} = require('../../lib/redis');
module.exports = () => {
let zookeeperModel = new ZookeeperModel();
schedule.scheduleJob('* * * * * *', async () => {
const appsData = await client.getAsync('degradeSSRKeys');
const apps = JSON.parse(appsData || '[]');
_.forEach(apps, async app => {
const zkDegradePath = `/wap/webapp/${app}-degrade`;
const degradeKey = `${app}:degradessr`;
const isDegradeKey = `${degradeKey}:isdegrade`;
const [degradeJson, isDegrade] = await Promise.all([client.getAsync(degradeKey), client.getAsync(isDegradeKey)]);
const zkIsDegrade = await zookeeperModel.getPath(zkDegradePath)
const degrades = JSON.parse(degradeJson || '[]');
if (!isDegrade && zkIsDegrade === 'true') { // isdegrade的redis key已过期,且没有触发限制刷新key过期时间,则降级开关关闭
zookeeperModel.setPath(zkDegradePath, false);
console.log('SSR降级恢复')
Operation.action({
_id: 0,
username: 'ssr-degrade'
}, 'SSR降级恢复', '降级恢复' , {app});
}
_.forEach(degrades, async item => {
const key = `${degradeKey}:${item.time}`;
const result = await client.getAsync(key);
if (item.time * item.tick < +result) { // 大于qps限制,降级
const degradeData = {
...item,
maxTick: +result
};
console.log('触发降级策略')
Operation.action({
_id: 0,
username: 'ssr-degrade'
}, 'SSR降级', '触发降级策略' ,`${isDegradeKey},${JSON.stringify(degradeData)}`);
client.setexAsync(isDegradeKey, item.delay * 60, JSON.stringify(degradeData));
client.delAsync(key);
zookeeperModel.setPath(zkDegradePath, true);
}
});
})
});
}
\ No newline at end of file
... ...
const Router = require('koa-router');
const SsrDegradeModel = require('../models/ssrDegradeModel');
let r = new Router();
const ssrDegrade = {
async index(ctx, next) {
const ssrDegradeModel = new SsrDegradeModel();
const apps = await ssrDegradeModel.getApps();
return ctx.render('action/ssr_degrade', {
list: apps || []
});
},
async editPage(ctx, next) {
const ssrDegradeModel = new SsrDegradeModel();
const app = ctx.request.query.app;
if (!app) {
return ctx.render('action/ssr_degrade_edit', {
data: {}
});
}
const appData = await ssrDegradeModel.getApp(app);
return ctx.render('action/ssr_degrade_edit', {
data: appData
});
},
async edit(ctx, next) {
const ssrDegradeModel = new SsrDegradeModel();
const data = ctx.request.body;
if (!data.app || !Array.isArray(data.degrades)) {
return ctx.body = {
code: 400,
message: '参数错误'
};
}
const result = ssrDegradeModel.editApp(data);
if (result) {
return ctx.body = {
code: 200,
};
}
return ctx.body = {
code: 500,
message: '失败'
};
},
async delete(ctx, next) {
const ssrDegradeModel = new SsrDegradeModel();
const app = ctx.request.query.app;
if (!app) {
return ctx.body = {
code: 400,
message: '参数错误'
};
}
const result = ssrDegradeModel.deleteApp({app});
if (result) {
return ctx.body = {
code: 200,
};
}
return ctx.body = {
code: 500,
message: '失败'
};
}
};
r.get('/index', ssrDegrade.index);
r.get('/edit', ssrDegrade.editPage);
r.post('/edit', ssrDegrade.edit);
r.get('/delete', ssrDegrade.delete);
module.exports = r;
... ...
... ... @@ -14,6 +14,7 @@ const routers = require('./routers');
const collectData = require('./actions/collect_data');
const profile = require('./actions/profile');
const redis = require('../../lib/redis');
const degradeSsrTask = require('../tasks/degrade-ssr-task');
const {
normalMenus,
... ... @@ -47,6 +48,9 @@ const mastersUrl = [
// 服务器监控数据采集
// collectData.collect();
// SSR自适应降级监控
degradeSsrTask();
app.use(async(ctx, next) => {
ctx.redis = redis.client;
... ...
const model = require('../../../lib/model');
const {client} = require('../../../lib/redis');
const ZookeeperModel = require('../../web/models/zookeeperModel');
const _ = require('lodash');
class SsrDegradeModel extends model {
constructor(ctx) {
super(ctx);
}
async getApps() {
const appsData = await client.getAsync('degradeSSRKeys');
const apps = JSON.parse(appsData || '[]');
return Promise.all(_.map(apps, this.getApp));
}
async getApp(app) {
const zookeeperModel = new ZookeeperModel();
const [degradeJson, isDegradeJson] = await Promise.all([
client.getAsync(`${app}:degradessr`),
client.getAsync(`${app}:degradessr:isdegrade`)]
);
const zkIsDegrade = await zookeeperModel.getPath(`/wap/webapp/${app}-degrade`);
const degrades = JSON.parse(degradeJson || '[]');
let isDegrade;
if (isDegradeJson) {
isDegrade = JSON.parse(isDegradeJson);
_.forEach(degrades, d => {
if (d.time === isDegrade.time && d.tick === isDegrade.tick) {
d.status = true;
d.maxTick = d.maxTick;
}
})
}
return {
app,
degrades,
status: zkIsDegrade === 'true'
};
}
async editApp(data) {
const zookeeperModel = new ZookeeperModel();
const appsData = await client.getAsync('degradeSSRKeys');
const apps = JSON.parse(appsData || '[]');
if (!apps.some(app => app === data.app)) {
apps.push(data.app);
client.setAsync('degradeSSRKeys', JSON.stringify(apps));
}
zookeeperModel.setPath(`/wap/webapp/${data.app}-degrade`, false);
client.delAsync(`${data.app}:degradessr:isdegrade`);
const degrades = _.map(data.degrades, d => {
return {
time: d.time,
tick: d.tick,
delay: d.delay
}
})
return await client.setAsync(`${data.app}:degradessr`, JSON.stringify(degrades));
}
async deleteApp(data) {
const zookeeperModel = new ZookeeperModel();
const appsData = await client.getAsync('degradeSSRKeys');
const apps = JSON.parse(appsData || '[]');
const saveApps = apps.filter(app => app !== data.app);
client.setAsync('degradeSSRKeys', JSON.stringify(saveApps));
client.delAsync(`${data.app}:degradessr`);
client.delAsync(`${data.app}:degradessr:isdegrade`);
zookeeperModel.setPath(`/wap/webapp/${data.app}-degrade`, false);
return true;
}
}
module.exports = SsrDegradeModel;
... ...
... ... @@ -29,6 +29,7 @@ const noAuth = new Router();
const base = new Router();
const file = require('./actions/file');
const riskManagement = require('./actions/risk_management');
const ssrDegrade = require('./actions/ssr_degrade');
const logs = require('./actions/logs');
const spa = require('./actions/spa');
const upload = require('./actions/upload');
... ... @@ -80,6 +81,7 @@ module.exports = function(app) {
// base.use('', index.routes(), index.allowedMethods());
base.use('/risk_management', riskManagement.routes(), riskManagement.allowedMethods());
base.use('/ssr_degrade', ssrDegrade.routes(), ssrDegrade.allowedMethods());
base.use('/logs', logs.routes(), logs.allowedMethods());
base.use('/upload', upload.routes(), upload.allowedMethods());
base.use('', spa.routes(), spa.allowedMethods());
... ...