本文介绍如何使用 Service Infrastructure 对与 Service Management API 集成的托管服务实施速率限制。
托管服务可以为许多服务使用方提供服务。为了保护系统容量并确保合理使用,托管服务通常使用速率限制在服务使用方之间分配容量。 借助 Service Management API 和 Service Control API,您可以管理和实施速率限制。
配置速率限制
如要使用速率限制功能,请为您的服务生产者项目在服务配置中配置 _quota metrics_
和 _quota limits_
。
当前,受支持的速率限制是每个服务使用者每分钟的请求数,其中服务使用者是由 API 密钥、项目 ID 或项目编号标识的 Google Cloud 项目。对于速率限制,请求是一个模糊的概念。服务可以选择 HTTP 请求作为请求,也可以选择有效负载的字节作为请求。速率限制功能独立于请求的语义。
配额指标
指标是命名的计数器,用于衡量特定值随时间变化的情况。例如,服务收到的 HTTP 请求次数就是一个指标。配额指标是用于限制配额和速率的指标。当服务发生某项活动时,一个或多个配额指标可能会升高。当指标值达到预定义的配额限制时,服务应拒绝该活动并显示 429
错误。
配额限制
配额限制是对配额指标的强制性限制。例如,每个服务使用方每分钟的请求次数就是一个配额限制。目前,唯一受支持的配额限制类型是每位使用者每分钟的配额,具体来说就是 1/min/{project}
。
服务/使用方对的实际速率限制由 3 项设置控制:
- 为托管服务指定的默认限制。
- 服务使用方对应的服务提供方替换值。
- 服务使用方对应的服务使用方替换值。
有效的速率限制如下:
- 如果没有任何替换值,则采用默认限制。
- 如果有服务提供方替换值,但没有服务使用方替换值,则采用服务提供方替换值。
- 如果有服务使用方替换值,但没有服务提供方替换值,则采用服务使用方替换值和默认限制中的最小值。
- 如果既有服务提供方替换值,也有服务使用方替换值,则采用服务使用方替换值和服务提供方替换值中的最小值。
强制实施速率限制
要强制实施速率限制,属于托管式服务的每台服务器都需要定期调用 Service Control API services.allocateQuota
方法。如果 services.allocateQuota
方法的响应指示用量超出限制,则服务器应拒绝相应传入请求并显示 429
错误。如需了解详情,请参阅 services.allocateQuota
方法的参考文档。
建议每台服务器都应使用批处理、缓存和预测逻辑来提高系统性能和可靠性。一般来说,一台服务器每秒只应为同一(服务/使用方/指标)元组调用 services.allocateQuota
方法一次。
下面的示例演示如何调用 services.allocateQuota
方法来检查速率限制。服务名称、使用方 ID、指标名称和指标值这些重要请求参数必须正确设置。services.allocateQuota
方法会尝试将(服务/使用方/指标)元组对应的用量增加指定的值。如果增加后的使用量超出限制,则会返回错误。以下示例使用 gcurl
命令演示该调用。如需了解如何进行这项设置,请参阅 Service Control API 使用入门。
gcurl -d '{ "allocateOperation": { "operationId": "123e4567-e89b-12d3-a456-426655440000", "methodName": "google.example.hello.v1.HelloService.GetHello", "consumerId": "project:endpointsapis-consumer", "quotaMetrics": [{ "metricName": "endpointsapis.appspot.com/requests", "metricValues": [{ "int64Value": 1 }] }], "quotaMode": "NORMAL" } }' https://servicecontrol.googleapis.com/v1/services/endpointsapis.appspot.com:allocateQuota { "operationId": "123e4567-e89b-12d3-a456-426655440000", "quotaMetrics": [ { "metricName": "serviceruntime.googleapis.com/api/consumer/quota_used_count", "metricValues": [ { "labels": { "/quota_name": "endpointsapis.appspot.com/requests" }, "int64Value": "1" } ] } ], "serviceConfigId": "2017-09-10r0" }
错误处理
如果 HTTP 响应代码为 200
,并且响应中包含 RESOURCE_EXHAUSTED
QuotaError
,则您的服务器应拒绝相应请求并显示 429
错误。如果该响应不包含任何配额错误,则您的服务器应继续处理传入请求。对于所有其他配额错误,您的服务器应拒绝相应请求并显示 409
错误。考虑到安全风险,您在错误消息中添加错误信息时应非常谨慎。
如果出现的是其他任何 HTTP 响应代码,那么您的服务器可能存在一些编程错误。建议您在调试问题时让服务器继续处理传入请求。如果 services.allocateQuota
方法返回任何意外错误,则您的服务应记录该错误并接受传入请求。您可以稍后再调试该错误。
应急开启
速率限制功能的作用是防止您的托管服务过载,以及在服务使用方之间合理分配服务容量。由于大多数服务使用方在正常操作期间都不会达到其速率限制,因此如果速率限制功能不可用,您的托管服务应接受所有传入请求(也称为“应急开启”)。 这可以避免服务可用性受到速率限制系统的影响。
如果使用 services.allocateQuota
方法,则服务必须忽略 500
、503
和 504
错误,而无需重试。为避免过度依赖速率限制功能,Service Control API 会定期执行有限的错误注入。