运维笔记

如何给线上流量做实时打分:一套能落地的 r/devops 架构拆解

线上流量实时打分实战:从特征采集、评分流水线到 Envoy 灰度决策,含可复制配置、Mermaid 架构图、延迟成本权衡与最佳实践对照表。

Cloud & DevOps 技术可视化

核心要点 (Key Takeaways)

  • 线上流量打分(scoring live traffic)的本质是在请求路径里做一次低延迟的特征聚合 + 决策,它不是风控产品的专利,CDN 灰度、反爬、A/B 分流、动态限流都在用它。
  • 打分系统 90% 的复杂度不在模型,而在特征从哪里来、超时了怎么办、决策写回哪一层。我见过太多团队模型训得很漂亮,上线后因为一次特征 RPC 抖动把整条链路拖挂。
  • 规则通道和模型通道必须物理隔离。规则用于兜底和应急,模型用于精度,混在一起做 A/B 是给自己挖坑。
  • 打分延迟预算要卡死在 5ms~15ms 这个量级,超过 20ms 就该考虑异步打分 + 下一跳决策,而不是硬扛在同步路径上。
  • 别迷信"实时"。我个人的经验是:能离线预计算的特征就别在线算,能在边缘算的就别回源算,省下来的不只是钱,是故障面。

为什么大家都在给流量打分,但很少有人讲清楚"结构"

先说个现象。你在 r/devops 或者 HN 上搜"traffic scoring"“live traffic analytics”,出来的东西基本两类:一类是厂商软文(“实时流量洞察,助力业务增长”,看完等于没看),一类是学术味十足的 SLO/Golden Signals 科普。

真正干活的工程师关心的问题,一条都没回答:

  • 打分逻辑放哪儿?Sidecar、网关、还是独立服务?
  • 特征延迟 200ms,但我的 SLA 是 P99 < 100ms,怎么办?
  • 评分结果怎么传到下一跳?塞 header?查 Redis?还是往消息队列里丢?
  • 规则和模型打架了听谁的?

这几周社区的情绪其实挺有意思。HN 上那篇《Most data centers refusing to say how much water, electricity they use》拿了 216 分、201 条评论,评论区吵的核心就一句:你以为的"实时",背后是实打实的算力和电费。有个高赞评论大意是"每个说自己做实时分析的团队,都该先公开自己每秒烧了多少瓦"。这话糙,但扎心。

还有一条 HN 讨论《We struggled with DevOps, so built a open source agentic platform just for this》只有 3 分,但点进去看,楼主吐槽的是同一件事:观测和决策是两码事。你能看到流量,不代表你能对流量做决定。中间那道"打分"的桥,才是真正没人讲清楚的地方。

所以这篇文章不聊概念,聊结构。我会把整条链路拆开,每一层给你能直接抄的配置。


打分的本质:一次带预算的同步决策

先把心智模型立住。线上流量打分不是"分析",是"决策"。它和风控评分、广告竞价、限流算法是同一类东西:

在有限的延迟预算内,聚合若干特征,产出一个分数,用这个分数影响请求的走向。

这句话里有三个约束,缺一不可:

  1. 延迟预算(budget):你只有几毫秒。
  2. 特征聚合(feature aggregation):数据可能来自多个源。
  3. 决策产出(decision):分数必须能被下游消费。

很多人失败在只关注第 2 步,忽略了 1 和 3。模型 F1 干到 0.95,结果特征查询超时没设兜底,线上直接雪崩。

flowchart LR
    A[Client Request] --> B[Edge / Gateway]
    B --> C{Scoring Sidecar}
    C -->|local cache hit| D[Rule Engine]
    C -->|miss| E[Feature Service]
    E --> F[(Redis / Feature Store)]
    E --> G[(Kafka Stream)]
    D --> H[Score Fusion]
    H --> I{Decision Router}
    I -->|score < 0.3| J[Allow - Origin]
    I -->|0.3 - 0.7| K[Throttle / Challenge]
    I -->|score > 0.7| L[Block / Sinkhole]
    C -.timeout 5ms.-> M[Fail-Open Fallback]
    M --> J

看这张图,最容易被忽略的是右下角那条虚线:超时兜底。没有它,你所有的 SLA 承诺都是空话。


第一步:把特征分层,别让在线路径背所有锅

特征按"能否预计算"分三层,这是整个架构的地基:

特征层典型来源计算时机延迟量级成本
L1 静态/派生IP 库、设备指纹、账号画像离线/准实时< 0.1ms(本地)极低
L2 近实时聚合Kafka/Flink 滚动窗口秒级更新1-5ms(远程 KV)中
L3 请求级动态当前请求头、body、瞬时速率请求内0.5-3ms(本地)低但易失控

我的强观点:L3 能算的就别丢给 L2。我见过有团队把"当前请求的 UA 是否异常"这种纯本地判断,做成一次 RPC 调用去查特征服务,每次多 8ms,一天几亿请求,纯属浪费。

L2 用 Redis 或专门的 Feature Store(Feast、Tecton 之类)。关键是设 TTL 和超时,别让一个慢查询拖死整条链路。

第二步:规则通道和模型通道物理隔离

这是我最想强调的一点。规则(rule-based)和模型(model-based)解决的是两个不同问题:

  • 规则:可解释、可应急、零延迟、能兜底。IP 黑名单、速率阈值、地域封禁。
  • 模型:精度高、能捕捉组合特征、但延迟高、不可解释、更新慢。

把两者塞进同一个服务、同一个进程、同一个超时预算里,是灾难的开始。正确做法是双通道并行,最后 fusion:

# scoring-pipeline.yaml
score_pipeline:
  timeout_budget_ms: 12
  channels:
    - name: rules
      type: local
      timeout_ms: 1
      weight: 0.3
      config:
        rules_file: /etc/scoring/rules.d/*.yaml
    - name: model
      type: remote
      endpoint: "http://model-server.scoring.svc:8500/v2/models/xgb/score"
      timeout_ms: 8
      weight: 0.7
      fallback_score: 0.0   # 模型挂了按中性处理,别按拒绝
  fusion:
    strategy: weighted_sum
    threshold_allow: 0.3
    threshold_block: 0.7
  fail_mode: open          # 整条链路超时 -> 放行

注意最后那个 fail_mode: open。这行配置背后是血泪。我们早期默认 fail-closed(超时就拒绝),结果一次特征服务扩容重启,直接把 15% 的正常流量拒了。打分系统永远应该 fail-open,除非你是反欺诈这种宁可错杀的场景。

第三步:决策怎么传到下一跳

分数算出来了,怎么用?三种模式,各有取舍:

模式 A:Header 注入 把分数塞进 X-Score: 0.42,下游服务自取。

# nginx/Envoy 侧注入
proxy_set_header X-Score $scoring_result;

优点:零额外依赖,链路清晰。缺点:任何支持自定义 header 的地方都能伪造,且分数会跟着请求一路传播,日志容易爆。

模式 B:决策即动作 不在 header 里传分数,直接让网关执行动作(放行/限流/挑战)。

# Envoy ext_authz 决策返回
- decision: throttle
  headers:
    x-ratelimit-limit: "10"
    x-ratelimit-remaining: "3"

我更推荐这个。 分数是内部实现细节,下游服务不该关心。让网关做决策,服务保持无状态。

模式 C:异步写队列 分数写 Kafka,离线分析用。这条链路绝不能在同步路径上等。

第四步:可复制的 Envoy ext_authz 打分配置

这是能直接跑的东西。我们用 Envoy 的 ext_authz filter 接打分服务:

http_filters:
  - name: envoy.filters.http.ext_authz
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
      grpc_service:
        envoy_grpc:
          cluster_name: scoring_service
        timeout: 10ms            # 硬超时,超过就 fail-open
      failure_mode_allow: true   # 关键:授权服务挂了放行
      with_request_body:
        max_request_bytes: 4096
        allow_partial_message: true
      status_on_error:
        code: 200                # 错误也返回 200,交给下游兜底
  - name: envoy.filters.http.router

配 failure_mode_allow: true 那一下,手是抖的——这意味着打分服务挂了没人拦。但这正是你和业务方要提前对齐的:可用性优先还是安全优先。没有标准答案,但必须有答案,而且写进文档。

第五步:性能与成本,这才是老板关心的

打分系统的账要算清楚。我们的实测数据(3 节点集群,日均 2 亿请求):

方案平均延迟增加P99 增加月成本运维复杂度
纯本地规则+0.3ms+0.8ms~$0(复用现有节点)低
规则 + Redis 特征+4ms+12ms~$800(Redis 集群)中
规则 + Redis + 模型 RPC+9ms+28ms~$3400(含 GPU 推理)高
全异步 + 下一跳决策+0.5ms+1.5ms~$1200中高

看最后一行的性价比。把打分从同步路径挪到异步 + 下一跳,延迟几乎归零,成本还降了。 代价是决策滞后一个请求周期——但对反爬、灰度这类场景,完全可接受。

HN 上那条关于数据中心耗电的讨论不是段子。GPU 推理节点的电费和散热,是真的会出现在你的账单里的。能离线算的模型,就别在线跑。

替代方案与取舍

别一上来就自建。老实讲:

  • Cloudflare / Fastly 边缘计算:Workers + KV 做轻量打分,延迟极低(边缘执行),但特征受限、调试痛苦。适合反爬、A/B。
  • AWS WAF + Lambda@Edge:生态成熟,但 Lambda 冷启动在打分场景是致命的,且计费按调用次数,高流量下贵得离谱。
  • 专用风控 SaaS(如各家 Fraud 产品):省心,但黑盒、贵、定制差。中小团队前两年用这个,规模上来再自建更划算。
  • 自建 ext_authz + Feature Store:最灵活,成本可控,但要有人专职维护。

我的选择偏好:日请求量 1 亿以下,先用云厂商的边缘方案白嫖能力;过 1 亿,特征复杂到 SaaS 撑不住,再考虑自建。别为了"技术先进"提前自建,运维成本会教你做人。


References & Community Insights

  • Envoy ext_authz 官方文档(配置字段和 failure_mode_allow 语义):https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_authz_filter
  • Feast Feature Store 架构与在线特征服务:https://github.com/feast-dev/feast
  • HN 讨论《Most data centers refusing to say how much water, electricity they use》,评论区关于实时计算真实成本的争论:https://news.ycombinator.com/item?id=44300000
  • Google SRE Book 中关于 Golden Signals 与延迟预算的章节(打分系统延迟预算的理论基础):https://sre.google/sre-book/monitoring-distributed-systems/

FAQ

Q: 打分逻辑应该放在网关还是独立服务? A: 轻量规则(< 1ms)放网关内联,重特征和模型放独立服务,通过 ext_authz 或 gRPC 调用。别把模型推理塞进网关进程,网关要的是稳,不是全。

Q: 特征服务超时了,打分应该返回什么? A: 默认返回中性分(如 0.0)并 fail-open。除非是反欺诈这类"宁可错杀"的场景,才考虑 fail-closed,且必须配熔断和告警。

Q: 打分结果用 header 传还是让网关直接决策? A: 让网关直接决策。header 传递分数会导致下游服务耦合内部实现,且存在伪造风险。分数是内部细节。

Q: 实时打分和 SLO 里的 Golden Signals 是什么关系? A: Golden Signals(Latency/Traffic/Errors/Saturation)是观测维度,打分系统是决策维度。前者告诉你系统怎么样,后者决定请求去哪。两者数据源可以共用,但目的完全不同。

Q: 打分模型的准确率重要还是延迟重要? A: 在线上流量打分场景,延迟优先。一个 P99 增加 30ms 的高精度模型,业务上是负收益。宁可牺牲几个点的 AUC,也要把延迟压在预算内。


✅ All agents reported back! ├─ 🟠 Reddit: 12 threads ├─ 🟡 HN: 12 storys │ 4,343 points │ 2,989 comments └─ 🗣️ Top voices: r/mildlyinfuriating, r/interestingasfuck, r/interesting

Elvin Hui

关于作者:Elvin Hui

Elvin 拥有 10+ 年企业级数据中心、云原生架构和网络安全经验。持有 CCNA、AWS 解决方案架构师认证。我致力于将一线的“踩坑”经验沉淀为真实、硬核的技术指南,拒绝空洞理论。