日志 logging : 记录离散事件信息

追踪 tracing:记录调用链 , 排除故障 , 使用插件式的探针完成

度量 metrics: 信息的统计聚合、内存大小、占用率,用于监控和预警

日志记录

输出 》 收集 》 缓冲 》 聚合加工 》 索引存储 ==》 查询分析

输出阶段: 日志的职责是记录事件,记录参数相关的任务需要交给追踪系统

不记录: 敏感信息、慢操作、错误的误导信息

需要记录: TraceID , SpanId , 关键的事件,配置的变化信息

收集和缓冲阶段:

使用 LOGSTASH 作为日志收集器可能太重了(每一个服务至少1GB的JVM),可以使用现在 Go 做的 Beats 家族完成日志收集

如果是大规模系统,比较常见的是在收集器前面使用 Kafka 或者 redis 作为缓冲

加工聚合阶段:

对于非结构化的数据,使用 grok 来完成结构化

对于固定查询的指标,可以提前收集完成聚合 - logstash 聚合插件 - logstash主要就是为了收集 , 可以提前聚合就提前操作,避免使用 elastic search 实时聚合查询的时候消耗

到了存储索引、查询阶段:

使用 elastic search 完成,对于日志此类特征的数据,以下方面可以帮助完成存储和索引:

  • 按照时间索引:日志是按照时间存储的,因此可以提前创建索引,降低分片的消耗
  • 最近时间是最具有价值的:最近的数据使用好的硬件
  • 实时要求不高

链路追踪

目前市面的链路追踪系统基本都是基于 Google 的 Dapper 论文来实现

https://static.googleusercontent.com/media/research.google.com/zh-CN//archive/papers/dapper-2010-1.pdf

如 Twitter的Zipkin , 大众的CAT , 开源的 SkyWalking , 这些都是广义的APM (Application Performance Management)

目前基本都是遵循 OpenTrace规范 , 或者 谷歌的 OpenCensus规范

Trace : 数据从客户端发起 , 经过每一个服务,然后返回给客户端的过程

Span:当到达一个服务,就是开启一个新的Span , 记录父SpanID、TraceId、开始时间点、IP等信息

一个Trace就是若干个存在顺序的、有层级的Span组成的追踪树

链路追踪真正的挑战在于服务架构的异构性, 语言、通信协议等等。

同时还需要保证 低性能损耗、对应用透明、易于扩展、持续的监控(稳定性)的要求

有点像 daemon 进程一样

从收集的数据类型来看:

  • 将信息输出到日志里面 , 然后对日志进行分析获取信息。这个方式性能好,侵入性低,但是稳定性不太行,同时实时性也很差 , Spring Cloud Sleuth
  • 追踪服务,即使用追踪的探针(如Java的Agent),然后这些探针组成一个小型微服务系统,存在自己的协议和心跳检测机制,定期将信息发给追踪系统;这种方式是现在的主流方式,存在性能消耗和侵入性,但是稳定性和准确性比较高。
  • 基于代理的服务网络的方案,这个对网络的扩展性和设计性有很高的要求。

聚合度量

这里一般都是仪表板类型的显示系统的状态。

对于信息的获取可以采取Push ,也可以采取Pull的方式获取。

对于此类信息的存储,都是属于读少写多,然后几乎不会修改删除的场景,很适合时序数据库 ,使用LSM作为存储的底层结构