本文首发于:github.com/bigo-fronte… 欢迎关注、转载。
背景
bigo前端开始推广bff,hello农场作为首个bff落地项目,历经2个月,完成了从0-1的落地实践。
【node实战系列】按照小模块拆分,从开发者的角度讲叙,如何进行bff高可用编码。
本系列文章,基于eggjs框架编码,使用ts语法,为了提升阅读体验,建议大家先了解一下eggjs。
系列文章
- 【node实战系列】编写一个重试装饰器
- 【node实战系列】自行实现应用缓存
- 【node实战系列】异步并发,自定义Promise.allSettled
- 【node实战系列】rpc与http协议通讯
- 【node实战系列】使用reqId跟踪全链路日志
- 【node实战系列】入参校验validate
- 【node实战系列】异常中断
- 【node实战系列】base64编码
- 【node实战系列】服务发现
- 【node实战系列】编码与约定
- 【node实战系列】监控告警
- 【node实战系列】单元测试
- 【node实战系列】压测
- 【node实战系列】灰度
- 【node实战系列】文档
- 【node实战系列】系列小结
欢迎大家关注我们的github blog,持续更新。 github.com/bigo-fronte…
使用reqId跟踪全链路日志
问题排查
接口怎么报错了?你这个字段的数据不对呀? 作为bff聚合层,测试或者前端同学对于接口异常,第一时间找到我们,需要我们快速定位问题,确定是业务逻辑异常,还是下游响应异常。
对于那种影响比较大的bug,处理时间是分秒必争的,慢几秒处理完,可能GMV就哗啦啦的掉了很多。
一个程序员是否优秀,其中一个判断维度就是:处理线上问题是否快狠准,而其中日志是帮我们快速定位问题的绝佳手段。
但是随着应用集群部署,微服务架构复杂,日志量大,做单个场景的全链路追踪就很重要。
reqId
reqId(或者叫traceId: 调用链id),在bff对当前请求生成随机reqId,日志打印需要包含reqId,同时在每个 RPC 方法里面传入 reqId,在返回给前端响应里面带上reqId。
排查问题时,就可以通过response的reqId查询所有下游日志,实现全链路追踪。
实现过程
// 返回指定长度的随机数
randomNum(len) {
let str = '';
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for(let i=0; i<len; i++){
const pos = Math.round(Math.random() * (arr.length-1));
str += arr[pos];
}
return Number(str);
}
// 首个 middleware 里面生成seqId
ctx.seqId = ctx.helper.randomNum(8);
// 日志方法里面默认打印 seqId
log(text, obj: PlainObject) {
this.logger.info(`seqId=%j uid=%j ${text}`, this.seqId, this.loginuid || 0, obj);
}
// 约定透传给下游rpc
list.push({
key: 'seqId',
value: String(this.ctx.seqId),
});
日志查询
如下图,基于seqId=87336202,就能快速查询日志了。
数据库日志查询:
可视化时间轴展示:
总结
日志追踪分析是解决生产问题的第一技术手段,甚至可以说是唯一的手段。通过seqId分析整个微服务的调用链,数据在不同服务节点的变更都一目了然,对于定位问题至关重要。好了,本文的简单介绍到这里就结束了。
欢迎大家留言讨论,祝工作顺利、生活愉快!
我是bigo前端,下期见。