接口返回 200,但数据停在三天前,算不算服务正常?

可观测性与 SLA:指标、日志、告警与数据新鲜度

约 12 分钟6 道自测更新于 2026-11-01

一句话记住可观测性要同时看服务信号和数据健康;SLI 是测量,SLO 是目标,SLA 是带后果的对外约定。

01学完你能做到

  • 区分指标、日志、链路追踪,以及它们各自适合回答的问题。
  • 区分 SLI、SLO、SLA 和错误预算,不把示例数字当成行业标准。
  • 为金融数据服务设计按交易日计算的新鲜度指标和分级告警。
  • 用分位数、请求 ID、租户和工具字段定位长尾延迟与影响范围。

02这课解决什么问题

接口没有报错,但今天的日 K 还是昨天的;或者系统平时很快,开盘时一批请求特别慢。怎样在客户发现之前发现问题,并在事后说清楚影响了谁、哪一段出了问题?

03可观测性的三类信号

指标(metrics) 是随时间变化的数值,例如请求数、错误率和 P95 延迟,适合看趋势和触发告警。

日志(logs) 是一条条事件记录,例如请求时间、工具名、租户、状态和耗时,适合定位某个请求发生了什么。日志中不应写入完整 API Key、手机号等不必要的敏感信息。

链路追踪(traces) 记录一次请求经过网关、缓存、数据库和上游的路径与耗时,适合回答“慢在哪一步”。一次请求通常用 request_id 或 trace ID 关联各个环节。

OpenTelemetry 将 Traces、Metrics、Logs、Baggage 列为信号概念;不同实现还可能提供事件和性能剖析等能力。课程里先掌握三类最常用信号即可。

04SLI、SLO、SLA 与错误预算

  • SLI(Service Level Indicator):对服务水平某一方面的定量测量,例如成功请求占比、P95 延迟、交易日日 K 的落后天数。
  • SLO(Service Level Objective):为 SLI 设定的目标值或范围,例如“在约定窗口内,成功请求占比达到某个目标”。目标值应基于业务需求和历史表现设定,而不是照搬一个“行业标准数字”。
  • SLA(Service Level Agreement):与用户之间的明示或默示约定,并包含达标或未达标的后果。没有明确后果时,通常只是内部 SLO 或产品目标。
  • 错误预算(error budget):SLO 允许的未达标空间。例如,若某个时间窗口的目标是 99.9%,对应的允许失败比例是 0.1%;实际预算还要结合请求量、统计窗口和排除项计算。

错误预算可以帮助产品和工程团队做取舍:预算还有余量时,可以继续推进普通发布;预算消耗过快时,应优先处理稳定性。具体发布策略要由团队根据业务影响制定。

05数据服务的四个观察面

服务端常见的观察面包括延迟、流量、错误和饱和度。金融数据服务还应增加数据新鲜度:最新可用数据距离“按规则应该到达的时间”有多远。

新鲜度不能简单写成“超过 24 小时就报警”。周末、节假日和午间休市没有新的日 K 是正常的;更可靠的方式是结合交易日历,比较:

应有的最新交易日 − 实际最新交易日 = 落后的交易日数量

例如,周日查询到周五收盘的日 K,落后交易日数量为 0;下一个交易日收盘后仍只有周五数据,才应进入告警判断。收盘时间、入库宽限和策略使用时点要事先写入规则,并在不同市场分别配置。

06分位数与告警

把请求按耗时从小到大排序,第 95% 位置上的耗时称为 P95,第 99% 位置上的耗时称为 P99。平均延迟可能被大量快速请求掩盖,P95 和 P99 更适合观察长尾体验。

告警不应把每一次小波动都升级为紧急呼叫。可以按影响分层:

  • 紧急呼叫:持续影响用户、数据在应有时间之后仍未到达,或错误预算消耗速度很快。
  • 一般告警 / 工单:短暂波动、低影响的单个数据集异常,先记录并安排处理。
  • 信息记录:不影响用户的可预期变化,例如休市日数据不更新。

基于 SLO 的告警常用燃烧率(burn rate):实际错误率 ÷ 允许错误率。燃烧率越高,表示预算消耗越快。多窗口规则可以同时观察较长窗口的累计影响和较短窗口的当前状态,减少“故障已经结束但告警仍持续”的情况。具体窗口和阈值应由自己的流量、业务时段和响应能力校准,不应把某组示例数字当成统一标准。

07在金融数据链路中的位置

上游行情源 → 采集作业 → 存储 → API / MCP → 用户或 Agent
      │          │         │          │
   采集耗时    任务状态   最新交易日   请求数、错误率、P95、追踪
                         └────── 指标、日志、告警 ──────┘

至少要在三处采集信息:采集作业看是否按时完成,存储看最新数据是否覆盖应有交易日,服务层看用户请求是否成功和足够快。统一记录 request_id、租户标识和工具名,才能定位单个请求并判断影响范围;字段应遵循最小必要原则。

08一个新鲜度检查的伪代码

def expected_latest_trade_date(now, calendar, close_cutoff):
    candidates = [
        day for day in calendar
        if day < now.date()
        or (day == now.date() and now.time() >= close_cutoff)
    ]
    return max(candidates)

lag_days = sum(
    1 for day in calendar
    if actual_latest_date < day <= expected_date
)

这里的 close_cutoff 是系统自己的业务假设,不是所有市场通用的收盘时间。生产实现还要处理时区、半日市、临时休市、数据延迟和没有可用数据等情况。

09常见误区

  1. 只看接口可用率,不看数据新鲜度:返回 200 不代表内容已经覆盖最新应有交易日。
  2. 按墙钟时间判断所有数据是否过期:休市日会造成误报,应该按交易日历和业务时点计算。
  3. 用平均延迟定目标:平均值可能掩盖长尾,应结合 P95、P99 或规定时间内成功请求占比。
  4. 把 SLO 示例数字当行业标准:SLO 是业务目标,需根据用户影响、历史数据和成本设定。
  5. 每个异常都发紧急呼叫:告警过多会造成疲劳,应按影响和持续时间分级。
  6. 日志写完整密钥或个人信息:日志也是敏感数据的存储面,应做脱敏、访问控制和保留期限管理。
  7. 只盯自己的服务:上游返回空数据或覆盖代码数骤减时,接口仍可能返回 200,应监控行数、代码覆盖率和数据质量指标。

10延伸阅读

11一分钟讲给别人

试着用自己的话讲一遍服务出问题不一定会报错:接口能通,数据也可能是旧的。所以要同时看指标、日志和追踪,再为成功率、延迟和数据新鲜度设目标。SLI 是怎么量,SLO 是希望量到什么程度,SLA 是和用户约定没做到会有什么后果。告警看预算烧得多快,不是每一次抖动都叫人。

想一想

6 道自测

先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。

  1. 01指标、日志和链路追踪分别适合回答什么问题?

  2. 02SLI、SLO 和 SLA 的区别是什么?

  3. 03错误预算表示什么?

  4. 04为什么日 K 新鲜度不能只按墙钟时间计算?

  5. 05为什么 P95 / P99 通常比平均延迟更能反映长尾?

  6. 06燃烧率在告警中表示什么?

已看 0/6 题

练动手练习

任务:为一个日 K API 设计三项 SLI:请求成功率、延迟和数据新鲜度。为每项写出统计窗口、数据来源、异常分级和需要排除的休市情况;再设计一条日志字段清单,确保可以按请求 ID 和租户定位问题。

完成这一课

完成这一课

读完讲义、看完自测答案,这一课就算学完了。

  • 读完讲义
  • 看完全部自测

本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。