沃卡惠移动端logo

沃卡惠  行业资讯

资讯详情

浅谈云原生可观测性

2023-10-26 09:56:044636

背景

当前数字化转型进程持续加速中,在顶层设计指导下,结合自身发展需要,全面推广一朵全栈云,深化云原生生态建设,推动业务应用大量采用微服务、容器等云原生技术,基于DevOps模式进行研发,将传统的单体服务拆分成粒度更细的微服务模块,使系统可以更好地适配容器化部署,更好地进行敏捷的业务迭代研发,快速输出系统业务价值。

云原生建设是一个综合性的系统工程,涉及微服务重构、国产信创、分布式数据库、容器云、服务治理等多个方面,系统规模和复杂度以及数据量成倍提升,可能发生故障的数量和类型也同比提升,全面有效的保障服务持续稳定运行至关重要,云原生安全运营是当下面临的重要课题。

面临的挑战

要保障服务安全运营,首先必须要能全面理解系统运行的状态和行为,这要求实现从底层到上层对网络、主机、容器、应用、业务服务等进行全栈可观测。可观测性(observability)最早来源于控制理论领域,指的是系统可以由其外部输出推断其内部状态的程度。在云原生架构中,可观测性描述的是对系统中所发生情况的掌握程度。云原生系统规模大、系统复杂、动态变化,对其进行全面、有效的理解和掌控,以及保障安全运营方面面临着巨大的挑战:

如何理解大规模动态容器环境中应用的实际运行情况:云原生系统通过容器化技术对基础设施进行了标准化,提升了应用部署的便利性,并支持动态扩缩容。基础设施层的信息通过虚拟化封装不再透明,微服务化架构使应用部署的服务数量急剧增加,容器集群根据业务运行情况动态调度。服务间流量既有南北向,也有东西向,且以东西向为主。在这样大规模动态服务实例的环境中,有效全面理解从应用、容器、主机到网络的运行情况,是保障业务安全运营的关键。

如何在复杂的服务调用间快速定位故障:单体服务拆分成微服务后,模块间的交互由进程内的方法函数调用转变为进程间的服务调用,导致服务的调用路径变长且跨越网络交互,当发生错误时怎样快速定位故障点,及时采取流量切换、服务回退等措施,是保障服务持续运行的关键;不同服务模块在整个系统中承担的功能不同,请求压力也不同,当系统出现性能瓶颈时,怎样快速发现出现瓶颈的服务并进行服务扩容,或者及时采取熔断限流措施,是保障服务稳定运行的关键。

如何保证观测能力的实时性:云原生应用的动态性要求可观测性平台必须具备实时性或近实时性。如果应用的升级或扩容在分钟级完成,那么监测系统就必须提供秒级的反馈能力。云原生系统产生的指标、追踪、日志等数据往往是海量的,因此对可观测性平台实时处理海量数据的能力提出了极高要求。

如何实现多个运维平台的有机整合:云原生生态涉及多个支撑系统,各系统的有机协调运行才能共同构成云原生运行平台,但现实是各个运维工具平台由不同时期、不同产品、不同厂商建设,怎样将这些运维工具平台的数据进行有效的治理,实现数据关联整合,充分发挥数据的价值,实现运维的全景运行、有机协调,是对运维数据治理能力的巨大挑战。

针对上述云原生架构带来的新问题与挑战,我们将尝试设计一套整体的云原生可观测性平台来解决上述担忧。

可观测平台设计

可观测性平台方案设计由可观测运维对象、可观测数据、数据关联性、可观测方案实现四部分组成,涵盖识别运维对象、可观测数据标准、不同数据关联实现,组成整体的可观测性方案,最后实现价值输出,具体如下:

可观测对象

云原生系统可观测体系需要涵盖从网络、主机、容器、应用、业务服务等所有云原生系统的组成部分,根据监控对象在系统中所处的位置,将可观测体系划分为四个层次,如图1所示,涵盖从系统基础设施、容器、应用到业务的全范围,分别为:

图1 云原生运维栈示意图

基础设施层:也即IaaS层,该层涉及的监控对象为系统底层资源,如网络、存储设备、裸金属等。这些设备与组件的可靠性,直接影响到上层应用服务的稳定性。该层关联的可观测性数据包含指标(网络流量、网络连接数、主机性能)、日志(交换机日志、操作系统日志)、事件(系统平台事件、故障、宕机)等。

容器层:也即,PaaS层,该层涉及的监控对象涵盖了容器内的系统资源,如:Kubernetes服务运行情况、集群节点、CPU、内存、存储等,是针对容器云平台进行的监控,这些资源的使用情况决定了应用服务的性能和容量。该层关联的可观测性数据包含指标(节点或容器的CPU使用率、内存使用率、存储使用率等)、日志(Kubernetes各个组件日志)、事件(Kubernetes Event)等。

应用层:该层涉及的监控对象和应用服务紧密相关,如:服务可用性、JVM、中间件等,这些监控对象的健康度与负载情况决定了应用之上运行的业务的可用性与性能。该层关联的可观测性数据包含指标(服务存活性、JVM内存使用率、JVM GC停顿时长、数据库连接、缓存连接、消息队列消息堆积数等)、链路(应用服务间调用、应用调用中间件形成的分布式链路)、日志(运行日志、错误日志)等。

业务层:该层涉及的监控对象主要涉及业务运行信息,如:交易量、交易金额、服务请求量、请求延迟、变化比率、错误率等,这些监控指标直接反应业务的运行状态,体现着用户体验与企业发展情况。该层关联的可观测性数据包含指标(访问统计、请求数、错误数、延时等)、日志(访问日志、错误日志)。

可观测数据

可观测性体系的构建是通过对系统运行状态数据的收集、分析来判断系统的运行状态并实现快速排障。因此,首先要定义可观测性数据,当前业界主流标准将可观测性数据分为三个类别:

图2 Metrics, tracing, logging及关联关系

指标(metrics):指标数据通常为一段时间内可度量的数据,也被称为时序数据,用于观测系统的状态与趋势,常用于画曲线图。支持以下四种数据:

类型

说明

示例

Counter

单调递增的计数器

http请求总数、QPS、TPS等

Gauge

支持加和减的计数器

CPU使用率、内存使用值、负载等

Histogram

直方图

对观察值(如请求持续时间或响应大小)进行采样,并统计样本分布,服务端可用于计算分位数(P95、P99)、Apdex指数,如果需要聚合或者观测值的范围和分布,可以选择直方图。

Summary

分位数

百分位(客户端直接计算),如果需要精确的分位数,选择Summary。

指标数据类型

指标效果展示

链路(tracing):分布式追踪是一种理解分布式系统执行过程中参与的上下游及影响,支持跟踪应用请求从前端到后端服务以及数据库等中间件的流转过程,支持对高延时与高错误率的请求进行故障排查。同时从链路数据中,可以提取出业务的RED(速率、错误、持续时间),丰富指标监控。

Trace路径感知与性能分析

Trace效果展示

日志(logging):日志数据是离散事件的记录,反应系统运行过程中产生的信息,可以详细解释系统的运行状态。大多数开发语言、应用程序框架或库都支持日志。日志可以分为不同的类别,例如系统日志、应用日志、安全日志、基础设施日志。日志中存储的信息是无格式的文本,需要制定对应的字段规范以便于后续分析,例如日志包含服务名称、traceid,并附加采集的容器信息。

日志展示

数据关联性

可观测对象虽然划分为四层,但在实际使用时,通常需要结合多层数据和多个运维工具平台中的数据一起来分析问题,这就需要观测数据存在一定关联性。如下图所示:

数据关联性

从数据特性上可以区分为:

同一运维对象关联

同一运维对象应该具有确定且唯一的标识,在不同数据中(指标、链路、日志)应该使用统一的标识标准,用户可以使用同一套标识分别查询到不同数据,以方便关联分析。例如根据Prometheus告警中带的标签和时间戳,可以在日志中定位到对应服务在特定时刻的行为,在链路中也可以定位到对应服务特定时刻的执行链路。

相同运维对象和对应的指标和日志数据

不同运维对象关联

不同运维对象间的关联关系比较多样化,需要具体问题具体分析。在传统的环境中,我们通常基于IP进行不同主机、网络节点进行标识和关联,而在容器云环境中,通常基于标签标识不同运维对象和资源,不同资源类型不同,但应该具有相同的标签,这样才能实现组合。例如Kubernetes中Deployment与Service中的定义必须匹配对应的Labels才能实现匹配和对应功能。

不同运维对象基于标签识别关联

链路ID关联

在分布式环境中,应用服务被拆分为不同的服务模块,一个服务请求会跨越多个不同的运维对象,运维对象也服务于多个不同请求,这种分布式并发性使得如何区分不同请求成为一个难题,这个问题与TCP服务于多个请求的问题类似,HTTP1.1没有请求标识,无法多路复用,HTT2中加入了流标识才可以,类似的,不同应用间服务请求加入唯一的标识ID即可区分彼此。基于链路ID的链路跟踪可以将一次分布式请求还原成调用链路,对一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等,实现调用拓扑可视化、上下游依赖分析、故障快速定位等。

基于traceid关联多个运维对象的日志和链路

利用上述运维对象和数据的关联性,并结合梳理的全栈运行环境(图1),包括基础设施、容器云平台、应用和业务信息,构建整体的全景可观测性拓扑图,针对不同组件、不同层面的运维对象分别展示不同观测数据,并与CMDB信息联动,实现直观的拓扑信息展示。

全栈监测拓扑示意图

可观测实现

可观测性体系的实现分为三大流程:可观测性数据采集、可观测性数据分析、可观测性数据价值输出,覆盖可观测性数据的产生、采集、处理分析、存储、应用的全流程。

可观测性数据采集

    数据采集

    该流程主要完成可观测性数据的规范化定义与采集,包括指标、链路、日志三类数据。怎样保证采集数据的完整性以及对应用的无侵入性,是方案需要考虑的关键。指标数据为时序数据,数据结构相对固定,在设计时需限制表示业务信息的标签数量与取值范围,避免数据量过大,对指标服务端的性能造成影响。针对Kubernetes平台、业务应用、中间件等,采用服务端拉取的模式进行采集,在相应的服务器上部署独立的指标采集组件,这些组件负责收集指标数据并通过HTTP协议对外提供指标查询接口,由指标服务端(如Prometheus)定时调用。针对业务应用,使用Java Agent技术在JVM应用启动时进行JVM字节码的增强,在不改变业务代码的前提下进行JVM性能指标与业务指标的生成,实现监控逻辑与业务逻辑解耦,保证开发流程的扩展性。以上采集过程均能做到对应用无侵入。

    为了保证链路数据结构相对固定的同时提高数据扩展性,链路数据结构采用半结构化的JSON格式。对于链路数据,在开发框架中引入链路埋点库。该库对于服务间调用、服务调用主流中间件(如数据库、缓存、消息队列等)等关键程序执行位置自动埋点,提供了通用链路采集埋点逻辑,引入该开发库就能自动完成相应位置的链路采集。同时提供了手动埋点能力,供开发团队基于自身业务需求,自定义链路埋点代码以采集特定场景下的链路信息。通过无侵入埋点解决通用链路采集并结合手动埋点满足个性化定制需求的方式,在较少代码侵入的情况下,满足应用全面链路采集的需求。

    考虑到日志数据后续解析、处理的统一标准化,业务团队需制订并实施标准化的日志数据结构规范。对于日志数据,采用独立组件上报的模式进行采集,在相应的服务器上部署独立的日志采集组件(如Filebeat、Flunetbit),负责完成本地日志数据的读取、上报日志服务端(如ElasticSearch、Loki、ClickHouse)。日志采集组件使用通用的采集配置模板,以便运维人员快速修改进行本地日志采集,提升日志接入监控的效率,并于开发约定双方日志目录,实现双方解耦。

    可观测性数据分析

    指标分析处理

    指标采集端(如Prometheus、Grafana Agent)将从指标采集组件中采集到的指标,首先根据不同指标的特征在内存中进行聚类,对于内存中存储时长超过两个小时的指标数据,进行压缩并存储在磁盘中,以实现长久存储指标数据的目的(使用Thanos)。采用定时触发器的方法(Prometheus record rule),定期从时序数据库中读取指标数据,对其进行聚合分析,然后生成聚合指标,以支持高层抽象粒度分析。此外,由于指标监测数据随时间价值降低,但存储成本随时间增加,将历史数据进行压缩降采样(Thanos downsampling),在保留更长历史数据的同时减少存储成本,而且还可以提升查询效率。

    链路/日志分析处理

    链路服务端接收到客户端上报的链路数据后,首先将链路数据推送到消息队列(如Kafka)中,使用消息队列的高性能流式处理特性,为链路数据的后续分析、存储提供性能保障。之后,一方面链路存储应用读取消息队列中的链路数据,将其直接存储在全文检索中间件(如ElasticSearch)中,另一方面链路分析应用读取消息队列中的链路数据,在内存中进行链路数据的聚类分析,以构建系统服务拓扑,服务拓扑信息包含系统中组成分布式链路的所有应用、应用间调用的计数与平均延时、应用内部的错误分布,链路分析应用将分析后的数据也存储在全文检索中间件中。使用全文检索中间件存储链路数据与服务拓扑数据,可支持实现后续丰富的数据检索场景。

    日志服务端与链路服务端类似,日志服务端(如ElasticSearch、Loki)接收到日志采集组件上报的日志数据后,由日志解析组件基于预先定义的日志解析规则,对日志数据进行格式解析与数据过滤,并将解析后的数据构建成标准JSON数据格式,分类存储在全文检索中间件(如ElasticSearch)中。日志解析组件为集群部署,通过并行的流式处理,保证解析过程的高性能。日志解析规则支持多种日志解析格式,如JSON、Logfmt等,以及支持自定义日志解析器,让运维人员可以自定义日志格式,以满足不同业务场景的需求。

    可观测性数据价值输出

    可观测性价值输出示例——指标大盘

    通过统一的可观测性平台,提供一体化、可配置化、可视化的监控、告警、排障、日志检索等能力,实现可观测体系的价值输出,包括故障告警、监控大屏、链路检索、日志检索等功能。故障告警,提供针对系统故障的自动化实时告警功能。该功能支持用户自定义基于指标、日志关键词的告警规则,自动触发告警,并通过多渠道(邮件、通信软件)实时发送告警通知,保证运维人员能第一时间发现系统中的异常情况。监控大屏,提供针对系统当前运行状态的监控图表展示功能。该功能支持用户基于预设的大屏模板创建监控大屏,监控大屏实时调用指标服务端的指标数据查询接口,生成监控面板。监控面板支持丰富的指标展示形式,如:折线图、柱状图、饼图、度量仪等,方便运维人员在开发、测试、生产阶段,直观、高效的了解系统当前情况,或进行故障分析与定位。

    可观测性价值输出示例——排障

    链路检索,提供链路数据查询、链路详情展示、服务拓扑分析功能。该功能支持用户基于链路ID或者时间范围查询链路数据。在分布式链路详情页面中,可以直观看到请求在系统内流转时经过的应用服务关键路径,以及每个处理阶段的具体耗时情况。开发、运维人员可以利用链路检索功能,进行快速的故障定位,分析各个调用环节的性能与可用性,或者统计分析用户行为数据日志检索,提供日志数据查询与分析功能。运维人员可以借助日志检索功能,从分布式系统的海量日志中,快速定位到所需日志,以进行基于日志的故障原因排查或者业务数据统计。

    通过可观测性体系设计,对复杂的云原生系统不同层次的监控对象,执行可观测性数据采集、分析、价值输出流程,实现云原生系统的全范围监控,支持快速洞察系统当前运行状况;针对系统故障进行实时告警,通过多维监控工具辅助快速的故障定位与解决,保障系统可用性;该体系提供的监控能力,同样可以应用在系统开发与测试阶段,用于快速排查开发问题,辅助进行应用性能观测,提升业务交付的效率与质量。

    未来展望

    可观测性平台

    在平台建设过程中,我们发现关于云原生系统的可观测性体系,仍然有可以持续深耕的领域:

    持续剖析(Continues Profilling),是一种深入分析程序复杂性和性能的动态方法,例如CPU利用率或函数调用的频率和持续时间。通过持续剖析可以准确定位应用程序的哪些部分在哪个时刻消耗的资源最多,这为优化核心程序执行性能提供了一个可靠的方案。

    OpenTelemetry (OTEL)标准,由OpenCensus和OpenTracing项目合并形成的CNCF项目,是一个供仪表化、生成、收集和导出遥测数据(跟踪、指标和日志)使用的供应商中立的开源可观测性框架。提供了一组标准规范和工具集,规范可观测性数据的数据模型、数据采集、数据处理、数据治理和数据导出。目前各个主流开源项目(包括Kubernetes、Spring Cloud)都已经开始支持或切换到OTEL,是CNCF未来主推方案,值得关注。

    eBPF(Extended Berkeley Packet Filter),是一种数据包过滤技术,从BPF(Berkeley Packet Filter)技术扩展而来。自Linux 4.14内核以来,Linux社区为eBPF加入多个新特性和优化改进,提升了eBPF在跟踪分析、可观测性、安全和网络加速等场景的应用能力。eBPF在内核中实施观测和跟踪,可以实现无侵入性的持续剖析,并基于各种可能的来源生成可见性事件,扩展了可以实现的可见性深度。

    扩展到系统层面的全栈全链路观测能力——采集

    扩展到系统层面的全栈全链路观测能力——透视

    未来,基于eBPF在操作系统内核态实施可观测性,与用户态OpenTelemetry结合建立云原生观测数据收集处理的标准范式,并引入持续剖析,不断扩展可观测性深度和广度,将成为增强云原生环境可观测性未来发展的趋势。

    总结

    云原生架构在提升企业系统交付效率的同时,也使得系统的复杂性成倍提升,因此如何使系统具有可观测性,系统内部状态易于洞察变得尤其重要,系统可观测性平台正是云原生趋势下的必然产物。本文阐述了云原生系统可观测性平台的从数据采集、分析、存储、价值输出的关键技术方案与数据间的关联关系,以及如何利用可观测性平台高效进行故障定位与解决,降低故障定位与解决的运维成本,在最大程度上保障云原生系统的高性能与高可用性。同时,随着操作系统eBPF、Opentelementry、人工智能机器学习等技术的不断发展,可观测性技术一定会在信创和云原生场景中发挥更大作用,推动下一代监控技术的发展。