簡體   English   中英

如何在Python中限制對Web服務的請求率?

[英]How to limit rate of requests to web services in Python?

我正在開發一個與Web服務API接口的Python庫。 像我遇到的許多Web服務一樣,這個服務請求限制請求的速率。 我想為類實例提供一個可選參數limit ,如果提供的話,它將保持傳出請求,直到指定的秒數通過。

我理解一般情況如下:類的實例通過方法發出請求。 當它發生時,該方法發出一些信號,在某處設置一個鎖定變量,並開始倒數計時器的limit秒數。 (很可能,鎖定是倒數計時器本身。)如果在此時間范圍內發出另一個請求,它必須排隊,直到倒數計時器達到零並且鎖定被解除; 此時,發送隊列中最早的請求,並重置倒計時器並重新鎖定鎖定。

這是線程的情況嗎? 我還沒有看到另一種方法嗎?

倒計時器和鎖定應該是實例變量,還是它們屬於該類,以便該類的所有實例都保存請求?

另外,在庫中提供速率限制功能通常是個壞主意嗎? 我的理由是,默認情況下,倒計時為零秒,庫仍然允許開發人員使用庫並提供他們自己的速率限制方案。 鑒於任何使用該服務的開發人員都需要對請求進行速率限制,但我認為,為圖書館提供速率限制手段會更方便。

無論在庫中是否設置了速率限制方案,我都希望使用該庫編寫應用程序,因此建議的技術將派上用場。

非常感謝您的建議!

克里斯

使用隊列和調度程序可以更好地工作。

您將處理分為兩個方面: 發送 這些可以是單獨的線程(如果更容易,則可以是單獨的進程)。

Source方面以任何速度創建並排隊請求使他們滿意。

Dispatch方面做到了這一點。

  1. 獲取請求開始時間, s

  2. 將請求出列,通過遠程服務處理請求。

  3. 獲取當前時間, t 睡覺 - ( t - s )秒。

如果要運行直接連接到遠程服務的端,可以執行此操作,並繞過速率限制。 這對於使用模擬版本的遠程服務進行內部測試很有用。

關於這個的困難部分是為每個可以入隊的請求創建一些表示。 由於Python Queue幾乎可以處理任何事情,因此您無需執行任何操作。

如果您正在使用多處理,則必須將對象腌制以將它們放入管道中。

排隊可能過於復雜。 一個更簡單的解決方案是為您的類提供上次調用服務時的變量。 每當調用服務(!1)時,將waitTime設置為delay - Now + lastcalltime delay應該等於請求之間的最小允許時間。 如果這個數字是正數,那么在打電話之前要睡一會兒(!2)。 這種方法的缺點/優點是它將Web服務請求視為同步。 優點是它非常簡單且易於實現。

  • (!1):應該在收到服務的響應之后,在包裝器內(可能在包裝器的底部)發生。
  • (!2):在包裝器頂部調用Web服務周圍的python包裝器時應該發生。

當然,S.Lott的解決方案更優雅。

您的速率限制方案應該受到底層代碼(同步或異步)的調用約定的嚴重影響,以及此速率限制將在哪個范圍(線程,進程,機器,集群?)運行。

我建議保留實例中的所有變量,這樣您就可以輕松實現多個周期/控制率。

最后,聽起來你想成為一個中間件組件。 不要試圖成為一個應用程序並自己引入線程。 如果你是同步的,只需阻塞/休眠,如果你被其中一個調用,就使用異步調度框架。

如果您的圖書館設計為同步,那么我建議省略限制執行(盡管您可以跟蹤費率並至少幫助呼叫者決定如何遵守限制)。

我現在使用twisted來與幾乎所有東西進行交互。 通過使用將請求提交與響應處理分開的模型,可以輕松地執行此類操作。 如果您不希望您的API用戶必須使用twisted,那么您至少應該更好地理解他們的API以進行延遲執行。

例如,我有一個Twitter界面,代表xmpp用戶推送了相當荒謬的請求數量。 我沒有率限制,但我確實需要做一些工作來防止所有請求同時發生。

除非需要,否則不要重新發明輪子。 檢查真棒庫速率限制 如果你只是想以任何理由限制你的休息時間來限制你的生活,那就太完美了。

所以我假設一些簡單的東西像導入時間time.sleep(2)將無法在請求之間等待2秒

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM