Skip to content
Charles Shao
Go back

API 网关与分布式追踪

views

前面三篇把进程内 RPC注册发现、东西向 Service Mesh 串成了服务之间的骨架。还缺两块面对外部与面对排障的拼图:API 网关(南北向入口)与分布式追踪(一次请求如何在几十个服务里被看见)。二者常落在同一条链路上——网关是注入 Trace 的最佳点,也是鉴权限流的总闸。

广告 API——出价回调、投放配置、报表拉取——全部从网关进。没有统一入口,鉴权与限流会散落;没有 Trace 传播,p99 毛刺只能靠「几个团队对表」。本篇作为系列收官,并与 异步削峰 交叉。

本文是微服务与 RPC 系列的第 4 篇(收官)。 系列顺序:① RPC 框架(开篇);② 服务注册与发现深挖;③ 服务网格 Service Mesh 深挖;④ API 网关与分布式追踪(本篇)

一句话定位:网关收敛南北向的身份、配额与路由;分布式追踪用 TraceId/SpanId 把一次请求在网关→RPC→DB 上的故事讲完整——没有传播,排障就只剩猜。

TL;DR

Table of contents

Open Table of contents

1. API 网关:南北向总闸

API 网关职责分层示意图。左侧 Client 进入中央 Gateway 面板,面板内六块职责:鉴权认证(JWT/OAuth/API Key)、限流配额、路由与协议转换(HTTP→gRPC)、可观测入口(注入 Trace)、WAF/安全与 TLS 终结、灰度金丝雀。右侧扇出到 Service A/B/C。注释提醒网关管南北向,东西向交给 Mesh/RPC,限流可与异步削峰配合。

网关是边界控制器,不是第二个业务单体。

1.1 该做什么

  1. 身份与鉴权:JWT/OAuth2/API Key、服务账号;把验签放在边缘,避免每个服务重复实现。对内服务账号与对外用户身份分开模型,别混用一套 token。
  2. 限流与配额:按租户、AppId、IP 令牌桶/漏桶;与广告「客户 QPS 合约」对齐。尖峰还可挡在门外,把突发交给队列(见 异步削峰)。
  3. 路由:按路径、header、版本把流量导向不同服务或金丝雀集合;HTTP→gRPC 协议转换也常放这里。
  4. 安全:TLS 终结、WAF、IP 允许列表;与 Mesh 的 mTLS(东西向)形成纵深。
  5. 可观测入口:创建/透传 Trace,产出入口 RED 指标——这是全链路追踪的第一环。

网关还常做请求体大小限制、超时预算注入、响应缓存(仅对幂等读)。每加一项能力,都要问:这是边界职责,还是业务在偷懒把逻辑往上推?

1.2 不该做什么

常见产品:Kong、APISIX、Envoy Gateway、云厂商 ALB/API Gateway、自研基于 Netty/OpenResty。选型看插件生态、配置热更、与 K8s/Mesh 的集成,而不是功能清单长度。多活场景要规划跨机房入口与调度,避免单区域网关成为全球单点。

1.3 与 Mesh Gateway 的关系

Istio Gateway / Envoy Gateway 可以把南北向也做成「网格的门」。组织上有两种常见切分:

无论哪条,限流与鉴权的权威来源要唯一——两侧各做一套且规则不一致,是排障噩梦。

2. 分布式追踪:把调用链画出来

分布式追踪传播示意图。顶部 Gateway→Service A→Service B→DB/Redis 依次传递 traceparent / 同一 TraceId / 新 SpanId。下方 Span 树:根 Span 为 Gateway handleRequest,子 Span 为 POST /bid、getBudget、Redis GET,展示 parent 关系与耗时。注释说明网关是注入最佳点,采样策略决定成本。

没有统一的 TraceId 传播,微服务排障就退化成「几个人对着几份日志对表」。

2.1 Trace / Span / Context

W3C Trace Context 的 traceparent 形如:00-<trace-id>-<span-id>-<flags>。gRPC 用 metadata,HTTP 用 header;Mesh Sidecar 也可自动繁殖,但应用自己出站若不透传,仍会断链——异步线程池、消息队列尤其是重灾区,要显式传递 context 或用 instrumented 执行器。

2.2 网关作为根

最佳实践:

  1. 外部请求进入网关时,若无 traceparent生成新 Trace;若有则继续(便于外部上游关联);
  2. 根 Span 覆盖「网关处理总耗时」;
  3. 转发上游时必须写入传播头,并记录路由目标、租户、HTTP 状态等属性;
  4. 与鉴权失败、限流拒绝类短路径也要留 Span——否则「被网关挡下的流量」在 Trace 里消失,误判为客户没打进来;
  5. 把 TraceId 打进网关访问日志,便于从「客户投诉的 request id」一键跳转。

2.3 跨异步边界

RPC 同步链路上的传播相对直观。难点在:

没有跨异步传播,「竞价 → 异步写明细 → 对账」在 Jaeger 上会碎成三段,排障价值大减。

消息队列场景额外注意:一条消息被多次投递时,每次消费可以是新 Span,但应共享同一条业务 Trace(或至少用 messaging.message_id link)。否则你会在系统里看到「很多短 Trace」,却拼不出一次客户请求的全貌。OpenTelemetry 的 span link 就是为此准备的。

时钟也重要:跨主机 Trace 的时间线依赖 NTP;时钟漂移严重时,火焰图会出现「子 Span 开始时间早于父 Span」的怪相。可观测基建和机房基础一样,时钟是隐形依赖。

3. OpenTelemetry 采集链路

OpenTelemetry 采集链路横向流水线:App+SDK 自动/手动埋点 → OTLP Export → OTel Collector(接收·处理·导出)→ Jaeger/Tempo 存储查询 → Grafana/告警关联 Metrics 与 Logs。注释强调 Collector 是缓冲与策略层,三支柱要用统一资源属性串联。

SDK 负责产数,Collector 负责治数,后端负责存与查。

3.1 为什么经 Collector

应用不要每个实例直连 Jaeger:

Collector 本身也要高可用与容量规划——它挂了或积压了,观测盲区会系统性出现。把它当「可观测数据面的网关」看待。

3.2 采样策略

策略含义适用
头部(Head)采样根 Span 决定是否采整条常态基线,如 1%–10%
尾部(Tail)采样看完整条再决定留不留保留错误/慢请求
强制采样错误、特定租户、debug header排障与大客户

广告竞价 QPS 极高时,全量 Trace 会先打爆存储和钱。正确做法是:低比例头部采样 + 错误/高延迟强制保留 + 关键租户提高采样。指标侧用高基数谨慎的 RED/SLO,Trace 负责「为什么慢」。

尾部采样需要 Collector 缓冲完整 Trace,成本更高、也更强——值得为「只留失败」买单。

3.3 与日志、指标对齐

每条日志打上 trace_id;Metrics 示例带 service.name资源属性与 Trace 一致。排障路径变成:告警 → 看入口成功率 SLO → 抽一条 Trace → 跳日志——而不是三套系统各猜各的。

属性要降基数campaign_id 可以放进 Span attributes(按需查询),不要打进 Prometheus label。否则你会先见证监控系统崩,再轮到业务系统。

4. 网关 × Mesh × RPC:边界怎么划

清晰边界比「所有能力叠三层」重要——本系列讲到的雪崩,根因往往是责任叠乘(重试×重试、发现脏列表×重试、入口无 Trace×各自为战)。

一张可执行的协作表:

关注点权威层
对外鉴权 / 租户配额网关
服务间 mTLS / AuthZMesh
业务幂等与写重试应用 / RPC SDK
Trace 根与传播网关创建 + 全链路透传
SLO 入口成功率网关指标为准

4.1 限流:网关挡尖峰,下游仍要自保

网关限流保护的是入口合约;它挡不住:

所以限流是纵深:网关配额 + Mesh/应用舱壁 + 依赖方超时。只用网关一道闸,东西向一抖照样死。

4.2 开发者体验:Portal 与契约

成熟的 API 网关背后往往还有开发者门户:密钥申请、配额查看、OpenAPI/Protobuf 文档、沙箱环境。这不改变技术分层,但决定「对外 RPC/HTTP 会不会变成无人维护的口头协议」。契约变更走网关侧的版本与废弃策略,与 §1 的路由版本相呼应。

4.3 BFF 与网关:别混为一谈

BFF(Backend for Frontend) 为特定客户端聚合接口,常含业务编排;API 网关做边界策略。把 BFF 逻辑写进网关插件,短期快、长期不可测:发布耦合、多端互相踩踏。正确姿势是网关后接独立 BFF 服务,网关只负责把 /mobile/* 路由过去。

对外 OpenAPI 与对内 Protobuf 可以并存:网关做协议转换时,要在 span 上标清 http.route 与下游 gRPC method,否则 Trace 里只看见一堆 POST /,广告排障时毫无辨识度。

参考


views
Share this post on:

Previous Post
Dubbo 深挖(开篇)· 架构全景、SPI 与一次调用全链路
Next Post
服务网格 Service Mesh 深挖