转载自微信公众号:码神手记
原文地址: mp.weixin.qq.com/s/JB--u4S2B…
近两年,多次看到“可观测性(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。
论文地址: research.google/pubs/pub363…
论文介绍了Google生产使用的大规模分布式系统跟踪基础设施-Dapper。Dapper的概念和实践奠定了可观测性领域的基础,在学术和工业界产生广泛影响。Trace、Span等如今耳熟能详的概念也由此诞生。
Dapper Trace收集流程(图片出自Dapper论文)
设计目标
低开销
对应用层透明
可伸缩,轻松用于大规模系统
核心概念
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。
Zipkin应用架构(图片来自Zipkin官网)
应用架构
引入Tag概念
Annotation强调描述和记录Span的基本上下文信息,比如:接口名称、Span开始结束时间等信息,Tag则强调对Span的属性和特征进行标记分类,用于分组、筛选、过滤。
2012年-Prometheus
Prometheus应用架构(图片来自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应用架构
上图就是可用于生产的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应用架构(图片来自Grafana Loki官网)
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分布式追踪工作组进入正式运作阶段,目标是制定分布式跟踪工具之间的互操作标准。
工作组主页地址:
www.w3.org/groups/wg/d…
2020年10月20日发布了Baggage格式标准的草稿。
草稿地址:www.w3.org/TR/baggage。…
2021年11月23发布了Trace上下文信息的推荐性标准。
标准地址:www.w3.org/TR/trace-co…
2019年-SkyWalking
Skywalking应用架构图(来自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项目。
项目地址:
github.com/orgs/open-t…
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。
以上想法算是抛砖引玉吧,欢迎大家踊跃交流,各抒己见。