1. 程式人生 > >oogle advertiser api開發概述——速率限制

oogle advertiser api開發概述——速率限制

速率限制 

 

為了向遍佈全球的 AdWords API 使用者提供可靠的服務,我們使用令牌桶演算法衡量請求數並確定每秒查詢數 (QPS) 速率。這樣做的目的是阻止惡意的或不可控的軟體大量入侵 AdWords API 伺服器,影響其他使用者

例如,如果某個失控的客戶端意外產生數以千計的執行緒來同時呼叫 AdWords API,AdWords API 伺服器就會在發現後返回一個 RateExceededError,要求呼叫軟體減速

必須注意的是,速率限制會因為不同的變數(包括伺服器負載)而有所波動。因此,我們不推薦固定的每秒查詢數 (QPS) 限制。更加重要的是,您必須瞭解如何處理 RateExceededError

,並在開發軟體時考慮到速率限制情況。

本指南將深入介紹更多詳情,幫助您瞭解 RateExceededError 以及如何避免超出速率限制

 

 

歷史

在舊版 AdWords API 中,超出限制的請求會在 API 伺服器上排隊,一直等到可以執行為止,從而導致一些請求的執行時間可能看起來非常長

最新的 API 不會長時間阻塞客戶端,而是會迅速失敗並返回 RateExceededError。我們相信這是一個非常重要的反饋機制,可確保您發現問題並相應調整您的應用

 

 

速率限制類型

我們意識到,有時您的 AdWords API 客戶端應用之所以會超出限制並收到 RateExceededError

,是由於一些您無法完全控制的因素。需要注意的是,這種情況並不會遭致懲罰。 RateExceededError 通常是短暫的,會在閒置 30 秒後自動解決

伺服器可能會強制執行多種不同型別的速率限制

客戶端應用可能超出經理帳號的開發者令牌範圍內的速率限制AdWords 帳號範圍內的速率限制

每個範圍內,系統並非採用嚴格的每秒查詢數速率限制,而是每分鐘請求數、每分鐘運算元和/或其他型別的速率限制。這使得穩定流量和突發流量都能流入 AdWords API

範圍和速率限制名稱都會包含在返回的 RateExceededError 中。

 

 

基於許可權級別的操作限制

只有一種型別的速率限制不會波動,那就是基於您開發者令牌的訪問許可權級別的操作限制。有兩種訪問許可權級別:基本標準。對基本訪問許可權級別帳號的限制是每天 10,000 次操作每天 1,000 次報告下載。新獲批准的開發者令牌預設會獲得基本訪問許可權級別。如果計劃每日執行超過 10,000 次的操作或超過 1,000 次的報告下載,您可以填寫 AdWords API 標準許可權申請表來申請標準許可權級別。使用任一許可權級別均無需支付任何費用。如需瞭解操作的計數方式,請參閱價目表

除操作限制外,其他所有速率限制都可能波動。因此,您必須處理應用中的 RateExceededError

RateExceededError 的元素

我們來更詳細地瞭解一下 RateExceededError,它包含 3 個非常重要的欄位:

  • rateScope - 所超出的速率範圍,可以是 ACCOUNTDEVELOPER
  • rateName - 包含所超出速率限制的名稱。例如,值可以是 RequestsPerMinute
  • retryAfterSeconds - 包含您的應用在重試請求前至少應該等待的秒數。我們建議在確定等待秒數時,將隨機乘數(例如 1 和 2 之間的浮點值,包含邊界值)應用於 retryAfterSeconds。如果您的程式並行傳送請求(例如多執行緒),請確保它們在等待後不會同時傳送新請求

 

警告:無法保證在等待 retryAfterSeconds 後您的新請求一定會成功。

如果您的應用持續超出速率限制,那麼您需要了解 rateScoperateName,以在應用中實施更長期的限制策略

 

 

 

 

帳號範圍與開發者範圍

速率範圍的值可以是 ACCOUNTDEVELOPER,這取決於您是在 AdWords 帳號一級還是在開發者令牌一級超出速率限制

開發者令牌速率範圍

每個註冊使用 AdWords API 的 AdWords 經理帳號都使用一個開發者令牌,您發出的每個請求都很可能與該開發者令牌關聯在一起。如果使用同一開發者令牌的所有客戶端請求合起來的 QPS 超出特定的速率限制,則可能會返回 RateExceededError,其中指明超出了開發者速率範圍的限制。

例如,如果經理帳號管理 100 個 AdWords 帳號,並且有多個客戶端軟體例項使用相同的開發者令牌,每秒跨不同的程序、執行緒或機器總共產生數百個請求,則客戶端軟體可能會收到有關開發者令牌速率範圍的 RateExceededError

帳號速率範圍

如果同一個應用在由經理帳號管理的單個 AdWords 帳號上傳送的每秒請求數較高,AdWords API 伺服器可能會針對這種超出帳號範圍內速率限制的行為返回 RateExceededError。例如,如果您的客戶端應用針對單個 AdWords 帳號生成多個執行緒來執行過多的 mutate() 操作,就可能會發生這種情況。

請注意,此帳號速率範圍內的速率限制是按對單個 AdWords 帳號傳送的請求總數來衡量的,而不管傳送請求時所用的是哪個開發者令牌

假設一個 AdWords 帳號由五個不同的經理帳號管理,則可能所有五個經理帳號都會同時針對同一個 AdWords 帳號提出請求。如果所有經理帳號合起來的每秒查詢數超過限制,那麼客戶端將收到有關帳號速率範圍的 RateExceededError

 

 

速率名稱及其重要性

除了瞭解速率範圍之外,您還必須瞭解所超出的速率限制類型。速率限制的型別會在 rateName 欄位中返回。常見的速率限制名稱包括:

  • RequestsPerMinute
  • OperationsPerMinute

 

請求與操作之間的區別

RequestsPerMinuteOperationsPerMinute 之間的區別是什麼?每個 SOAP 服務呼叫都記為一次請求。例如,每次您呼叫 CampaignService.mutate() 時,系統都會將其記錄為一次請求。不過,在 mutate 請求中,您可能傳送了 100 次 CampaignOperation,這將記為 100 次操作!

在上述示例中,雖然您可以通過將多項操作組合為一個請求來避開 RequestPerMinute 速率限制,但仍有可能觸及 OperationsPerMinute 速率限制

如需有關如何計算操作次數的更多示例,請訪問價目表頁面。

邊緣案例

以上是較為常見的速率名稱,但請注意,您可能還會超出其他型別的速率限制。如果您遇到這些問題,請在 AdWords API 論壇中告知我們。

 

 

 

降速

如果您的應用收到 RateExceededError,就應該減慢速度!否則可能會進一步延誤應用從錯誤中恢復最簡單的降速方法之一是在重新嘗試請求和/或繼續其他請求時考慮 RateExceededError.retryAfterSeconds 的值

例如,在 Java 中,要在處理其他請求前暫停執行緒,

try {
  ...
} catch (ApiException e) {
  for (ApiError error : e.getErrors()) {
    if (error instanceof RateExceededError) {
      RateExceededError rateExceeded = (RateExceededError) error;
      Thread.sleep(rateExceeded.getRetryAfterSeconds() * 1000);
    }
  }
  ...
}

  

 

這種方法簡單而直接,但可能無法取得最佳的總吞吐量,因此應用作最後的防禦手段

有許多方法可以降低超出速率限制的機率。掌握企業整合模式 (EIP) 概念(如訊息傳遞、重新傳遞和限流)可幫助您開發更強大的客戶端應用

我們將在下一節介紹這些推薦做法。請注意,即使採用了緩減措施,您還是應具備處理 RateExceededError 的能力

 

 

掌控

通過主動減少請求數量和從客戶端限制 QPS,您可以控制應用並儘可能減少 RateExceededError

下面是一些推薦的做法,按從最簡單的策略到最強大但最複雜的架構排列

  • 限制併發執行緒數
  • 批量傳送請求
  • 使用 BatchJobService
  • 限流/使用速率限制器
  • 向不同帳號交錯傳送請求
  • 排隊
  • 區別對待新帳戶與現有帳戶

限制併發執行緒數

通常發生 RateExceededError根本原因是客戶端應用產生了過多的執行緒,並且所有執行緒都在同時呼叫 AdWords API。雖然我們不限制客戶端應用可以擁有的併發執行緒數,但是通過不限量的執行緒併發傳送請求,可能很容易就會超過開發者令牌級別的每秒請求數限制

我們建議設定合理的併發請求執行緒總數上限(包括所有程序和機器),並從這一上限點向上調整,以在不超出速率限制的情況下優化吞吐量

此外,您可以考慮從客戶端限制所有執行緒總的 QPS(參閱限流/使用速率限制器)。

批量傳送請求

儘可能考慮批量處理多個請求,將其放入單個請求中,此方法最適用於 mutate() 呼叫。例如,如果您要更新 AdGroupAd 的多個例項的狀態,而不是對每個 AdGroupAd 呼叫 mutate() 一次,則可以呼叫 mutate() 一次,並一次傳入多個 AdGroupAdOperation。如需瞭解更多示例以及組合操作的最佳做法,請參閱最佳做法一節

在將多個操作組合為單個請求時,請一定注意大部分請求都是不可分割的。如果某個操作失敗,則整個請求都將失敗,不會更新任何內容。您可以利用部分失敗功能來改變這種行為

最後,雖然批量傳送請求可以減少請求總數並減緩超出“每分鐘請求數”速率限制的情況,但如果您對單個帳號執行大量的操作,還可能觸發“每分鐘運算元”速率限制

使用 BatchJobService

如果作業時間較長,需要處理大量操作,或者有跨越多項服務的大量操作,請考慮使用 BatchJobService。BatchJobService 可為您在 Google 雲端中以非同步方式安排和執行數以千計的操作,而您要做的就是輪詢結果以檢視作業是否完成

詳情請參閱批處理指南

限流/使用速率限制器

除了在客戶端應用中限制執行緒總數之外,您還可以在客戶端實施速率限制器。這樣的策略可確保各程序和/或叢集中的所有執行緒都受到客戶端指定的 QPS 限制的約束

例如,您可以試試 Guava 速率限制器,或自行實施適合在叢集環境中使用的令牌桶演算法。例如,您可以生成令牌並將其儲存在共享的事務性儲存區(如資料庫)中,每個客戶端在處理請求之前都需要先獲取和使用一個令牌。如果令牌用盡,客戶端必須等待系統生成下一批令牌

大多數情況下,限流操作可幫助您避免超出開發者令牌範圍內的速率限制

向不同帳號交錯傳送請求

如果您超出了帳號範圍的速率限制,則可以在客戶端對帳號設定速率限制 QPS;但如果您有成千上萬個帳號需要管理,這可能並不輕鬆。與此相比,更為簡單的策略是基於帳號交錯傳送請求

例如,如果您要對 10 個帳號執行 5000 次 mutate() 操作,其中一種方法是依序先將批量操作傳送到帳號 1,然後傳送到帳號 2、帳號 3,依此類推

  1. 為帳號 1 傳送 500 個 mutate 操作(重複 10 次即可達到 5000 次操作)
  2. 為帳戶2傳送500個mutate操作(同樣重複10次)
  3. …(直到完成對所有 10 個帳號的操作)

這種方法非常簡單,但您可能在每分鐘運算元方面超出帳號範圍內的速率限制。

通過交錯帳號,請求順序會變成如下這樣:

  1. 為帳戶1傳送500次mutate操作
  2. 為帳戶2傳送500次mutate操作
  3. 為帳戶3傳送500次mutate操作
  4. …(直到完成對所有 10 個帳號的操作)
  5. 為帳戶1傳送500次mutate操作
  6. 為帳戶2傳送500次mutate操作
  7. …(直到為每個帳號傳送完 5000 次操作)

以上示例展示了如何基於帳號交錯傳送請求,但您也應檢查 BatchJobService 是否滿足您的要求。詳情請參閱批處理指南

排隊

訊息佇列是分配操作負載的最佳解決方案,同時還控制請求和使用者速率。可用的訊息佇列方案有許多:有些是開源的,有些是專有的,而且其中有許多支援不同的語言

在使用訊息佇列時,您可以有多個推送訊息到佇列的生成者和多個處理這些訊息的使用者

限流可在使用者一端實施,方法是限制併發使用者的數量,或者為生成者或使用者實施速率限制器或限流器

例如,如果訊息使用者遇到 RateExceededError,那麼該使用者可以將請求返回到要重試的佇列。與此同時,該使用者還可以通知所有其他使用者暫停處理幾秒鐘,以等待從錯誤中恢復

針對新帳號和現有帳號使用不同的佇列或速率限制器

當您實施排隊或速率限制器策略時,請務必注意,對新的 AdWords 帳號的速率限制可能明顯嚴格於現有帳號(即 QPS 更低)。因此,如果您的組織經常建立新帳號且有大量的老帳號需要管理,則您可以考慮針對這兩種型別的帳號使用不同的速率限制器或限流器

通過這種方式,您可以最大限度地提高兩類帳號的吞吐量,而不會受限於 QPS 最低的帳號

一般情況下,新 AdWords 帳號所受的嚴格限制會在帳號釋出廣告後放寬