Live:CloudOps Webinars & Hands-on Workshops ·Register ↗
跳到主要内容

开发人员

可观测性对开发人员至关重要,它能提升生产力、改善应用程序性能,并通过更好的决策和更快的问题解决来推动业务成功。本指南提供了有效利用可观测性的最佳实践和建议。

为什么可观测性对开发人员很重要

开发人员使用可观测性来实现以下关键目标:

  • 快速识别和解决问题:
    • 可观测性使开发人员能够快速识别和诊断问题,减少解决问题的时间(MTTR),提高整体软件交付性能
    • 它帮助开发人员了解系统在生产环境中的行为,使他们能够做出明智的决策并改善运营
  • 改善客户体验:
    • 通过分析系统行为,开发人员可以优化性能和可靠性,从而带来更好的客户体验和更高的用户满意度
    • 可观测性工具帮助监控用户交互,使开发人员能够及时识别和解决 UI/UX 问题
  • 提升团队效率和创新能力:
    • 可观测性平台为运营数据提供单一事实来源,促进跨团队协作并减少故障排除时间
    • 得益于自动化洞察和告警,开发人员可以将更多精力放在创新上,减少手动调试的时间
  • 数据驱动决策:
    • 可观测性提供系统性能的详细洞察,使开发人员能够就代码改进和资源分配做出数据驱动的决策
    • 它帮助组织优化投资并加速产品上市,通过识别需要改进的领域
  • 复杂性管理:
    • 可观测性通过提供系统相互依赖关系的全面视图,帮助管理现代云原生和多云环境的复杂性
    • 它使开发人员能够简化复杂性并专注于相关数据,促进更高效的开发过程

代码质量最佳实践

  • 监控问题跟踪指标:

    • 使用 JIRA、Trello 或其他问题跟踪平台来跟踪以下指标:
      • 工单从代码审查到测试审查再回到进行中状态的次数。高频次可能表示技能不足、高复杂性或工具不够完善。
      • 工单因外部依赖被阻塞的次数。高频次可能表示依赖之间的耦合度高和/或复杂性高。
    • 建议:
      • 使用 Amazon Q Developer 等工具通过自动化代码审查来提升生产力和代码质量。Amazon Q Developer 可以将软件开发任务加速高达 80%,并通过减少快速开发周期中人为错误的可能性来提高代码质量。
      • 将定期指标审查纳入回顾会议,以识别改进方向并培养持续改进的思维方式
  • 为性能指标进行代码插桩:

    • 对代码进行插桩以便能够测量以下内容,这些指标通过评估代码实现的性能效率和可扩展性来间接衡量代码质量
      • RED 方法: 监控微服务的请求数(Requests)、错误率(Errors)和持续时间(Duration)。这提供了服务性能和可靠性的洞察。
      • USE 方法: 跟踪系统资源的利用率(Utilization)、饱和度(Saturation)和错误率(Errors)。这有助于识别瓶颈和资源约束。
    • 在请求处理路径中对所有外部依赖(如其他服务、数据库、缓存等)的调用添加插桩。这可以提供调查请求处理时间突然变化所需的信息,并加快问题根因识别速度
    • 建议:
      • 为请求延迟和错误率设定 SLO(服务水平目标),并以此推动改进以获得更好的质量和性能
      • 将插桩验证添加到执行关键数据流和请求处理路径的自动化测试中
      • 构建自动化负载测试任务以创建系统性能和代码质量度量的基线
      • 确保插桩添加了足够的上下文以识别单个请求的性能影响
      • 配置并利用 SDK 提供的自动插桩功能来减少手动添加插桩的工作量

高效的日志记录和监控

  • 使用结构化日志格式(如 json)。对于现有应用程序,考虑使用日志转换功能注入更多上下文、添加或删除字段
  • 使用包含足够元数据的宽事件格式,以便能够推导出有意义的信号并在信号之间进行交叉关联。
  • 使用 OpenTelemetry 或 ADOT SDK,它们会在日志中注入额外的上下文,从而实现跨信号关联并减少平均识别时间(MTTI),进而减少平均恢复时间(MTTR)
  • 适当使用日志级别——这些可以帮助您控制日志量,从而控制摄入成本。
    • 对任何意外和预期的错误条件使用 ERROR。添加尽可能多的额外上下文以加速根因分析。
    • 对一般运行时事件(如用户登录)使用 INFO,这些事件可以提供上下文且很重要
    • 对处理路径中的调用使用 DEBUG,以深入了解应用程序的流程和状态。
  • 避免记录任何可能被视为敏感的数据,如 PII 或 PHI。如有此需求,考虑使用数据保护策略或在摄入时对数据进行脱敏。使用 IAM 策略控制谁可以查看原始数据。
  • 使用嵌入式指标格式(EMF)将指标嵌入日志中,减少对可观测性平台的 API 调用次数,降低成本。
    • 避免对具有高基数维度的指标(如 requestId)使用 EMF
  • 告警:
    • 使用异常检测以避免为告警设置固定阈值。这可以避免随着系统使用量变化而更新阈值的开销,并减少告警噪音。
    • 使用指标数学和组合告警来减少针对特定故障生成的单个告警数量。
    • 仅在 SLO 面临风险或已失败时才触发告警。这可以避免团队被不必要地唤醒并减少认知和上下文过载
    • 仅在有人能对故障通知采取行动时才告警
    • 尽可能自动化告警的解决。例如,利用平台原生配置,如自动扩展、自动故障转移到副本或备用实例等。
    • 在告警通知中添加足够的上下文,确保被通知的人能够快速识别要查看的 dashboard、要使用的 playbook 以及受影响的服务
  • Dashboard:
    • 为每个角色/利益相关者创建一个或多个 dashboard。
      • 应用开发人员需要足够的上下文来诊断问题、了解应用程序的性能
      • 平台工程师需要 dashboard 提供上下文,以识别对 SLO 的影响以及需要关注的基础设施组件及其对使用它们的服务的影响
      • 产品经理需要 dashboard 展示用户旅程、产品功能使用指标、采用率、流失点等
      • 业务利益相关者对展示产品采用率、用户流失或任何与影响业务绩效和收入相关内容的组件感兴趣
    • 在所有 dashboard 中使用一致的时区(如 UTC)
    • 在 dashboard 上的所有组件使用相同的时间范围
    • 使用注释为 dashboard 添加更多上下文
    • 确保 dashboard 上只有有助于错误解决的组件。过多的组件会增加噪音和认知过载,导致更长的 MTTR
      • 如果没有过多的组件,将其他次要组件移到另一个 dashboard 或 dashboard 的底部。过多组件会影响加载时间,导致更高的压力和认知过载。
    • 确保整个 dashboard 适合单个屏幕,且趋势在笔记本电脑的分辨率和屏幕尺寸下可见
    • 添加一个带有 dashboard 描述和使用指南的组件
    • 在组件上配置和显示阈值
    • 不要在单个组件中塞入过多指标,这会导致趋势和峰值被平滑化,失去其作用。这也使诊断变得困难。
    • 使用动态调整的 Y 轴以使趋势和峰值可见
  • 建议:
    • 控制成本:
      • 识别利益相关者:
        • 确定对功能性能感兴趣的不同角色,如功能、可用性、安全性、成本、销售和产品使用。
        • 利益相关者可以包括开发团队、终端客户、内部业务利益相关者、平台运维团队或应用开发人员。
      • 识别关键成果:
        • 对于每个利益相关者,定义可量化的成果(如错误率、请求处理时长、每分钟登录次数、每分钟购买产品数、废弃购物车数等),这些通常使用服务水平目标(SLO)来衡量。
        • 使用每个角色的 SLO 来确定所需的插桩
      • 选择正确的信号:
        • 具有足够上下文的宽日志可以转换为指标和 traces,提供单一事实来源,控制成本并实现信号关联
        • 运行 可观测性策略研讨会 以确定应插桩到应用程序中的正确信号
    • 选择正确的信号:
      • 日志和 traces 帮助您找出故障或意外行为的根因。确保添加的日志能帮助您回答诸如"为什么某个特定请求失败了?"或"如果请求处理时间的 p50 或 p99 增加,我需要知道什么来判断与请求时长相关的 SLO?"这样的问题
      • 指标适合了解基线性能、预测趋势和异常。它们可以主动指示某些东西未按预期工作。但自定义指标成本较高。
    • 减少告警疲劳:
      • 根据配置,告警可以主动或被动地突出系统中的问题。过多的告警会导致告警疲劳和低效团队,进而导致代码质量和产品交付下降。
    • 定期审查和持续改进:
      • 安排团队成员定期轮值监控 dashboard 并报告发现的新趋势或模式。
      • 在每个发布中分配一部分时间来改进信号、根据回顾会议和轮值观察中发现的差距调整告警阈值和 dashboard
      • 根据解决所需的努力和告警触发次数来优先修复重复告警的根因

性能分析和性能优化

  • 真实用户监控(RUM):
    • 使用 AWS X-Ray 或 New Relic 等工具来监控真实用户交互并识别性能瓶颈。关注关键转化点,同时衡量技术性能和业务成果(转化率、流失点)。
    • 优先监控关键用户路径,如结账流程和注册流程。
    • 建立基线性能和用户行为,以便快速识别可能影响业务成果的异常和趋势
  • 合成监控:
    • 使用 Amazon Cloudwatch Synthetics 等工具来模拟用户交互并在各种条件下测试应用程序性能。合成金丝雀可以帮助在用户受到影响之前识别问题。
    • 使用合成金丝雀验证健康检查和系统正常运行时间。
  • 分析工具:
    • 使用 AWS X-Ray 等工具进行性能分析,以识别性能瓶颈并优化资源利用
    • 设置根据流量模式动态调整的采样率,并保持对错误 traces 和异常值的充分保留。这确保了对关键问题的全面可见性,同时管理数据量和成本。
    • 使用尾部采样为收集器配置多个采样策略,根据错误状态、持续时间阈值和自定义属性优先处理高价值 traces。这将确保采样的 traces 包含最有价值的那些
  • OpenTelemetry:
    • 使用 OpenTelemetry 进行自动插桩,简化性能指标和 traces 的收集。在添加手动插桩之前验证自动插桩提供的遥测数据,然后根据需求调整自动插桩以控制信号和成本。

错误处理和调试技术

  • 通用:
    • 为瞬时故障设计带指数退避的重试机制。为外部依赖实现断路器。这在分布式系统中特别有用,可以防止对下游组件/服务的过度负载。这可能不适用于所有场景,因此在采用此设计之前请进行充分的尽职调查。
    • 为关键操作创建降级机制,并为失败的事务维护清晰的回滚流程。
    • 在所有入口点添加输入验证。
    • 确保可重试操作是幂等的。
  • 日志:
    • 维护已保存的 Cloudwatch Log Insights 查询库。使用文件夹对查询进行分组
    • 不要静默错误。始终适当地记录日志或处理。
    • 除了其他相关上下文外,在日志中添加关联 ID 或请求 ID 等标识形式。
  • Playbook 和 Runbook:
    • 编写 playbook 时,包含清晰的可操作步骤,包括所需权限、工具和预期结果。
    • 在 playbook 和 runbook 中包含验证步骤、回滚流程以及相关 dashboard 的链接。
    • 对 playbook 进行版本管理,并在事件后更新它们,包括经验教训和关键洞察。
  • 调整采样规则:
    • 基于服务关键性和流量模式实现动态采样规则。
    • 为错误条件和业务关键路径设置更高的采样率。
    • 根据运营需求和成本考量定期审查和调整采样规则。

代码审查和协作策略

  • 工单细化:
    • 在功能细化过程中识别可观测性需求。这可能包括
      • 受影响的利益相关者和相关 SLO
      • 所需的遥测/信号
      • 所需的告警
      • 需要创建或更新的 dashboard 列表
  • 无责回顾:
    • 每次事件后,进行无责回顾以寻找改进流程或添加自动化的机会。始终考虑变更成本,并确保每次事后分析至少有一个已达成共识的可操作项,并关联完成时间表。
  • 运营就绪审查:
    • 与平台和运维团队参加运营就绪审查,以识别可观测性态势中的差距——这可以是一个清单和部署到生产环境前的强制性演练。对于拥有多个团队的大型组织,为避免此过程成为瓶颈,应根据新功能和发布节奏定期进行。
  • 建议:
    • 使用 AWS Systems Manager Incident Manager 等工具来指导您完成事后分析
    • 参考运营就绪审查以获取运营就绪审查清单或流程中应包含的问题的灵感。
    • 始终分享回顾和运营就绪审查的经验教训——这可以通过 wiki 或邮件组订阅实现

API 设计和文档指南

  • 版本管理:
    • 确保 API 有版本控制,并在处理每个请求时添加版本作为上下文
    • 如果发送自定义指标,在适用时添加版本维度
    • 在 dashboard 上添加注释或标识符以清晰区分从一个版本到另一个版本的切换
    • 确保跟踪每个版本的请求,并添加可视化版本使用情况的组件。这是为了确认请求按预期路由,也是为了减少根因识别时间。这可以在弃用和移除旧版本时提供更多信心
  • 向后兼容性:
    • 在移除与旧 API 版本相关的代码路径之前,确保没有请求发送到旧版本
  • 批量 API:
    • 为每个单独请求的状态以及整体批量请求发出信号
    • 确保日志中添加了标识批量请求 ID 和单个请求的上下文