速率限制

Google Ads API 会按每个客户账号的客户 ID (CID) 和开发者令牌的每秒查询次数 (QPS) 对速率限制请求进行分桶处理,这意味着要分别针对 CID 和开发者令牌强制执行计量。Google Ads API 使用令牌桶算法对请求进行计量,并确定适当的 QPS 限制,因此,确切的限制会因任意给定时间的服务器总负载而异。

实施速率限制的目的是防止某个用户有意或无意地发出大量请求,给 Google Ads API 服务器带来过重负担,从而中断其他用户的服务。

违反速率限制的请求将被拒绝,并显示以下错误:RESOURCE_TEMPORARILY_EXHAUSTED

您可以主动减少请求数和从客户端限制 QPS,以此方式控制您的应用并减缓超出速率限制的情况。

有许多方法可以降低超出速率限制的几率。掌握各种企业集成模式 (EIP) 概念,如消息传递、重新传递和限流,可帮您开发更强大的客户端应用。

下面列出了一些推荐的做法,排在前面的是比较简单的策略,后面的则是比较强大但复杂的架构:

限制并发任务数

导致速率超限的一个根本原因是客户端应用产生了过多的并行任务。虽然我们不限制客户端应用可以产生多少并行请求,但这样做很容易超出开发者令牌层面的每秒请求数限制。

我们建议对所有进程和机器上将会发送请求的并行任务总数设置合理的上限,并以之为基础向上调整,从而在不超出速率限制的情况下优化吞吐量。

此外,您可以考虑从客户端限制 QPS(请参阅限流和使用速率限制器)。

批处理请求

对于多个操作,请考虑将其放入单个请求中进行批量处理。这最适用于 MutateFoo 调用。例如,如果您要更新 AdGroupAd 的多个实例的状态,则可以调用一次 MutateAdGroupAds 并传入多个 operations,而不是对每个 AdGroupAd 都调用一次 MutateAdGroupAds。如需了解更多示例,请参阅我们的批量操作指南

虽然批量发送请求可以减少请求总数,并减缓超出“每分钟请求数”速率限制的情况,但如果您对单个账号执行大量的操作,还是可能会触发“每分钟操作数”速率限制。

限流和使用速率限制器

除了在客户端应用中限制线程总数之外,您还可以在客户端实施速率限制器。这样可确保各进程和 / 或集群中的所有线程都受到客户端指定的 QPS 限制的约束。

您可以试试 Guava 速率限制器,或为集群环境实施自己的基于令牌桶的算法。例如,您可以生成令牌并将其存储在共享事务存储空间(例如数据库)中,每个客户端都必须先获取并使用令牌,然后才能处理请求。如果令牌用尽,客户端就必须等到下批令牌生成。

队列

消息队列是用于分配操作负载的解决方案,同时还可以控制请求和使用者速率。可用的消息队列方案有许多:一些是开源的,一些是专有的,而且其中许多都支持各种不同的语言。

在使用消息队列时,您可以有多个推送消息到队列的生成者和多个处理这些消息的使用者。限流可在使用者一端实施,方法是限制并发使用者的数量,或者为生成者或使用者实施速率限制器或限流器。

例如,如果消息使用者遇到速率限制错误,那么该使用者可以将请求返回到要重试的队列。与此同时,该使用方还可以通知所有其他使用方暂停处理几秒钟,以等待从错误中恢复。