服务可观察性
1 什么是可观察性
度量你的基础设施、平台和应用程序,以了解它是如何运行的。
可观察性可以帮助我们理解和度量系统运行状态,判断是否有可优化的空间,以及定位如下问题。
每个服务的状态如何,是否在按预期处理请求?
请求为什么会失败?
客户请求都经过了哪些服务,调用链上是否有性能瓶颈?
至于如何使一个系统具有可观察性,关键在于如何提供可以体现系统运行状态的数据,以及如何收集、展示这些数据并在系统异常的时候正确报警。
指标:一个时间段内累计的度量或计数,它具有原子性,并且是可累加的。比如某次请求使用了多少内存,某个服务在过去的一段时间内处理了多少请求等。指标数据占用内存最少,可以被高效传输和存储。
日志:系统事件的记录,这些事件是不连续且不可变的。比如记录某个服务出错时的错误信息,记录系统处理某次请求的信息等。日志占用的内存最多,因为它可以携带丰富的信息来帮助我们调试问题。
追踪:单次请求范围内的信息,某次请求生命周期内所有的数据、元数据信息都被绑定到单个事务上。比如一次请求经过了系统中哪些服务或模块,在这些服务或模块上的处理状况(错误、时延等)如何。追踪数据占用的内存介于指标和日志之间,它的主要作用是串联系统各个服务或模块的信息,帮助我们迅速定位问题。
侧重指标:Prometheus、InfluxDB、Cortex、Zabbix、Nagios、OpenCensus等。
侧重日志:ELK、Fluentd、Splunk、Loggly等。
侧重追踪:Jaeger、Zipkin、SkyWalking、OpenTracing、OpenCensus等。
2 云原生下的日志解决方案
单体应用时期
在单体应用和物理机时期,我们通过在物理机上部署Filebeat将应用产生的日志按行进行收集,加入分类信息及封装。
服务容器化早期方案:Sidecar
Filebeat将作为Sidecar在Pod中采集对应路径下的日志文件并将其发送到Kafka集群。这种方案下的Filebeat配置与物理机时期非常相近,作为过渡方案改动相对较小。但是Sidecar运行时的资源消耗会对整个Pod造成影响,进而影响服务的性能。
服务容器化稳定方案:DaemonSet
将控制台中的日志(调试日志、请求日志、第三方日志)重定向到节点的存储位置,之后令节点中的Filebeat对日志所在的路径进行监控采集。这种方案能够有效地将Filebeat的运行与应用的容器和Pod分割开来,规避了在Pod中使用Sidecar对应用造成的资源损耗。以DaemonSet模式启动的Filebeat会对采集到的日志进行初步处理,在增添Kubernetes宿主环境信息且封装后,将信息传递到对应的Kafka集群中,作为Kafka集群消费者的Logstash会监听注册的topic中的消息并进行消费。当Logstash接收到新的消息时,会根据日志消息中的type(类型)来区分是调试日志、请求日志还是第三方日志,并根据日志类型的不同来进行不同的解析处理。最后,Logstash会将处理好的日志信息与其对应的Elasticsearch索引发送给Elasticsearch集群进行存储。
3 分布式追踪
核心概念
追踪(Trace):用来描述分布式系统中的一个完整的调用链,每个追踪都会有一个独有的追踪ID。
跨度(Span):分布式系统中一个小的调用单元,可以是一个微服务,也可以是一次方法调用,甚至是一个简单的代码块调用。
跨度中可以包含起始时间戳、日志等信息。每个跨度会有一个独有的跨度ID。
跨度上下文(Span Context):含额外追踪信息的数据结构,跨度上下文中可以包含追踪ID、跨度ID,以及其他任何需要向下游服务传递的追踪信息。
分布式追踪系统是如何实现跨服务调用时的问题定位的呢?对于一次客户调用,分布式追踪系统会在请求入口处生成一个追踪ID,用这个追踪ID将进入每个服务的调用日志串联起来,形成一个时序图。如图7-19所示,假设服务A的两端表示一次客户调用的开始和结束,中间会经过类似B、C、D、E等后端服务。此时如果服务E出现问题,该问题会被快速定位,无须让服务A、B、C、D都参与进来查找问题。
分布式追踪最常见的应用场景就是如上所述的快速定位线上问题,其还有以下几个典型应用场景。
生成服务调用关系拓扑图,优化调用链路。
分析整个应用系统的性能瓶颈并对其进行有针对性的优化。
根据完整的调用链路进行用户行为路径分析,进而对服务进行优化。
4 度量指标
当我们构建一个监控系统时,收集和观察业务日志能帮助我们细致了解当前系统的业务行为和处理状态。但是,一个实现完整可观察性的监控系统还需要收集、观察和分析更多的度量指标,做到运行状态实时可控。这里面的度量指标包括CPU的使用情况、内存的操作开销、磁盘的读/写性能、网络吞吐量等。
利用Prometheus收集度量指标
收集Kubernetes集群中应用的度量指标
收集Kubernetes集群中任务的指标
通过kube-state-metrics收集Kubernetes集群资源状态指标
使用Grafana展示度量指标
5 监控与告警设计
监控平台
基础设施监控:主要对网络、网关、EKS集群(包括节点状态、Istio等)这些设施的运行状态进行监控
微服务通用监控:主要对业务系统微服务通用指标进行监控,包括微服务Pod状态(CPU、内存使用情况等)、处理请求数、请求时延及请求结果等。
业务监控:是指根据各个服务的自身业务需求定义的监控,比如对某些大客户特定业务所自定义的监控。
微服务监控四大黄金指标
流量(Traffic):服务请求的数量,比如一定时间内完成的请求总数,每秒的请求数(QPS)等。
延迟(Latency):完成请求所花费的时间,包括平均时长、95分位数(p95)等。
错误(Errors):发生的错误请求。
饱和度(Saturation):当前服务的饱和度,主要考查受限制的资源,比如内存、CPU及磁盘状态等。通常这些资源饱和会引起服务性能的显著下降甚至使服务停止。
告警系统
异常情况的灵敏度:指标对异常情况的感知是最灵敏的,日志次之,而追踪最多用在排障定位的场景。告警系统主要建立在指标和日志数据之上。