日志 logging : 记录离散事件信息
追踪 tracing:记录调用链 , 排除故障 , 使用插件式的探针完成
度量 metrics: 信息的统计聚合、内存大小、占用率,用于监控和预警
日志记录
输出 》 收集 》 缓冲 》 聚合加工 》 索引存储 ==》 查询分析
输出阶段: 日志的职责是记录事件,记录参数相关的任务需要交给追踪系统
不记录: 敏感信息、慢操作、错误的误导信息
需要记录: TraceID , SpanId , 关键的事件,配置的变化信息
收集和缓冲阶段:
使用 LOGSTASH 作为日志收集器可能太重了(每一个服务至少1GB的JVM),可以使用现在 Go 做的 Beats 家族完成日志收集
如果是大规模系统,比较常见的是在收集器前面使用 Kafka 或者 redis 作为缓冲
加工聚合阶段:
对于非结构化的数据,使用 grok 来完成结构化
对于固定查询的指标,可以提前收集完成聚合 - logstash 聚合插件 - logstash主要就是为了收集 , 可以提前聚合就提前操作,避免使用 elastic search 实时聚合查询的时候消耗
到了存储索引、查询阶段:
使用 elastic search 完成,对于日志此类特征的数据,以下方面可以帮助完成存储和索引:
- 按照时间索引:日志是按照时间存储的,因此可以提前创建索引,降低分片的消耗
- 最近时间是最具有价值的:最近的数据使用好的硬件
- 实时要求不高
链路追踪
目前市面的链路追踪系统基本都是基于 Google 的 Dapper 论文来实现
如 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作为存储的底层结构