可预测性—事件日志、链路追踪、聚合度量

事件日志

记录系统运行期间发生过的离散事件。

复杂的分布式系统往往还要有专门的全局查询和可视化功能。

从打印日志到分析查询之间,还隔着收集、缓冲、聚合、加工、索引、存储等若干个步骤。

 

 

输出

“错误的做法”

  • 避免打印敏感信息,不过,日志中应当包含必要的非敏感信息,譬如当前用户的 ID

  • 避免引用慢操作,如果数据需要专门调用远程服务或者从数据库获取,又或者通过大量计算才能取到的话,慎重考虑该信息放在日志中是否恰当。

  • 避免打印追踪诊断信息,追踪诊断应由追踪系统去处理。

 

“正确的做法”

  • 处理请求时的 TraceID。服务收到请求时,如果该请求没有附带 TraceID,就应该自动生成唯一的 TraceID 来对请求进行标记,并使用 MDC 自动输出到日志。

    通过TraceID把请求在分布式系统各个服务中的执行过程串联起来。

  • 系统运行过程中的关键事件。进行了哪些操作、发生了与预期不符的情况、运行期间出现未能处理的异常或警告、定期自动执行的任务。

  • 启动时输出配置信息。对于系统启动时或者检测到配置中心变化时更新的配置,应将非敏感的配置信息输出到日志中,譬如连接的数据库、临时目录的路径等等,初始化配置的逻辑一般只会执行一次,不便于诊断时复现,所以应该输出到日志中。

 

收集与缓冲

覆盖整个链路的全局日志系统,每个节点输出日志到文件后,必须将日志文件统一收集起来集中存储、索引,由此便催生了专门的日志收集器

缓解压力:将日志接收者从 Logstash 和 Elasticsearch 转移至抗压能力更强的队列缓存,譬如在 Logstash 之前架设一个 Kafka 或者 Redis 作为缓冲层,面对突发流量,Logstash 或 Elasticsearch 处理能力出现瓶颈时自动削峰填谷,甚至当它们短时间停顿,也不会丢失日志数据。

 

加工与聚合

日志包含的 10 项独立数据项

 

 

加工

Logstash把日志行中的非结构化数据,通过 Grok 表达式语法转换为上面表格那样的结构化数据,进行结构化的同时,还可能会根据需要,调用其他插件来完成时间处理(统一时间格式)、类型转换(如字符串、数值的转换)、查询归类(譬如将 IP 地址根据地理信息库按省市归类)等额外处理工作,然后以 JSON 格式输出到 Elasticsearch 中。

Elasticsearch 便可针对不同的数据项来建立索引,进行条件查询、统计、聚合等操作。

 

聚合

  • 通过 Elasticsearch 本身的处理能力做实时的聚合统计,这很便捷,不过要消耗 Elasticsearch 服务器的运算资源。

  • 在收集日志后自动生成某些常用的、固定的聚合指标,这种聚合就会在 Logstash 中通过聚合插件来完成

 

存储与查询
  • 日志是典型的基于时间的数据流,增长速度很快,但已写入的数据几乎没有再发生变动的可能。

    Elasticsearch 都会使用时间范围作为索引,根据实际数据量的大小可能是按月、按周或者按日、按时。

  • 日志基本上只会以最近的数据为检索目标,随着时间推移,早期的数据将逐渐失去价值。这点决定了可以很容易区分出冷数据和热数据,进而对不同数据采用不一样的硬件策略。

    从日志记录的事件中去挖掘业务热点,分析用户习惯

 

Kibana:把存储在 Elasticsearch 中的数据被检索、聚合、统计后,定制形成各种图形、表格、指标、统计,以此观察系统的运行状态,找出日志事件中潜藏的规律和隐患。

 

链路追踪

排查故障分析性能提供数据支持。

系统对外提供服务的过程中,持续地接受请求并处理响应,同时持续地生成 Trace,按次序整理好 Trace 中每一个 Span 所记录的调用关系,便能绘制出一幅系统的服务调用拓扑图。

 

一个完整的分布式追踪系统应该由数据收集、数据存储数据展示三个相对独立的子系统构成。

 

Spring Cloud Sleuth负责数据收集部分,搭配 Zipkin 作为数据展示,搭配 Elasticsearch 作为数据存储来组合使用。

 

追踪与跨度

“追踪” Trace:从客户端发起请求抵达系统的边界开始,记录请求流经的每一个服务,直到到向客户端返回响应为止的整个过程。

“跨度” Span:每次开始调用服务前都要先埋入一个调用记录,记录具体调用了哪些服务,以及调用的顺序、开始时点、执行时长等信息。

Span放在日志或者网络协议的报文头里,应含有时间戳、起止时间、TraceID、当前 Span 的 ID、父 Span 的 ID 等能够满足追踪需要的信息。

 

每一次 Trace 实际上都是由若干个有顺序、有层级关系的 Span 所组成一颗“追踪树”。

 

 

 

数据收集

基于日志的追踪(Log-Based Tracing) Sleuth

将 Trace、Span 等信息直接输出到应用日志中,然后随着所有节点的日志归集过程汇聚到一起,再从全局日志信息中反推出完整的调用链拓扑关系。

基于服务的追踪(Service-Based Tracing)Zipkin

通过某些手段给目标应用注入追踪探针(Probe),探针在结构上可视为一个寄生在目标服务身上的小型微服务系统,它一般会有自己专用的服务注册、心跳检测等功能,有专门的数据收集协议,把从目标系统中监控得到的服务调用信息,通过另一次独立的 HTTP 或者 RPC 请求发送给追踪系统。

 

比基于日志的追踪消耗更多的资源,也有更强的侵入性,换来的收益是追踪的精确性与稳定性都有所保证

 

基于边车代理的追踪(Sidecar-Based Tracing)

 

聚合度量

指标收集

“如何定义指标”,所有通用的度量系统都是面向指标的数据类型来设计的

度量器

  • 计数度量器

  • 瞬态度量器

  • 吞吐率度量器

    统计单位时间的吞吐量,即单位时间内某个事件的发生次数。

  • 直方图度量器

  • 采样点分位图度量器

 

“如何将这些指标告诉服务端”

  • 拉取式采集

    度量系统主动从目标系统中拉取指标

  • 推送式采集

    目标系统主动向度量系统推送指标

 

存储查询

时序数据库:存储跟随时间而变化的数据,并且以时间(时间点或者时间区间)来建立索引的数据库。

  • 以日志结构合并树作为存储结构

  • 设置激进的数据保留策略,根据过期时间(TTL)自动删除相关数据以节省存储空间

  • 对数据进行再采样(Resampling)以节省空间,譬如最近几天的数据可能需要精确到秒,而查询一个月前的数据时,只需要精确到天,查询一年前的数据时,只要精确到周

监控预警

posted @ 2022-06-18 18:30  roibin  阅读(166)  评论(0编辑  收藏  举报