Logging,Metrics 和 Tracing
单体应用慢慢进化成微服务应用,随之带来的是运维方式的改变。形成了DevOps方式的运维,这一切都是为了提高软件的交付和部署效率。相应的基础的运维服务主要总结为以下三大块,Logging集中的日志管理系统,结构化的日志,统一的查询使得定位问题更加有针对性,Metrics则关注整个系统的各种指标的的变化,集中度量系统主要采集QPS、吞吐量、网络带宽、接口的平均调用时间等等指标,和今天所要说的分布式追踪系统tracing,呈现整个系统各个组件的相互关系与问题的快速定位。
- 微服务中如何诊断到耗时服务
- 如何定位单点失败
- 如何检测并避免循环依赖关系
- 如何定位相互调用关系
实现原理
分布式追踪的关键步骤在于,数据采集,存储与分析展示
- 在API接入层,生成全局唯一traceID,并注入到对应的context中
- 在每个节点生成spanID,根据traceID和spanID定位某次请求的某服务
- 将traceID跟随context注入到下一节点
- 入库消息的结构组成,traceID、层级表示、调用方法、调用时间、返回时间
custom opentracing
下图是一个分布式调用的例子
opentracing && jaeger
opentracing 是分布式追踪应用中的规范,主要解决了不用分布式追踪系统Api不兼容的问题。规范
关于opentracing jaeger ui展示层
接收client的trace span消息,存入到内存map中,并定时清理map中的内容
jaeger实践
jaeger是Uber开源的一个分布式追踪系统项目,使用Go语言开发。在实践中主要将数据的采集和数据展示拆分出来,简化了中间的存储过程,采用了内存存储的暂时性方案,修改了相应的源码,这里内存存储主要存在以下几个问题,所以后续还是会将存储落地到数据库。在数据的展示层还是兼容了jaeger本身自有的API接口,但是这块非常的薄弱,只有tracing和关系依赖功能,后续可以在这个系统中加入相应的metrics功能,例如参考Prometheus。
- 如果span消息暴增,则会导致周期内写入map中的数据暴增,map会变得很大
- 如果在清理过程中阻塞或者是在写入时阻塞,会导致map无法写入或者无法清空
- 如果map在清理过程中耗时过长,将导致在清理的过程中,map完全不可写入