建立可观测性宏观认知 - 从概念到过去 10 年的实践发展
近两年,多次看到“可观测性(Observability)”一词,在大多数人脑海中,可观测性是监控。从业多年,亲身经历了移动互联网的辉煌崛起,在工作中零散地接触过各种相关技术和工具,但从未从宏观视角系统思考过“可观测性”。
因此,我将在这篇文章中系统性地梳理一下可观测性的知识结构和信息,也希望读者能从中受益。
可观测性哲学三问
将哲学三问切换到“可观测性”领域,就变成了以下三个问题:
概念:是什么?从控制论这一学科中寻找答案。
起源:从哪来?看看早期的可观测性实践做了什么,解决了什么问题。
发展:到哪去?新时代带来新挑战,从开源生态的发展历程中总结可观测性发展趋势。
控制论与可观测性
观测是为了更好地控制系统,从而获得期望的输出。
1948 年,维纳的《控制论》出版,成为控制论这一学科诞生的标志。控制论是一门研究系统稳定性和行为的学科,它关注如何通过控制输入来使系统达到所期望的输出。
可观测性正是控制论中的一个重要概念,是控制策略设计的基础,用于表示系统内部状态和输出被观察测量到的程度。这句话很好地回答了”可观测性是什么?“这一问题。
计算机系统本质上也是一种复杂的系统,涉及到多个组件和子系统之间的相互作用和调节。控制论为计算机科学提供了设计和优化系统控制策略的一种理论和方法,而可观测性则提供了监测和度量系统行为和性能的手段,从而对控制和调节进行有效的支持。
可观测性的早期实践
经典的系统监测方法囊括三个方面,它们通常也被称为可观测性的三大基石,可观测性的发展一直围绕且将持续围绕这三个基本点。
Log:日志
Trace:跟踪
Metric:指标
在计算机科学和信息技术领域的早期发展阶段,就已经出现了以上概念的应用:
1980 年代-BSD Unix 系统的 Syslog:提供了一种标准化的机制,允许系统中的各个组件和应用程序将日志消息发送到 Syslog 守护进程。Syslog 守护进程负责接收、存储和转发这些消息,以便管理员可以集中管理和分析日志数据。Syslog 的设计思想和基本架构奠定了日志记录和集中管理的基础,为后来的日志管理工具和平台提供了借鉴和参考。Syslog 的消息格式和传输方式在 RFC 3164 中进行了标准化,该 RFC 于 2001 年发布。
1990 年代早期-Apache Web 服务器:使用日志文件记录每个请求的详细信息,包括访问时间、来源 IP、请求方法和 URL 等。这些日志文件帮助网站管理员了解网站流量和用户行为。
1995 年-Java 支持追踪机制:如 java.util.logging 或第三方库,允许开发人员在代码中插入追踪指令,记录方法调用和异常信息,以便进行调试和错误排查。
2002 年-NET Framework 支持追踪机制:开发人员可以使用 Trace 类将自定义追踪消息写入事件日志或跟踪文件,用于应用程序的调试和监控。
2003 年-MySQL 的二进制日志:即 Binary Log(binlog),用于记录数据库的写操作,包括插入、更新和删除等操作。这些日志文件对于数据恢复和复制非常重要。
2003 年-AWS 的 CloudWatch 服务:提供了对云资源的监控和指标收集功能。用户可以收集和分析诸如 CPU 使用率、网络流量、磁盘 IO 等指标,以评估资源的性能和可靠性。
从历史实践来看,Log 是最早被广泛应用的,其次是 Trace,最后是 Metric。经典系统监测方法在操作系统、Web Server、开发语言、数据库、云平台等不同领域都发挥着重要的作用。
在 2020 年代的今天,对于很多处于建设初期的信息系统,它们可以没有 Metric、Trace,但一定会有 Log。Log 本身也可以作为细节更加丰富的附加信息被关联到 Metric 和 Trace 中。某种程度上,我认为 Log 是基石中的基石,优秀的可观测性系统离不开高效的 Log 采集。
关于 Log,你一定经历过下面的场景,在基建不太完善的小公司中尤为明显:
晚上 20:00,下班回家!
客户:系统有问题,登录不进去,快给解决一下,急用!
你:重新坐下!打开电脑,打开终端,登录服务器,cd...cd…再 cd 进入日志目录,ls 命令列出日志文件。巧了,有一堆错误日志:xxx-error.log。
你:cat、grep...,若干个 linux 命令玩儿得明明白白。半小时后,你找到了客户登录出错的那条错误信息,发现了一个 NullPointerException。”
你:打开代码编辑器,根据异常信息找到对应的代码,分析调试。1 小时后,你悟出真相:“在 xxx 情况下,这个对象没有实例化”。又是 1 小时以后,你终于把修好并测好的代码部署到线上。
此刻是晚上 22:30,下班!
作者源于现实的虚构场景
假如你面临的是一个由几十上百台服务器构成的分布式系统呢?要一台一台查日志吗?22:30 下不了班,根本下不了!在多台机器上人工筛查日志是众多让人心力憔悴的悲催场景之一,我们面临的挑战也不止于此。
新时代的挑战
早期的可观测性实践多用于单体架构系统,拓扑结构简单,不需要跨越不同网络边界。随着分布式、微服务、云原生架构的兴起,系统观测方法需要针对以下几个方面继续进化:
大规模部署:一个电商系统由数十个微服务组成,每个微服务都有自己的日志和指标,并部署了多个实例。传统的日志和指标收集方法无法高效地分析大规模集群中每个组件的性能和健康状态。
高度动态性和弹性:一个容器编排平台上运行的微服务应用,根据负载自动扩展和缩减实例数量。监测工具需要实时监测每个容器的资源利用率、健康状态和弹性扩缩容情况,以便运维团队实时了解系统的规模和性能,及时发现和解决问题。
多层次依赖关系:一个电商系统中,订单、用户和支付等多个微服务相互依赖。当支付出现性能问题时,传统的监测方法只能捕捉到支付服务自身的单一指标,难以准确追踪到问题根源所在的订单或用户服务。
我按时间线顺序梳理了开源生态中与可观测性相关的里程碑事件,期望从中参悟可观测性领域的发展和重要成果。当遇到相关问题场景时,也可作为参考信息去思考解决方案。
开源生态里程碑
2010 年-Google Dapper
2010 年,Google 发布了一篇论文:Dapper, a Large-Scale Distributed Systems Tracing Infrastructure。
论文地址: https://research.google/pubs/pub36356
论文介绍了 Google 生产使用的大规模分布式系统跟踪基础设施-Dapper。Dapper 的概念和实践奠定了可观测性领域的基础,在学术和工业界产生广泛影响。Trace、Span 等如今耳熟能详的概念也由此诞生。
设计目标
低开销
对应用层透明
可伸缩,轻松用于大规模系统
核心概念
Trace(跟踪):代表着一个完整的请求或操作路径。它由一系列相关的 Span 组成,描述了请求在分布式系统中的流转和处理过程。
Trace ID(跟踪 ID):每个 Trace 有一个唯一的标识 ID。
Span(跨度):表示一个特定的操作或事件。它包含了起始时间、持续时间、相关的上下文信息和标签等。Span 用于记录和追踪请求在系统中的流转,并捕捉与请求相关的关键信息。
Span ID(跨度 ID):每个 Span 有一个唯一的标识 ID。
Annotations(注解):Span 中的附加信息,用于记录操作或事件相关的关键数据。可以包含任意的键值对,例如请求的 URL、响应码、错误信息等。可使用 Annotations 丰富 Span 的上下文信息,方便后续的分析和调试。
Sampling(采样):Dapper 中的一项重要策略,用于控制在高负载环境下的跟踪数据量。由于大规模系统中可能会产生海量的 Span 数据,为了减少存储和处理的负担,可以使用采样策略,只选择部分请求进行跟踪,而忽略其他请求。
2012 年-Twitter Zipkin
2012 年,Twitter 开源了一个分布式追踪系统:Zipkin。以 Dapper 的设计思想为基础,可观测性领域的重要里程碑,促进了分布式追踪的普及和应用。Java 工程师应该都知道 SpringCloud,Spring Cloud 中的分布式追踪组件 Sleuth 就是集成了 Zipkin。
应用架构
instrument libraries(仪器化库):用于在应用程序中插入跟踪代码的库。为开发人员提供了用于捕获和记录跟踪数据的 API 和工具。
Reporter(报告器):负责收集应用程序中生成的跟踪数据,并通过 Transport 发送出去。
Transport(传输):定义了跟踪数据的传输方式和协议(HTTP、Kafka、gRPC)。它负责将跟踪数据从应用程序发送到 Zipkin 服务器或其他跟踪存储后端(Apache Skywalking、Jaeger、Pitchfork)。
Components(Zipkin 核心组件):
collector(收集器):用于接收、验证跟踪数据,存入 storage 并构建索引。
storage(存储):支持的存储包括 Cassandra、Elasticsearch、MySQL、内存等。
search(搜索 API):提供查询接口服务。
web ui(WEB 交互界面):用户通过 web 界面查看跟踪数据。
引入 Tag 概念
Annotation 强调描述和记录 Span 的基本上下文信息,比如:接口名称、Span 开始结束时间等信息,Tag 则强调对 Span 的属性和特征进行标记分类,用于分组、筛选、过滤。
2012 年-Prometheus
SoundCloud 在 2012 年开源了 Prometheus,于 2016 年加入 CNCF,成为继 Kubernetes 之后的第二个 CNCF 托管项目。Prometheus 按照时间序列存储 Metric 数据,Prometheus server 可以主动从仪器化的监控对象中拉取 Metric 数据,也可以通过 Pushgateway 接收监控对象推送的 Metric 数据。
Alert manager 是 Prometheus 生态系统中的一个组件,用于处理和管理报警规则的触发和通知。它接收来自 Prometheus server 的报警信息,并根据预先定义的报警规则进行处理,比如发送邮件、IM 机器人消息、通过对接的呼叫中心拨打报警电话、通过对接短信网关发送报警短信。
我们可以使用 PromQL 在 Prometheus Web UI 中检索、分析实时指标数据,也可以使用 Prometheus 的数据在 Grafana 中创建更加复杂、美观的监控仪表盘。
直至今日,依然有许多公司会基于 Prometheus+Grafana 实现监控告警。
2014 年-ELK
ELK,即 Elasticsearch + Logstash + Kibana。作为 elastic 公司提供的日志采集、展示、分析的整体解决方案受到广泛关注,并在 2014 年左右成为行业标准。Logstash 用于日志收集、传输和处理,Elasticsearch 用于日志存储并提供搜索和分析能力,Kibana 则用于可视化分析日志数据。
通常在使用 ELK 方案时,会在 ELK 基础上加入 Kafka 消息队列,Logstash 将采集到的日志送入 Kafka 队列,消费者程序从 Kafka 中消费数据,进行适当的格式处理等工作后存入 Elasticsearch。消息队列的引入,使 ELK 方案具备了应对大规模日志数据流时的削峰填谷能力。
你以为这就足够了吗?
Logstash 的运行依赖 JVM,资源占用较多,配置复杂,不够轻量,不适合在容器化部署方案中使用。因此,在 2015 年出现了一种改良方案,用 Filebeat 代替 Logstash,负责日志的采集。Filebeat 也是 elastic 公司的产品,使用 Go 语言开发,配置简单,十分轻量,在资源占用上明显优于 Logstash。在 Kubernetes 中,可以以 DaemonSet 的方式部署 Filebeat。
上图就是可用于生产的 ELK 日志采集、展示、分析方案的架构。从这套方案中,可以总结出一个通用的抽象流程:
采集
投递到消息队列
异步消费处理
存储
查询分析
这样的流程基本适用于所有的日志采集方案,当我们把 Filebeat、Kafka、Logstash、Elasticsearch、Kibana 中的一个或若干个组件换成其它同类实现,整套流程依然可用。
2016 年-Open Census
Open Census 于 2019 年被合并到 Open Telemetry 项目,此处不做过多描述。
2016 年,Google 发布了 Open Census,一款厂商中立、多语言跨平台、低开销的分布式 Trace 和 Metric 库,提供一致的 API 和数据格式。
提出 Exporter 概念:和 Zipkin collector 作用相似,用于将收集到的 Trace 和 Metric 数据导出到各种后端存储和分析系统中。
支持 Sampling(采样)机制。
支持 Tag:和 Zipkin 中的 Tag 作用一致,用于对 Span 的属性和特征进行标记,用于分类、过滤和聚合 Span 数据。
提出 Resource 的概念:Compute Unit(Container/Process/Lambda Function)、Deployment Service(如 Kubernetes)、Compute Instance(如 Host)、Environment(如 Cloud)都属于不同的 Resource 类型。
2016 年-Open Tracing
Open Tracing 于 2019 年被合并到 Open Telemetry 项目,此处不做过多描述。
2016 年,由 LightStep、Google、Uber 等公司共同推出的一款厂商中立、多语言跨平台的分布式追踪库,提供标准化追踪 API。
提出 SpanContext 概念:封装 traceid、spanid、其它以键值对形式的附加信息,并在 Span 之间透传。用于跟踪和关联不同组件的 Span。
支持 Tag:用于对 Span 的属性和特征进行标记,用于分类、过滤和聚合 Span 数据。
提出 Baggage Item(行李物品)概念: 用于在 Span 之间传递业务自定义的键值对数据,比如自定义的业务参数。
2018 年-LPG
LPG,即 Loki+Promtail+Grafana。这是一套相对较新的日志管理方案,成本要低于 ELK 方案。自 2018 年起逐渐受到关注和采用,特别是在容器化和云原生环境中。
Loki 是一个由 Grafana 开发的开源日志聚合系统,设计目标是为容器化和云原生环境提供高效的日志收集、存储和查询解决方案。
Promtail 是 Loki 的日志收集和传输工具。它负责从各种源(如本地日志文件、系统日志、容器日志等)收集日志数据,并将其传输到 Loki 进行存储和索引。Promtail 提供 Pipelines 能力用于过滤日志内容,Pipelines 的操作分为四种:解析、转换、动作、过滤。
Grafana 是一个流行的开源可视化工具,于 2014 年发布,提供了丰富的仪表盘和图表功能。Grafana 不仅能够和 Prometheus 搭配,实现各种监控图表,也可以和 Loki 搭配,实时监控和分析日志数据。
2018 年-W3C Distributed Tracing Working Group
2018 年,W3C 分布式追踪工作组进入正式运作阶段,目标是制定分布式跟踪工具之间的互操作标准。
工作组主页地址:
https://www.w3.org/groups/wg/distributed-tracing/。
2020 年 10 月 20 日发布了 Baggage 格式标准的草稿。
草稿地址:https://www.w3.org/TR/baggage。截止到本文发布,该草稿最近一次更新时间是 2023 年 8 月 10 号。读者感兴趣的话,可以访问以上地址查看最新动态。
2021 年 11 月 23 发布了 Trace 上下文信息的推荐性标准。
标准地址:https://www.w3.org/TR/trace-context-1。W3C 关于分布式追踪的标准制定工作一直在持续当中。以 W3C 的权威性,其所制定的标准将有力推动分布式追踪领域的互通互联。
2019 年-SkyWalking
2015 年,中国人吴晟发起了 SkyWalking 项目,并在 2017 年底加入 Apache 孵化器,2019 年顺利毕业,成为 Apache 顶级项目。
SkyWalking 是用于分布式系统的应用程序性能监控工具,专为微服务、云原生和基于容器(Kubernetes)架构设计。截止到目前,SkyWalking 已发展成为 All-in-one 的 APM(Application performance monitor)解决方案,提供的能力涵盖了分布式跟踪、指标收集、日志管理和报警。SkyWalking 支持来自多种可观测生态系统的 Metric、Trace 和 Log,比如:Zipkin、OpenTelemetry、Prometheus、Zabbix 和 Fluentd。对 eBPF 技术的使用,也使能够观察到的数据从用户空间扩展到了内核空间。
另外值得一提的是 SkyWalking 自研数据库-BanyanDB,BanyanDB 是 SkyWalking 的子项目,这是一个专注于获取、分析、存储 Metric、Trace、Log 数据的可观测性数据库,专用于 APM 领域,于 2022 年 6 月发布了第一个版本并支持集成到 Skywalking 9.1.0。不过尚无公司在生产环境中使用。我在 Slack 中问了吴晟本人,回复如下:“0.5 发布之后(2023 年 10 月底),才建议尝试生产部署。” 让我们拭目以待吧!
在 APM 数据库领域,BanyanDB 是首创,它很好地将时序数据、键值数据以及一些 APM 领域的元数据融合在一个库内。SkyWalking 最早是用 HBase 作为底层存储,之后全面转向 Elasticsearch,利用它强大的搜索功能来实现快速的数据检索,但使用 Elasticsearch 存储成本较高,需要大量的存储空间来获得较高的查询性能。
2019 年-CNCF Open Telemetry
Open Census 和 Open Tracing 在目标、API 设计和社区支持上存在重叠,为了避免混淆和重复劳动,2019 年合并为 CNCF Open Telemetry 项目。
项目地址:
https://github.com/orgs/open-telemetry。
Open Telemetry 提供了一个统一的标准和工具集,用于仪器化、生成、收集和导出观测数据(Metric、Log、Trace)。Open Telemetry 的标准与 W3C 标准并不冲突,项目贡献者中不乏有参与 W3C 标准制定工作的。
Open Telemetry 可以集成各种数据源、工具,包括 Prometheus、Jaeger 和 Elasticsearch,以提供全面的监测和分析能力,上文提到的 SkyWalking 也可以作为后端服务接收 Open Telemetry Collector 所收集的观测数据。
Open Telemetry 对不同语言生态的支持进度不尽相同,对部分语言只能稳定支持 Log、Trace、Metric 三者中的部分,但对于活跃的开源社区来讲,这并不是个问题,对主流语言(Java、Golang 等)的支持还是相对完整的。
Open Telemetry 核心内容包括:
Signals(信号)
Instrumentation(仪器化)
Components(组件)
Semantic Conventions(语义约定)
Sampling(采样)
SDK Configuration(SDK 配置)
详细内容可以到 OpenTelemetry 项目官网查看。
思考与总结
从开源生态的发展中能总结出什么?
仁者见仁,智者见智。个人总结如下:
标准与流程:从 Dappor 提出概念,到后续各种开源实现的一脉相承,并加入新的概念。可观测性的概念模型逐渐细化、完备。CNCF Open Telemetry 项目是统一标准的重要里程碑。从客户端集成 SDK 并生成观测数据,到传输、处理、存储、分析,可观测性的工程实践流程也变得清晰明了。
一体化趋势:从某个产品专注于 Trace、Log、Metric 中的一项能力,到 All-in-one 解决方案的出现。All-in-one 显然更符合用户的需要,开箱即可获得完整的观测能力。
智能化趋势:引入统计、机器学习手段,基于历史时序数据自动识别故障模式、调整阈值等等是完全具有可行性的。已经有公司在做这方面的事情。
如何从 0 到 1 落地系统可观测?
我的核心关注点如下:
标准:兼容被广泛认可的行业标准,即:Open Telemetry。
功能完备:分布式追踪(Trace)、日志采集与分析(Log)、指标分析与报警(Metric)。SkyWalking 确实是个不错的选择。
可能的方案:
仪器化:将 Open Telemetry SDK 集成到基础开发框架中,同时支持开发人员自定义各类指标。使用 prometheus exporter 对数据库、服务器、k8s pod 等进行监控数据采集。
数据收集处理:部署 Open Telemetry Collector 接收并处理观测数据,发送到 SkyWalking Server。
告警:在 SkyWalking 中配置各项 metric 的告警规则,对接到钉钉、飞书、短信、电话等通知渠道。
查询分析:使用 SkyWalking 提供的 UI 以及 Dashboard。
以上想法算是抛砖引玉吧,欢迎大家踊跃交流,各抒己见。
版权声明: 本文为 InfoQ 作者【刘绍】的原创文章。
原文链接:【http://xie.infoq.cn/article/b8947d13f34db03c080d5125b】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论