跟着 iLogtail 学习高质量软件建设

余韬

本文根据 iLogtail PMC 成员余韬 2024 年 6 月 26 日在 DBAPlus 社群的公开直播《云上千万级可观测 Agent SRE 实践》整理而成。

1. 引言

近年来,关于可靠性工程这一话题的热议不断升温,这主要归因于当前形势的显著变化。

首先,行业竞争日益激烈,以往的蓝海市场或空白领域已逐渐饱和,企业普遍面临同质化竞争的挑战。以公有云市场为例,2021-2023 年公有云市场增速迅速降温,同时新玩家的入局使得竞争日趋激烈。在如此高度竞争的环境中,更低的成本与更高的质量成为了企业在市场中立足的决定性因素。

其次,这两年互联网行业重大故障不断,经济压力下的降本增效使得单纯依赖人力提升系统稳定性的策略显得捉襟见肘,运动式攻坚项目形式的稳定性工程实践在业务长期发展中被证明难以为继,稳定性建设的高投入低成效推动企业探索更为科学的手段提升软件研发与质量管理效率。

再者,随着产业升级的推进,众多互联网公司从传统的 ToC 模式转向 ToB 领域,这不仅对软件研发能力,也对工程实施能力提出了更高的标准和要求。与 ToC 业务的不同,ToB 业务具有更高的获客成本和客户终生价值,客户对产品的质量容忍度也远小于 ToC 产品。ToB 客户自身安全合规的组织要求和更加严格的流程,使得对系统维护响应速度较慢。为了弥补,就要求在质量保证体系上有更严格的质量保障要求。

这些因素共同作用,使得可靠性工程问题备受关注。

2. 千万级可观测 Agent 的稳定性挑战

2.1 业务背景

可观测性是从系统内部出发,基于白盒化的思路去监测系统内部的运行情况。在分布式IT系统中,可观测平台使⽤⽇志、指标和跟踪等类型数据来度量基础设施、平台和应用程序,以了解他们的运行状态和过程。这些数据的收集通常由一个与被观测对象共同运行的采集 Agent 完成。iLogtail 是阿里云日志服务(SLS)团队自研的可观测数据采集 Agent,拥有的轻量级、高性能、自动化配置等诸多生产级别特性,可以署于物理机、虚拟机、Kubernetes 等多种环境中来采集遥测数据。

iLogtail 在阿里云上服务了数万家客户主机和容器的可观测性采集工作,在阿里巴巴集团的核心产品线,如淘宝、天猫、支付宝、菜鸟、高德地图等也是默认的日志、监控、Trace 等多种可观测数据的采集工具。目前 iLogtail 已有千万级的安装量,每天采集数十 PB 的可观测数据,广泛应用于线上监控、问题分析/定位、运营分析、安全分析等多种场景,性能和稳定性是其广受信任的基石。

iLogtail 研发团队始终坚守可靠性工程的高标准,稳定安全高性能一直是 iLogtail 的核心竞争力。实践证明,可靠性工程的不断投入能有力推动业务的持续发展。只有当 Agent 展现出足够的稳定性,关键业务才会放心使用,它才会在更广泛的场景中落地,从而提出更高的功能需求。随着使用场景的扩展,我们会遇到更多新的挑战和问题,这需要我们投入更多的人力去解决。在解决这些问题和开发新功能的过程中,iLogtail 的能力和稳定性会得到进一步增强。这种提升不仅会催生新的业务场景,也会激发更多的创新需求和优化点,形成一个良性循环。

2.2 iLogtail 特有的稳定性挑战

作为一个使用场景众多,运行在不同环境,拥有海量部署的客户端软件,iLogtail 的稳定性面临以下特有的挑战。

  • 业务迭代快环境变化多
    • 新业务数据源
    • 新输出下游
    • 新处理方法
    • 新环境适配
  • 客户端控制能力弱
    • 版本难以收敛
    • 客户环境因素
    • 操作人员不可控因素
  • 部署数量多影响大
    • 集团内自动安装实例百万
    • 新版本发布后影响所有新启实例
    • 管控影响一个区域百万 Agent

3. Agent 可靠性工程的思考

3.1 质量第一

首先我们要明确一个原则:质量第一。那么在《软件开发的 201 个原则》里面对质量也有所讨论,第一条讲到质量第一。作者是这样说的,无论如何定义质量,客户都不会容忍低质量的产品。这一点也经常被忽视,在项目紧急的时候,就在时间和质量之间进行权衡和取舍,牺牲质量,降低对质量的要求。即使质量差,也按时交付产品,这似乎是政治正确的行为,但这是短视的。从中长期来看,这样做是自杀。质量必须放在首位,没有可权衡的余地,说得非常明确。

那么怎么做呢?

第一,对所有的项目,首先需要明确定义质量的要求,质量并不是绝对的,在各个场景下可能质量要求有所不同。所以我们到底做到什么样的质量,达到什么程度才能提供客户价值,这是需要在项目初期定义清楚,比如对某些功能提供实验版本。

第二点,我们也需要平衡质量和交付时间的关系,但这不是降低质量,而是要提高技术水平,通过技术手段更高效率、更低成本地保障质量,比如说我们可以用自动回归方法,甚至用 AI 方法,用这些高技术来保证质量。

第三点,高质量的软件一定是设计出来的,而不是靠后边测试、运维保证的,这些都已经很晚了。所以我们在设计阶段,就应该保证软件设计的质量,这是非常关键的。

总结一下,就是:1.设定目标 2.技术提效 3.更早重视

3.2 Agent 可靠性的目标是什么

  1. 数据完整性:确保数据采集 Agent 能准确无误地收集所有所需数据,即使在所在环境或上下游出现短暂故障,也应该在故障恢复后上报故障期间收到的数据。
  2. 可靠性:Agent 应能稳定运行,即使在高负载或异常条件下也能持续工作,无论什么条件下都不应该崩溃。包括依赖的容器运行时重启、应用程序崩溃、异常输入等情况。
  3. 性能影响:Agent 在运行时对系统资源(如 CPU、内存、磁盘和网络带宽)的占用应保持在可接受的范围内,避免影响其他关键服务的性能,也不能让其他服务产生异常。
  4. 实时性:Agent 应能快速响应并及时处理数据,以支持实时或近实时的数据分析和决策。新功能需要通过性能测试,保证组合使用时性能达标,同时保证已有功能无性能退化。

3.3 可靠性工程的要素与方法论

作为技术人员,我们的主要工作当然是通过各种技术手段来实现可靠性目标,但同时我们也应该从更全面的视角来审视可靠性工程的多方位要素。

要素1:意识

首先是意识。要保证工程的高质量超越了单纯的编程技巧,它体现了一个团队的整体素养。高质量生产的意识贯穿于设计、开发、测试、上线等各个环节,影响到各个环节中稳定性建设的投入程度。只有团队具备了高质量生产的意识,所有的规范、工具和机制才会从空洞的理论和表面化的流程转变为切实提升软件质量的实战利器。

要素2:规范

其次是规范。规范如同知识的灯塔,是无数开发者在真实项目中摸爬滚打的经验结晶。它们凝聚了行业的智慧,是对最佳实践的提炼和总结,为后来者提供了站在巨人肩膀上的视角。规范的完整性与完备性往往超越了单个开发人员的视野,能够弥补个体经验和知识的局限性。

要素3:技术

然后是技术。技术工具能够帮助规范落实,并提高规范的执行效率。通过流程自动化技术工具能够自动化执行许多繁琐的流程,如代码准入、测试执行、灰度部署、系统监控、故障升级等。通过自动化,可以减少人为错误,保证流程的准确性和一致性,从而更好地遵循规范。

要素4:机制

最后是机制。为了进一步确保规范落地、工具有效使用并促进高质量生产意识的形成,往往需要采取综合策略。这些策略通常与组织架构、绩效考核与奖惩机制关联起来,以使团队自觉地实施规范、使用工具,同时培养团队对高质量生产和服务可靠性的深刻认识,从而提升整体工程效果。

对于以上要素,前人们已经总结了很多方法论来供我们进行参考。

方法论——规范

软件工程学将软件的开发过程分为需求分析、设计、编码、测试、部署、维护等几个阶段,每个阶段都伴随着一套完整的标准和指导原则,以确保在项目进展的每一步都达到高质量的标准。

设计阶段:

  • 需求管理:确保关键需求被准确理解,定义需求范围和优先级。
  • 文档编写:编写详细的系统设计文档,包括架构图、流程图、接口规范等。
  • 设计评审:通过同行评审确保设计的完整性和质量。

开发阶段:

  • 编码规范:遵循统一的代码风格和命名规则,提高代码可读性。
  • 分支规范:使用版本控制系统,如 Git,进行代码管理,按照约定的分支开发模式进行开发。
  • 提交规范:根据约定的格式提交 commit message,并与需求关联。
  • 代码审查:通过代码审查提高代码质量,发现潜在问题。
  • 单元测试:编写单元测试用例,覆盖核心功能和边界条件。

测试阶段:

  • 集成测试:验证不同模块之间的接口和交互。
  • 功能测试:根据需求规格说明书,编写测试用例。包括正向测试(正常操作)和负向测试(错误输入)。高效地覆盖所有关键功能和业务流程。
  • 回归测试:每次代码更改后,执行回归测试以确保未引入新问题。使用自动化测试套件进行回归测试,减少手动测试的工作量。跟踪回归测试结果,快速定位和修复回归的缺陷。
  • 性能测试:评估系统在高负载条件下的性能和稳定性。测试响应时间、并发用户数、资源利用率等指标。识别性能瓶颈并进行优化。
  • 安全测试:进行渗透测试,发现和修复安全漏洞。验证数据加密、身份验证和授权机制。检查输入验证,防止 SQL 注入、跨站脚本等攻击。遵循 OWASP(开放网络应用安全项目)的测试指南。
  • 兼容性测试:测试软件在不同操作系统、浏览器、设备上的表现。包括移动设备、桌面应用和 Web 应用的兼容性。考虑不同分辨率和屏幕尺寸的适配。

发布阶段:

  • 变更管理:制定变更控制流程,定义前期检查,部署执行,后置验证,回滚等步骤,旨在实现高效、稳定的软件发布,并最大限度地降低风险。
  • 灰度发布与 A/B 测试:将新版本逐步部署到部分用户,观察用户行为和系统表现。使用 A/B 测试对比新旧版本效果,优化产品。
  • 发布记录:记录版本信息,包括版本号、发布时间、更新内容。存档备查,以供未来参考和审计。

运维阶段:

  • 监控与告警:实时监控系统状态,记录日志,设置实时告警,快速响应问题。
  • 故障管理与分级:制定故障分级标准,根据影响范围和紧迫性(如 P1、P2、P3)来定义。快速识别和分类故障,有效分配资源进行处理。
  • 标准操作程序(SOP):建立故障处理流程,包括故障识别、分析、定位和修复。并定期更新,确保其反映最新的最佳实践。
  • 服务级别协议(SLA):制定 SLA,明确服务响应时间、故障恢复时间等目标。SLA应与客户期望和业务需求保持一致。
  • 工单管理流程:使用工单系统跟踪问题,进行分类、优先级设置和责任分配,确保高效处理,在规定时间内完成工单闭环。
  • 用户文档与知识库:包括系统功能、操作指南、常见问题(FAQs)和最佳实践。确保用户知悉系统功能限制和能力边界。定期审查和维护。

每个阶段的规范都是为了保证软件在开发、测试、部署和运维过程中的一致性、质量和可靠性。

方法论——技术

现在我们已经拥有了足够多的流程自动化工具来帮助软件开发规范的高效执行。

  • 敏捷开发工具:如 Teambition、Jira 支持迭代开发和敏捷流程,帮助团队按照敏捷原则,快速响应变化,持续交付高质量的软件。
  • 文档与知识管理系统:如语雀、钉钉文档帮助组织和分享规范文档,促进知识的共享和项目协作。
  • 持续集成与持续部署(CICD)系统:如 Jenkins、GitLab CI/CD,实现快速反馈。自动化部署,确保版本管理和部署一致性。
  • 监控与告警工具:如 Prometheus、Grafana,实现系统监控、指标可视化和报警管理。
  • 灰度部署、服务治理工具:如 Istio、Envoy,通过智能路由和流量管理,实现灰度发布、蓝绿部署。如 Sentinel,通过流量控制、服务降级和熔断策略,实时保护服务,确保服务质量和性能。
  • 分布式链路追踪系统:如 OpenTelemetry、SLS、ARMS,用于监控和分析微服务架构中请求在各个服务之间传输的工具,它可以帮助开发者和运维人员理解系统性能、定位延迟问题。
  • SRE 集成平台:如 SREWorks,旨在提供一站式的站点可靠性工程解决方案,将分散的工具和流程整合在一个统一的平台上,以提高运维效率和系统可靠性。

这些技术工具,通过自动化、流程化、可视化等方式促进了质量规范的落地和执行,提高了软件工程的效率和质量。

3.4 适合 Agent 研发团队的 SRE

从上面的回顾可以看到,可靠性工程并不缺少方法论和能效工具,而身处阿里云中更是具备了不少工具的天然获取优势。事实上负责 iLogtail 研发和运维的团队很精炼,我们不仅要为软件的研发功能迭代负责,并且需要持续优化性能,负责集团内外上线和监控,编写用户文档并处理工单。因此团队必须不断提高人效水平,但并不是用的规范、工具越多越好,而是选择最合适的 SRE 工具,并根据 Agent 的特点针对性地进行补充。

以下是我们团队在产研的各个环节中认为有必要引入的规范和工具。

红色框的内容针对了了 Agent 的特点进行了专门的加强,下面会重点讲解。

4. 研发流程、测试和灰度发布实战

4.1 设计阶段

如我们一开始就提到的,高质量软件是设计出来的,在设计阶段想清楚问题本质,能帮助我们从源头避免问题。以一个典型的例子来说明设计阶段的重要性。

iLogtail 在大量不同场景下广泛使用势必面对大量不同的数据处理需求,比如提取字段、字段脱敏等等,那么面对千变万化的需求,如果每个需求都进行定制化开发,不仅研发效率极低并且频繁的变更会带来版本的稳定性风险。那么 iLogtail 是如何通过合理的设计解决这个问题的呢?

iLogtail 从两条路线来解决这个问题:

第一条路线是插件化设计,类似 linux 中存在的大量基础工具,将它们串联起来自由组合就可以完成一件较为复杂的工作,在 iLogtail 中内置了大量具备单一能力的处理插件,如 JSON 解析、字段替换等,用户也可以通过接口自定义实现自己的处理插件,这些插件在 iLogtail 中通过流水线进行编排就可以组合出强大的处理逻辑。

第二条路线是可编程化,iLogtail 引入了 SPL 提供了运行时编译自定义插件的能力,即使自带的插件无法满足处理需求,也可以在线通过 SPL 构建出复杂的自定义处理逻辑,SPL 为用户提供了比插件配置组合更统一,更易懂,更简洁的数据处理任务描述,并且在复杂编排、多级处理等复杂场景下具备潜在的性能优势。通过插件化和可编程化的设计,iLogtail 将处理复杂的问题从根本上进行解决,有效减少了因处理数据需求的变更频率,从而避免了大量变更引起故障的风险。

在撰写设计文档工具的选择上,我们摒弃了传统的 doc 文档方式,转而使用如语雀、钉钉文档等在线协作工具。这些工具在评论、批注和版本管理等方面可以大大提高设计评审的效率。而对于设计文档本身,我们并不追求必须按模版写八股文,而是遵从简单需求简写,复杂需求详写的原则以提高效率。越吃不准的地方越需要在设计阶段详细写出来,避免在开发的后面阶段返工。

4.2 开发阶段

众所周知,软件工程的原则:问题发现得越早,修复问题的代价越低。在《代码大全》一书中提到,集成测试阶段修复一个 Bug 的成本是编码阶段的 40 倍。在这一阶段 iLogtail 团队在开发流程上做了大量的优化。

**首先是开发模式。**iLogtail 与很多其他软件不同,它既有开源版本也有商业版本,并两个版本在发布的目标上不完全相同。开源版本强调更敏捷的功能开发,随时都有可能被 fork,需要保证主干可用,而商业版要求稳定性,需要在发现问题时更快地完成修复。为了同时满足这些要求,我们采用了分支开发主干发布与主干开发分支发布相结合的开发模式。开源版使用分支开发主干发布,保持主干可用,大型功能开发时不污染主干;商业版使用主干开发分支发布,开源版本定期合入商业版代码库,代码融合完成后进行分支发布,如果有问题那么可以在分支上立刻修复问题,不会受主分支提交新代码的影响。

其次是编码规范。iLogtail 的编写由 C++ 和 Go 两种语言构成,C++ 遵循基于 Google 代码规范[1]的风格,Go 遵循 Effective Go[2]风格。为了保持风格一致,我们在代码仓库中包含了 vscode 的 .devcontainer 文件,提供开发镜像,内置 clangformat、gofmt 等格式化工具,确保每个参与者都能保持一致的编码风格。

**第三是持续改进。**我们都知道“熵增定律”:在一个孤立的系统里,如果没有外力做功,其总混乱度会不断地增大,最后达到一个无序的状态。我们开发的各种软件系统,也都遵循“熵增定律”。因此在 iLogtail 1.0 到 2.0 的改造过程中,我们进行了大量的代码优化,例如通过模块化、插件化设计降低代码耦合度,通过应用设计模式复用代码,减少代码重复量,通过删减无效代码,为代码库瘦身。通过一系列持续改进的行动,2.0 的代码在功能和性能上优于 1.0,而核心代码的数量反而更少了。

**最后是拥抱 AI。**你肯定也遇到过编码效率不够高,没人帮忙评审等编码问题,现在大量涌现的 Code Copilot 就像 24 小时在线老司机可以帮助我们解决很多问题。我们使用的是通义灵码,在遇到代码不熟悉,写出的代码不够高效时,让 AI 帮我们优化一下可以大幅提高开发效率。

4.3 测试阶段

iLogtail 是一个可以运行在多种环境的功能丰富的客户端软件,因此对其充分测试是很有难度的。

iLogtail 的测试痛点包括:

  • 参数配置多:每个小的功能点都有参数控制,而这些功能的组合数量更加庞大。
  • 输入不受控:不仅 iLogtail 采集的数据是不受控的,而且由于其客户端软件的特点,配置文件也可能被错误配置,导致其非预期使用多。
  • 上下游依赖:iLogtail 作为通用的可观测数据采集管道,输入输出包含与第三方系统的交互,测试需要搭建上下游环境一起测试才能验证功能点正确性。
  • 运行环境多样:测试不仅在 Linux 主机上进行验证,还需要考虑 Windows,各种容器运行环境。
  • 环境动态变化:iLogtail 所处的环境是动态变化的,需要考虑环境变化时采集器能否适应。动态的变化包括配置文件变化、容器增删变化、甚至是容器运行时升级等。
  • 开源软件:对于 iLogtail 团队来说,除了关心开源版 iLogtail 的稳定性,更需要对 iLogtail 商业版的稳定性负责,商业版特有的代码也需要保证测试覆盖。

针对以上痛点,iLogtail 在测试环节应用了大量的测试方法,包括静态代码扫描、单元测试、功能测试、环境兼容测试、回归测试和性能测试。其中前三项测试执行速度较快,作为代码入库的门槛。

静态检查

我们利用 coverity、golangci-lint 等静态代码检查工具,检查常见的代码内存泄露、访问越界和线程不安全调用模式,这可以以较低的成本帮助我们在更早的阶段发现代码中的潜在问题。

单元测试

单元测试的特点是不依赖外部环境,执行快,其作用在于确保函数、类方法的功能正确性。

针对参数配置多、输入不受控的痛点,我们在单元测试中使用了正交阵列测试的方法,列出参数确保分支覆盖全面,同时构造错误的输入覆盖异常场景。

例如对于以上参数组合,我们可以根据正交阵列构造的测试用例表:

用例编号KeepingSourceWhenParseFailKeepingSourceWhenParseSucceedRenamedSourceKey
1truetrue”key1”
2truefalse""
3falsetrue""
4falsefalse”key1”

通过这个正交阵列,我们确保每个参数的每种可能取值在测试用例中至少出现一次,同时也覆盖了不同参数组合所可能引发的不同行为。

对于社区和线上发现的任何问题,我们都会及时修复并补充测试用例,避免错误的二次发生。例如:错误的 yaml 配置,导致 ilogtail coredump无法启动[3]

自研 E2E 测试框架

功能测试的目标是为了快速验证采集器在正常场景下的基础功能正确。

环境兼容测试则保证采集器在不用运行环境下云可以正常工作。

全量回归测试负责测试在环境变化,配置变化、极端场景和异常场景下采集器的稳定性。

性能测试确保新功能性能达标,老功能性能不退化。

这些测试相比于单元测试来说,是比较复杂的,因为它们都涉及到第三方系统环境的搭建,甚至是操作系统环境的搭建, 编写这些测试的用例十分费劲。针对 iLogtail 存在上下游依赖、运行环境多样、环境动态变化的痛点,为了提高测试效率,我们根据 iLogtail 的特点自研了一套 E2E 测试框架。

这样,我们就可以根据对环境依赖程度不同、场景不同结合测试速度要求等通过配置组合生成多个阶段的测试。比如,环境部署的速度足够快,如仅搭建一个单机的第三方存储,那么它就归类到功能测试,主要用来验证 Flusher 的功能正确;如果是构建不同操作系统主机环境、容器环境,那么它就归类为环境兼容测试,来验证采集器在不同系统上是否工作正常,如果是复杂场景的组合,并且模拟环境变化、异常注入等,那么它就是回归测试,完整地看护 iLogtail 在各种场景下功能按预期工作。

下面我们就来看一下这个 E2E 测试框架的架构。

E2E 测试框架的流程主要分为 4 个部分,分别是 Setup、Trigger、Verify 和 Cleanup,其中 Setup 部分是框架中最重要的部分。Setup 部分负责模拟测试的环境,可以模拟主机和容器环境。在功能测试中,Setup 在单机环境中利用 Docker Composer 构建环境,利用 Docker 容器搭建上下游依赖;在系统兼容性测试中,Setup 则调用阿里云 API 真实购买 ECS 实例并安装不同操作系统;在回归测试中,Setup 则利用阿里云 ACK 作为测试环境,部署 Pod。同时 Setup 还利用了 ChaosBlade 来模拟各种异常,例如 K8s 故障、磁盘故障、网络故障等。Trigger 部分负责生成待采集的数据,如正则日志、Json 日志、Metric、Trace 等。Verify 部分负责验证数据采集的正确性,正确性不仅包括数据的数量正确,也包括内容的正确性,如 Tag、解析字段是否正确,同时 Verify 部分还可以收集性能相关的数据,如日志采集延时、CPU、MEM 占用率等。在这套框架的加持下,iLogtail 的测试效率大为提升。

精准测试

在构建测试用例过程中,还有许多效率问题需要考虑,例如 iLogtail 支持的众多的操作系统版本、Java Agent 支持的 JDK、软件框架版本是否需要一一进行测试?如下图所示,由于版本众多,如果对每个支持的版本都进行穷举测试,那带来的开销将非常不经济,并且测试时长也是不可接受的。因此,我们采用了一种精确测试的方法。我们的方法是先将测试对象的初始大版本放入测试集,如 1.0.0、2.0.0 等,如果这些版本之间的测试对象都是兼容的,那么仅测试这些版本就足够了。但如果中间的小版本有不兼容的更新,如 libc 升级、函数签名变动等,那就需要通过技术手段识别出不兼容的版本,并将不兼容的首个小版本也加入到测试集中。这样,通过较少的典型测试用例,我们就可以保证所有被测试区间覆盖的版本的兼容性。

准入和测试流程完整大图

iLogtail 的完整准入和测试流程包含开源版和商业版的所有测试。代码由用户通过 PR 提交到开源仓库,PR 发起后 Github Action 自动触发,执行编译、静态检查、UT、FT 等合入门槛测试,只有都通过的代码才可以合并入库。合入开源库后,内部代码仓库会定期合入开源库的代码并触发商业版测试流水线。商业版测试流水线通过阿里内部的可视化 CI 平台编排,通过云效 CI 平台执行。与商业版代码合并后的代码会重新执行编译、静态检查等步骤,还会额外执行如安全检查、构建产物等。完成编译阶段后,进入测试阶段。测试阶段先利用最新编译产物更新测试环境中的 iLogtail,然后执行商业版的功能测试、全量回归测试等,如果在测试过程或结果中遇到错误,那么流水线将触发钉钉通知,将错误报告给负责人。

4.4 发布阶段

软件的研发一定会存在 bug,有 bug 就有可能导致故障,那么根据墨菲定律,故障是一定会发生的。那么如果故障一定会发生,我们有没有什么方法可以将影响控制在最小范围呢?灰度发布的方法就是一个很好的控制故障范围的方法,因此我们在实践中也应用了该方法。

灰度发布

我们支持的灰度发布维度包括集群维度、用户维度、用户等级维度、地域维度等。

在进行灰度发布后,我们会监控灰度范围采集器的各项指标,如资源使用情况、是否发生异常重启、与服务端通信是否正常、数据量是否发生异常波动等,确保其工作正常。如果这些观察项在连续 1 天时间内都保持正常,那么我们就会进行灰度发布的下一阶段,如扩大灰度范围、推全。

4.5 运维阶段

灰度阶段的有效观察离不开完善的指标体系建设,这也是运维阶段达成 SLA 的基础。SLA 是我们面向客户的产品稳定性承诺,例如 SLS 服务向的 SLA 就是 99.9%。构成 SLA的背后是一组 SLO 即服务水平目标,通常数量不会太多,4-5 个。构成 SLO 的背后是 SLI,也就是各项系统指标。构建一套完善的指标体系往往是运维阶段的重中之重,而这也是有方法论的。如下图右侧所示,指标的层级由基础的系统层到应用层可以分为系统监控、服务监控、业务监控、数据监控、资源监控等,我们的 iLogtail 指标体系也是参考这一方法论进行建设的。

为了使这些指标的作用最大化,iLogtail 基于 SLS 服务自身构建了一个智能可观测平台。SLS 本身已经具备了构建可观测平台的诸多基本功能,如数据采集、流式计算、数据存储、即席查询、可视化仪表盘、告警通知、智能预测等,利用这些能力就可以构建出一个智能可观测平台。

在 iLogtail 的智能可观测平台中,平台使用一套数据化运维体系,把所有系统的运维数据全部采集起来、真正打通,并深度挖掘这些数据的价值,为运维提供数据决策,构建了如集群稳定性大盘、重保客户大盘、基础设施监控、集群水位监控、数据采集诊断等功能。整合了刚刚提到的指标和 iLogtail 日志、系统 Trace 等数据后的智能可观测极大地提升了 iLogtail 的运维和故障排除工作效率。

4.6 运营阶段

如果是经典的 SRE,那么我们的职责也就到运维阶段为止了,但在 SLS 我们将可靠性维护的职责扩展到了运营阶段,接下来我们就看一下在这一阶段我们做了哪些颇具特色的工作。

持续迭代的客户支持机制

在阿里云,通常一个客户问题的解答会经历如下几个阶段。当用户提出工单后,会由客户服务人员跟进,如果无法解决则提交到技术服务手中,如果仍然无法解决就会进行技术服务升级。有些比较困难的问题就会通过这一渠道触达到产研值班手中,如果产研值班也无法解决问题就会再次进行产研值班升级,产研会进行排查直到问题解决为止。但是,如果大量的客户工单问题都升级到我们产研侧,以产研侧有限的人力那必然是无法承接的。因此我们与技术服务部之间会有反馈机制以持续优化客户支持效率。

技术服务部会定期将高频的问题和最想要的工具反馈给我们,而我们会定期进行培训和工具提供来帮助他们提升客户服务能力。比如说,我们会共建知识库,共同优化排查手册并提供内部工具的使用方法,并且我们会与技术服务部共同约定工单的处理流程与规范,如何时应当升级等。

自助排查工具助力工单收敛

我们还希望能够从根源头来减少客户提出的工单,比如说当客户遇到问题时能否利用排查工具自助地就将问题给解决了。这里我们就介绍 2 个典型的用户自助排查工具。

1)Cloud Lens For SLS

在 Cloud Lens For SLS 中,用户可以统览全局的 iLogtail 实例,了解安装的版本号和整体资源占用情况。通过采集监控,用户可以获取每个实例采集数据的明细指标。在 iLogtail 异常监控界面中,我们将最关键的错误信息进行了集中显示,这样客户就可以在一个地方看到所有的重要事件。并且,我们将这些错误信息和排查的最佳实践联系起来提供在同一页面上,这样客户在大多数情况下就可以自助将问题解决了,从而在源头上减少了工单的数据量。

2)容器元信息预览

在分析工单问题的分类后,我们发现在采集容器日志场景下,K8s/Docker 场景容器筛选、路径配错占采集失败工单的 50%。导致这一局面的原因在于,配置容器采集的复杂度确实高于主机,同时一些概念也往往容易搞错。比如容器名称这一概念,用户往往和容器组名称进行混淆,导致配置错误,数据采不上来。而容器元信息预览则很好地解决了这一问题,它将 iLogtail 视角发现的容器在界面上直观呈现,术语对齐容器筛选。在匹配容器标签中展示配置能匹配上的容器,而在全量容器标签中则同时展示了不匹配的容器,并给出了不匹配的原因。通过这一工具,用户完全可以自主解决错配问题,从而减少了工单。

用户界面优化根治源头问题

再进一步,我们能否在源头上就避免用户产生问题呢?我们发现在实际使用过程中,用户会提出大量关于参数配置问题的咨询工单,因此我们对用户界面进行了全面的翻新。下图中的左侧为老配置界面,右边为新配置界面,界面上的参数还是比较多的。通过对比可以看出,原先老界面中的参数分布条理欠缺,用户往往会忽略关联的参数,而在新版中对参数进行了分组,使得相关功能内聚,参数间依赖关系明确,布局条理清晰。而原先容易误导客户的非常用功能则默认折叠起来,既起到了简化界面的作用,起到了突出重点功能的作用。事后,我们进行了效果评估,整体接入效率提高了 30%。

5. 总结与展望

这张图总结了 Agent SRE 持续优化的效果。从 iLogtail 的特点出发,我们首先分析了 iLogtail 在质量建设上的痛点,然后针对这些痛点在整个研发链路上引入了符合 iLogtail 团队需要的规范和工具,将这些规范和工具集成到流水线中做到自动化。特别是测试阶段引入了自建 E2E 测试框架、全量精准回归测试等提高效率的测试工具,并在平时的实践中不断完善测试用例,最终使得线上问题拦截率提升 80%,并彻底杜绝了操作系统兼容性等问题。

而对用户侧提供自助排查工具如 Cloud Lens For SLS 和优化前端交互界面,赋能了用户自助解决问题的能力,这使得工单从源头被拦截。**从效果上看,工单整体收敛了 30%,心跳类收敛 80%。**而基于 Cloud Lens For SLS 和其可观测数据,一些大客户也可以进一步定制出自己的可观测体系,来保障数据采集稳定性。

展望未来,大模型的广泛使用将使得 SRE 在技术支持、根因分析上产生革命性改变。而作为 Agent 需要不断优化自身的可观测数据,为 Lens、根因分析模型提供更好的输入数据,支持减少排查定位时间。AI 技术同样会应用到数据接入的自动化上,不断降低数据接入门槛的同时,也可以避免配置错误引入稳定性问题。最后对于 SRE 工程师的要求也会越来越全栈化,不仅要求其具备全栈开发能力,能从全栈视角提升运维效率,而且新的全栈中还需要加上能利用 AI 能力的元素。

相关链接:

[1] Google 代码规范

[2] Effective Go

[3] 错误的 yaml 配置,导致 ilogtail coredump 无法启动

参考资料:

[1] 软件工程能力漫谈:比质量更重要的,是项目管理能力 | ArchSummit

[2] 2023 年中国互联网故障总结之十大故障

[3] 降本增笑 P0 事故频发,构建持续高可用系统的破局之道

[4] 细聊工作中常见的分支开发模式

[5] 以阿里为例,详解 SRE 的团队建设与职能分工

[6] What is Orthogonal Array Testing? (Example)

[7] 如何低成本修 bug?测试左移给你答案


observability.cn Authors 2024 | Documentation Distributed under CC-BY-4.0
Copyright © 2017-2024, Alibaba. All rights reserved. Alibaba has registered trademarks and uses trademarks.
浙ICP备2021005855号-32