NODEJS 在广发证券的应用
大纲
- 背景
- 定位&选型
- Microservice&Devops
- Q&A
背景
我们是谁
- 广发证券
- 信息技术部
- 互联网金融
定位&选型
业务1
业务2
业务3
证券交易所
柜台
中间件
业务-后台
用户-浏览器
证券交易所
柜台
中间件
行情
基金
为什么选择 NodeJS
- 团队成员大多有前端基础
- 业务高并发
- 内存占用小
- 支持 async/await 解决异步问题
选择什么框架
express | koa | |
---|---|---|
Github Stars | 34k+ | 17k+ |
Contributions | 217 | 136 |
Middlewares | 3128 | 1038 |
优点 | 最流行、最出名、生态成熟 | 依赖模块少,优雅的异步处理和错误处理 |
缺点 | 异步处理和错误处理 | 生态相比不够成熟 |
性能
为什么选择Koa2
- 优雅的异步处理
- 优雅的错误处理
- 可以通过简单的包装直接使用 express 的中间件
- 中间件开发简单
- 性能也不赖
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log(1);
await next();
console.log(2);
});
app.use(async (ctx, next) => {
console.log(3);
await next();
console.log(4);
});
app.listen(3000);
const logger = require('../lib/logger').getLogger();
module.exports = async function(ctx, next) {
let start = +new Date;
try {
await next();
} catch (error) {
error = error || new Error('unknow error');
if (error.expected) return;
logger.ctx(ctx).fatal(`error: ${error.message}, stack: ${error.stack}`);
ctx.set('cache-control', 'no-cache, max-age=0');
ctx.status = error.status || 500;
ctx.type = 'json';
ctx.body = {
code: error.code,
error: error.error,
message: error.message,
};
} finally {
let time_cost = +new Date - start;
// todo report
}
};
process.on('unhandledRejection', (err) => {
logger.fatal(`unhandledRejection: ${err.message}, stack: ${err.stack}`);
});
process.on('uncaughtException', (err) => {
logger.fatal(`uncaughtException: ${err.message}, stack: ${err.stack}`);
});
异常处理示例
使用 express 中间件
日志应该怎么记
- 设置好日志级别
- 利用好 debug 模块
- 每个请求一个reqid
- 每个用户一个uid
- 每条日志都要记录 reqid 和 uid
- 密码等敏感信息不能记录到日志中
- 不换行
require('request-debug')(rp, function(type, data, r) {
if(type === 'request') {
let {debugId, uri, method, body} = data;
let userId = data.headers.userId;
let more = body ? '' : ('-' + body) + userId ? '' : ('userId:' + userId);
debug(`${debugId}-${method}-${uri}-${more}`.replace(/\s+/g, ' '));
}
if(type === 'response') {
let {debugId, statusCode, body} = data;
debug(`${debugId}-resp-${statusCode}-${JSON.stringify(body)}`.replace(/\s+/g, ' '));
}
});
代码质量检查&测试用例
- eslint
-
supertest & ava
-
贵在坚持
Microservice&Devops
服务应该怎么部署
- pm2
- docker
pm2 | docker | |
---|---|---|
优点 | 简单、方便、适用于小项目 | 环境稳定、版本控制好、方便跨集群部署、结合 CI 可自动化部署 |
缺点 | 不方便回滚、不方便跨集群部署 | 需要与之配套的发布工具及环境 |
建议 | 个人项目、小项目使用 | 公司有条件支持时使用 |
优缺点
Dockerfile 怎么写
# base image
FROM node:slim
# image name
ENV IMAGE_NAME example
# work dir
RUN mkdir -p /www/$IMAGE_NAME
ADD . /www/$IMAGE_NAME
WORKDIR /www/$IMAGE_NAME
# install node_modules
RUN npm install --production --verbose
# env
ENV PORT=8000
# start
CMD ["./start.sh"]
几条命令
- docker build -t example:latest .
- docker push example:latest .
- docker run -d -p 8000:8000 --name=example example:latest
- docker tag example:latest example:1.0.0
Gitlab CI
Gateway-Nginx
用户-浏览器
后台-Gateway
后台服务
docker
前端资源
html/css
k8s
k8s
开发和运维
整体架构
监控-内存占用
监控-CPU使用率
监控-QPS
监控-延时
Q&A
Node
By loskael
Node
- 1,144