# 计费 API 网关调用：API 即服务的架构

> 构建一条能够在高流量场景下准确计算 API 调用费用的计量流水线。了解 API 即服务产品的架构、批处理和常见问题。
- **Author**: Ayush Agarwal
- **Published**: 2026-05-18
- **Category**: Architecture, API, Usage-based Billing
- **URL**: https://dodopayments.com/blogs/zh/billing-api-gateway-calls-architecture

---

可靠地处理计费 API 网关调用，需要四层架构：在网关中进行埋点，为每次可计费调用发出一个事件；使用不会阻塞请求的批量异步传输；将事件转换为计量数据的聚合层；以及每天运行的对账任务，将网关日志与平台总量进行比较。跳过第四层，你的计费数据就会在不知不觉中逐渐偏离。

API 即服务产品成败取决于计量流水线。产品本质上是一系列 API 调用。客户为这些调用付费。成本基础也是这些调用。业务中所有重要事项都通过这一信号运行；如果计量在任一方向上偏差几个百分点，商业模式就会崩溃。

底层支付层同样需要这种精确性。我们关于[支付网关如何运作](https://dodopayments.com/blogs/how-payment-gateway-works)的解释文章对此进行了详细拆解。

本文将介绍一套可扩展、能经受故障并产出可信计费数据的 API 调用计量流水线架构。本文假设你的产品是 SaaS 或 AI 基础设施产品，而不是电商产品。

## API 调用计量究竟需要完成什么

一个实用的流水线需要完成五项工作。

它需要在网关边界捕获每次可计费调用，包括方法、路径、状态码和响应时间。捕获必须与请求同步执行，以避免事件丢失，但不能明显拖慢请求。

它需要将每次调用归因到特定客户，也可以进一步归因到 API 密钥、环境或功能。归因是让数据具备计费价值的关键。匿名调用对分析很有用，但不能用于生成发票。

它需要承受高流量。API 即服务产品经常会在所有客户范围内达到每秒数千甚至数万次调用。流水线不能依赖每次调用都直接写入计费系统。批处理和排队不是可选项。

它需要经受局部故障。网关调用彼此独立地成功或失败，计费 API 调用也彼此独立地成功或失败。计量流水线必须协调这些情况，确保客户只为实际发生的调用付费。

它需要支持商业模式。有些产品按调用收费，有些按成功调用收费，还有些会根据端点成本将调用分为不同层级收费。聚合层必须支持业务选择的计费模式。如果你还没有确定模式，那么在将流水线固定为某种形态之前，可以先阅读[如何为 API 访问收费](https://dodopayments.com/blogs/charge-for-api-access)指南，比较按次付费、分层订阅和预付额度。

能够出色完成这五项工作的流水线，看起来只是很小的一块基础设施。遗漏任何一项的流水线，都是一场等待发生的故障。

## 逐层拆解架构

一个清晰的流水线与其他用量计费系统一样，都由四层组成，但每一层都有 API 网关特有的注意事项。

### 网关中的埋点

最理想的埋点位置就是网关本身。无论你的网关是 Cloudflare Worker、带 Lambda 授权器的 AWS API Gateway、带自定义过滤器的 envoy 代理，还是自定义 Node 服务，原则都一样：请求完成路由和身份验证后、响应发回之前，捕获相关字段并发出计费事件。

需要捕获的字段包括客户标识符、API 密钥标识符（如果每个客户支持多个密钥）、路径、方法、响应状态码和响应时间。你还可以根据需要捕获请求大小、响应大小，以及影响定价的自定义元数据。

捕获过程必须是非阻塞的。如果计费事件发送失败或速度很慢，客户不应受到影响。网关可以写入本地队列后继续处理，也可以发送事件后立即继续，同时进行明确的错误处理。

### 大规模传输

高流量网关无法为每个请求同步调用一次计费 API。传输层需要进行批处理和缓冲。

最清晰的模式是使用本地内存队列或进程内队列，在短时间窗口内保存事件，再由后台刷新器批量发送事件到计费 API。批处理可以将每次请求的开销降低一个数量级，并让数千个事件分摊网络往返成本。

对于非常高的流量，可以在网关和刷新器之间加入托管队列。Cloudflare Queues、SQS、Kafka 或 Pub/Sub 都可以使用。网关将事件写入队列，独立的工作进程集群从队列中读取事件并提交批次。这种分离方式可以让你独立扩展网关和刷新器，并吸收超过计费 API 瞬时处理能力的流量峰值。

传输层还负责重试。临时性的计费 API 故障应使用指数退避和幂等键进行重试。持续性故障应上报监控系统，而不是静默丢弃。

### 平台中的聚合

计费平台会将事件聚合为计量数据。对于 API 调用计费，常见模式包括计数聚合（累计事件数量）和对数值属性进行求和聚合（当调用具有不同权重时）。

计数聚合最简单，也最常见。每个事件计为一次调用，客户按调用次数付费。

求和聚合允许你为不同端点分配不同权重。简单的读取端点计为 1，计算量大的端点计为 5。定价仍然按单位计算，但单位定义包含了相对成本。这是在不将不同成本暴露为独立价格的情况下处理端点差异的最清晰方式。

对于更复杂的定价，一些产品会使用多个计量器：总调用次数计量器、高级端点调用次数计量器，以及在计费方式不同的情况下使用的失败调用次数计量器。事件都发送到同一个摄取 API，但通过不同的事件名称进行标记，再映射到不同的计量器。

### 跨边界对账

对账层用于发现网关日志记录的实际情况与计费平台记录的情况之间的差异。两者应当一致，但实际运行中有时并不会。

每天的对账任务会提取当天的网关日志，按客户和计量器进行聚合，并与平台总量进行比较。发现的差异会被记录并调查。

常见差异原因包括：批次提交失败且未进行重试；幂等冲突导致有效事件被丢弃；网关崩溃导致传输中的事件丢失；以及网关节点之间的时钟偏移导致事件被归入错误日期。

对账任务让流水线能够长期保持可信。没有它，偏差会在不知不觉中不断累积。

## 高流量场景中的常见问题

API 网关计费有一些 LLM 计量不需要处理的特殊陷阱。

第一个是事件量。即使规模适中的 API 产品，每月也可能产生数十亿个事件。流水线必须从第一天起就按这一规模进行设计，因为事后改造会非常痛苦。在网关处进行批处理、采用异步传输以及进行异步聚合，都是标准做法。

第二个是请求与事件的比例。一次 API 调用通常对应一个计费事件，但并非总是如此。有些产品会针对流式端点按响应分块计费，有些产品会按出口字节数计费。请求与事件之间的关系必须明确定义，否则很容易少计或多计。

第三个是失败调用的计费政策。由你的服务返回 500 错误的请求属于你的责任，客户通常认为不应为此付费。返回 401 的请求属于客户的责任，你可以选择收费，也可以选择不收费。限流器返回 429 的请求同样属于你的调用。必须明确制定政策，并让网关知道哪些调用需要发出计费事件。

第四个是边缘层的客户归因。有些流量在边缘层没有清晰的客户标识符。匿名流量、格式错误的请求、使用已撤销密钥的请求，都会抵达网关，需要进行处理。这些请求通常不计费，但需要记录下来，用于分析和滥用检测。

其中越来越大的一部分未归因流量来自代理，而不是滥用行为。如果你希望将其商业化，而不是直接拒绝，可以使用 [x402 协议](https://dodopayments.com/blogs/x402-protocol)，让网关通过 HTTP 402 返回价格，并在没有预先存在账户的情况下完成调用结算，将不可计费请求转化为可计费请求。

第五个是客户侧的重试。如果客户的客户端积极重试失败请求，你的网关看到的调用次数会多于逻辑操作次数。计费事件政策需要处理这种情况。有些产品无论如何都会对每次调用收费，另一些产品只对一组重试序列中成功的调用收费。两种方式都合理，但必须明确选择并保持一致。

## Dodo Payments 如何融入其中

Dodo Payments 提供聚合层以及传输层所需的事件摄取 API。你可以在控制面板中使用计数或求和聚合定义计量器，从网关或工作进程调用事件摄取 API，然后由平台处理聚合、订阅总量、超额用量和开票。

针对 API 网关场景，平台提供了 API 网关蓝图，将摄取 API 封装在适合高流量场景的 SDK 中。该 SDK 支持在网关侧进行批处理、使用幂等机制自动重试，以及使用结构化事件格式，其中包含端点、方法、状态码和响应时间等元数据。

其架构优势与 LLM 计量相同。封装、传输和聚合都经过大规模测试。你只需将 SDK 接入网关，并指定计量器事件名称，用量就会自动被跟踪。你仍然需要对账层和政策决策，但基础设施已经解决。

API 网关蓝图和事件摄取 API 的完整参考资料位于 [API 网关摄取蓝图](https://docs.dodopayments.com/developer-resources/ingestion-blueprints/api-gateway)和[用量计费指南](https://docs.dodopayments.com/developer-resources/usage-based-billing-guide)中。本文介绍架构，文档介绍实现方式。

## API 即服务产品的参考架构

综合来看，典型 API 即服务产品的流水线大致如下。

客户流量抵达边缘层，通常是带有 Worker 的 CDN。Worker 使用客户的 API 密钥验证请求，查找客户记录，然后将请求路由到源站。响应发送后，Worker 发出计费事件，其中包含客户标识符、端点、方法、状态码和响应时间。事件会被写入本地队列或托管队列。

工作进程集群消费队列中的事件。工作进程对事件进行批处理，并使用幂等键将其提交到事件摄取 API。提交成功的事件会从队列中移除，提交失败的事件会使用退避策略重试。持续性故障会被上报监控系统。

计费平台将事件聚合到相关计量器中。对于按次定价模型，单个计数计量器保存总量；对于加权定价，求和计量器保存加权总量。订阅和配额引用该计量器。当总量超过配额时，会自动触发超额用量。

你的应用通过平台 API 读取计量器总量，在客户控制面板中显示用量。客户看到的数字与驱动发票的数字完全一致。

对账任务每天运行一次。它提取网关日志和平台总量，按客户进行比较，并在差异超过阈值时发出提醒。任何超过阈值的情况都会由人工调查。

这种架构可以以可预测的成本和准确性处理每月数十亿次调用。组件并不复杂，真正让它发挥作用的是执行上的纪律。

## 运营维护

以下几个习惯可以让流水线保持健康。

监控批处理延迟。如果批次刷新所需时间超过设计预期，队列就会不断填充并形成积压。要在它演变成计费延迟之前发现问题。

监控幂等键冲突。冲突通常意味着代码变更导致密钥生成出现错误，从而可能丢弃有效事件。

监控对账差异。如果每日对账报告显示网关日志与平台总量之间的差距正在扩大，说明某些数据正在丢失。应立即调查，而不是等到月底。

进行混沌测试。定期向计费 API 或队列注入故障，观察流水线的处理方式。真实故障一定会发生，提前演练的成本很低。

记录重试、错误和加权端点相关政策。没有文档，政策会随着工程师更替而逐渐偏离。有了文档，政策就能得到执行并保持透明。

## 结语

API 网关计量属于那种正常运行时几乎隐形、出现问题时却非常明显的基础设施。客户会抱怨账单与预期不符，财务会抱怨收入与流量不符，工程团队则会抱怨流水线难以调试。

这里介绍的架构并不新颖。十多年来，可观测性和分析系统一直在使用相同的架构形态。将其应用于计费，并加入对账层和清晰的政策决策，就能构建一条可扩展且保持准确的流水线。第一次就按这种方式构建，整个业务之后都会运行得更加顺畅。

## 常见问题

### 我应该为失败调用收费吗？

这是一个政策决策。大多数产品不会对 5xx 错误收费，因为这些错误属于服务提供方的责任。大多数产品会对 4xx 错误收费，因为这些错误属于调用方的责任。有些产品只对成功调用收费，以保持模型简单。请明确决定并记录相关政策。

### 如何处理成本差异很大的端点？

最清晰的模式是使用求和计量器，让每个事件携带一个反映成本的权重。低成本端点的权重为 1，高成本端点的权重更高。计量器将这些权重相加。客户按单位付费，而单位定义会编码相对成本，无需将端点定价暴露为独立方案。

### 网关的批次大小应该是多少？

这取决于你的流量和延迟容忍度。常见的起点是 100 个事件或 1 秒，以先达到者为准。之后根据实际观察到的批处理延迟和摄取 API 吞吐量进行调整。

### 如何防止客户累积巨额账单？

设置与计量器总量关联的硬性上限。当客户的计量器超过配置上限时，网关开始拒绝其请求，并返回清晰的错误信息。对于 API 即服务产品来说，这不是可选项。没有上限时，一个配置错误的客户客户端就可能在短时间内给双方带来巨额成本。将上限与我们关于[计费 UX、用量上限和提醒](https://dodopayments.com/blogs/billing-ux-usage-caps-alerts)指南中的提醒模式结合起来，让客户提前看到即将触及上限。

### 可以将同一条流水线同时用于分析和计费吗？

事件可以同时为两者提供数据，但计费的事实来源应当是开具发票的平台。本地副本可以用于分析控制面板。当两者出现差异时，以平台数据为准。构建对账任务，在差异超过容忍范围时发出提醒。
---
- [More Architecture articles](https://dodopayments.com/blogs/category/architecture)
- [All articles](https://dodopayments.com/blogs)