API 网关服务质量(QoS)是指当不同工作负载争夺有限容量时,为它们提供可预测的差异化处理。在网关层,这通常意味着对流量分类,以可持续速率准入请求,限制并发,隔离关键上游容量,并衡量每个类别是否满足其服务等级目标(SLO)。
QoS 不是网关上的某个单一开关,也不能保证网关一定能挽救过载的依赖项。网关只能控制请求路径中某一点的准入和路由。端到端服务质量仍取决于客户端、网络、网关、上游服务和数据存储。
核心要点
- 从工作负载专属 SLO 出发,而不是从插件列表出发。
- 使用可信身份和路由上下文对流量分类;不能只信任客户端提供的优先级请求头。
- 将请求速率限制与并发限制结合,因为即使请求速率不高,也可能耗尽缓慢上游的容量。
- 为关键工作负载预留或隔离容量,不要期望一个共享资源池自然产生严格优先级。
- 明确定义过载行为:有限延迟、
429 Too Many Requests或503 Service Unavailable都比无界队列更安全。 - 通过各流量类别的延迟、错误、拒绝和饱和信号验证结果。
API 网关中的 QoS 是什么
网络 QoS 通常指数据包调度或带宽处理,而 API 网关 QoS 工作在应用层。它可以区分结账请求与报告导出,将请求关联到经过认证的调用方,并根据操作的业务与资源特征执行策略。
实用的网关 QoS 设计包含五个部分:
| 部分 | 要回答的问题 | 典型网关控制 |
|---|---|---|
| 服务目标 | 该工作负载需要获得怎样的体验? | 延迟、可用性或吞吐量 SLO |
| 分类 | 该请求适用哪项策略? | 路由、方法、调用方、凭证范围或已验证声明 |
| 准入 | 现在是否应允许请求进入系统? | 速率、配额、请求大小和并发限制 |
| 隔离 | 一个类别能否占用另一个类别的容量? | 独立路由、上游池、实例或区域容量 |
| 反馈 | 策略是否产生了预期结果? | 指标、追踪、日志、告警和容量测试 |
Google 关于 SLO 的 SRE 指南建议从用户真正关心的指标出发,并支持为延迟和吞吐量需求不同的工作负载定义不同目标。这一区分正是 API QoS 的基础:交互式请求与批量导出即使共享同一主机名,也不应自动使用相同目标。
从 SLO 反向设计 QoS
1. 按用户结果定义流量类别
类别数量应尽量少,确保可以运维。可以从以下三类开始:
- **关键交互:**认证、支付或控制操作,其延迟与可用性对用户可见。
- **标准交互:**具有常规延迟预期的普通读写操作。
- **后台或批量:**导出、同步、分析和其他可以容忍延迟的工作。
为每个类别写明 SLI、目标、测量窗口和过载响应。例如,团队可以衡量符合条件的关键请求中有多少在选定延迟阈值内完成,同时按完成率和吞吐量衡量批量工作。实际目标必须来自工作负载测试和业务要求;复制其他系统的数字无法证明它对你的系统安全。
2. 使用可信上下文对请求分类
路由和方法是有用的初始信号,经过认证的调用方身份、租户和凭证范围可以进一步细分策略。不能信任客户端提供的 X-Priority: critical 之类请求头,除非认证层会移除传入值,并根据经过验证的身份或策略派生新值。
分类还必须考虑请求成本。一个低成本元数据请求和一个大型报告请求即使都是 GET,也不应消耗相同预算。
3. 同时实施速率与并发准入
速率限制控制一段时间内的到达量,并发限制控制同时处理的工作量。通常两者缺一不可:
- 大量快速请求可能超过约定流量速率,却不会耗尽上游。
- 少量慢请求即使到达速率不高,也可能占满全部连接、工作进程或数据库槽位。
Apache APISIX 提供 limit-req限制请求速率,limit-count限制一个时间窗口内的配额,并通过 limit-conn控制并发请求。这些控制可以限制流量,但本身并不会创建一个总是优先执行关键任务的调度器。
4. 在需要优先级的地方隔离容量
如果关键路由和批量路由共享全部网关实例、上游节点、连接池和依赖项,策略错误仍可能让批量工作占用关键容量。更强的隔离方式包括:
- 为交互式和批量工作负载配置独立上游池;
- 为最重要的类别使用专用网关实例或 Kubernetes Deployment;
- 在共享上游限制之前,先设置每租户或每调用方配额;
- 使用独立的自动扩缩容信号与最大容量;
- 对不需要同步响应的任务使用异步任务系统。
隔离成本高于共享资源池,因此只应将其用于重要的故障边界。目标不是复制每一个组件,而是阻止已知过载路径影响更高优先级的服务。
5. 明确选择过载行为
每个队列都有上限,只是这个上限可能来自配置,也可能在故障中才被发现。对于小规模突发,优先采用短暂且有界的延迟;多余工作应在消耗上游资源前拒绝。
调用方超过调用方、路由或套餐限制时,使用 429 Too Many Requests。服务因容量不足无法接收工作时,使用 503 Service Unavailable。如果系统能计算出有意义的重试时间,可以返回 Retry-After;否则客户端应使用有上限并带抖动的退避策略。不要通过把工作放入无界队列来隐藏饱和。
APISIX 准入控制示例
下面的 Admin API 请求是关键交互路由的配置片段,数值仅用于说明,并非生产建议。该路由接受有界的每客户端速率,允许短暂延迟少量突发请求,并在转发到上游前限制并发请求。
1curl "http://127.0.0.1:9180/apisix/admin/routes/critical-api" \
2 -X PUT \
3 -H "X-API-KEY: ${admin_key}" \
4 -d '{
5 "name": "critical-api",
6 "uri": "/checkout/*",
7 "plugins": {
8 "limit-req": {
9 "rate": 20,
10 "burst": 10,
11 "key_type": "var",
12 "key": "remote_addr",
13 "rejected_code": 429
14 },
15 "limit-conn": {
16 "conn": 10,
17 "burst": 2,
18 "default_conn_delay": 0.05,
19 "key_type": "var",
20 "key": "remote_addr",
21 "policy": "local",
22 "rejected_code": 503
23 },
24 "prometheus": {}
25 },
26 "upstream": {
27 "type": "roundrobin",
28 "nodes": {
29 "checkout-1.internal:8080": 1,
30 "checkout-2.internal:8080": 1
31 }
32 }
33 }'
该片段特意使用 remote_addr,便于在测试环境观察行为。生产环境的调用方策略应优先使用经过认证的调用方或租户标识符,但首先要明确可信身份如何传递给 APISIX。还要注意,policy: local 会在每个 APISIX 节点上分别保存计数器。如果多个节点必须执行同一个共享配额,应评估限流插件文档中的 Redis 或 Redis Cluster 策略,同时考虑该共享依赖项对可用性和延迟的影响。
应采用多种并发和到达模式测试,而不是只用一种稳定负载:
1seq 1 20 | xargs -P20 -I{} \
2 curl -s -o /dev/null -w "%{http_code}\n" \
3 "http://127.0.0.1:9080/checkout/{}"请求成功、延迟和拒绝的具体比例取决于上游响应时间与到达时机。成功标准并不是复制本文中的固定输出,而是观察到的行为符合配置策略,并且上游保持在经过测试的运行范围内。
将策略作为控制回路进行测量
APISIX 的 prometheus 插件可显示请求状态、当前客户端连接、上游健康状况和延迟直方图。其 HTTP 延迟指标可以区分总请求延迟、上游延迟,以及 APISIX 和下游产生的其余延迟。
至少跟踪:
- 各流量类别的 SLO 达成情况;
- P50、P95 和 P99 请求及上游延迟;
- 已准入、已延迟和已拒绝的请求;
- 进行中的请求或连接;
- 上游错误和健康状态;
- 网关与上游 CPU、内存、连接和队列的饱和度。
避免使用无界指标标签。原始用户 ID、请求 ID 或任意路径可能创建高基数时间序列,让监控系统本身成为故障的一部分。
QoS 应作为反馈回路持续审查:测量 SLI,将其与 SLO 比较,每次更改一项策略或容量假设,再重新测试。如果某项限制保护了上游,却拒绝过多合法流量,说明设计尚未完成;过于宽松、只是把队列转移到下游的限制也同样如此。
API 网关 QoS 检查清单
- 流量类别是否基于不同的用户结果?
- 每个类别是否有可衡量的 SLO 和过载响应?
- 分类是否来自可信路由和身份上下文?
- 速率、配额和并发限制是否与经过测试的容量关联?
- 是否在必要位置将关键容量与批量工作隔离?
- 是否理解本地与共享限流器的语义?
- 客户端能否区分配额拒绝与服务不可用?
- 仪表盘能否按类别显示延迟、拒绝、饱和度和上游健康状况?
- 是否使用突发流量、慢速上游和部分故障测试过策略?
常见问题
API 网关能否独立保证 QoS?
不能。它可以控制准入、路由和一部分故障行为,但端到端服务质量还取决于上游容量、依赖项、网络和客户端。
限流等同于流量优先级吗?
不等同。限流约束准入的流量,优先级则决定请求竞争时哪些工作应该先得到服务。如果严格的容量优先级很重要,可能需要使用独立路由、资源池或部署。
每个流量类别都应该使用独立网关集群吗?
通常不需要。应从逻辑分类和限制开始。只有当共享容量产生不可接受的故障路径,或合规及所有权要求隔离时,才增加物理隔离。
后续步骤
可以继续阅读 API 网关流量控制策略,了解更广泛的控制面;如果上游选择是限制因素,请查看 API 网关负载均衡优化。
如果企业部署需要围绕 Apache APISIX 集中管理策略并获得运维支持,可以进一步了解 API7 Enterprise。
