Python并發(fā)請(qǐng)求下限制QPS(每秒查詢率)的實(shí)現(xiàn)代碼
前兩天有一個(gè)需求,需要訪問某API服務(wù)器請(qǐng)求數(shù)據(jù),該服務(wù)器限制了QPS=2(哈哈應(yīng)該都知道是哪個(gè)服務(wù)器了吧_(:з」∠)_),因?yàn)镼PS很小所以就使用阻塞式請(qǐng)求。后來開通了服務(wù),QPS提高到了20,阻塞式請(qǐng)求滿足不了這個(gè)QPS了,于是使用了GRequests來并發(fā)請(qǐng)求數(shù)據(jù),但這里又遇到了一個(gè)問題:并發(fā)太快,服務(wù)器通過發(fā)送錯(cuò)誤碼拒絕了很多數(shù)據(jù)的響應(yīng),造成了資源的浪費(fèi)。
故在此記錄以下幾種 節(jié)流(Throttle) 方法:
以下均假設(shè)有如下包和數(shù)據(jù)前提:
import grequests urls = [ "https://www.baidu.com", "https://www.google.com" ] requests = [ grequests.get(url) for url in urls ] * 1000 rate = 20 # 表示 20 請(qǐng)求/秒
time.sleep(1)
這是最簡單的方法,通過time.sleep(1)阻塞進(jìn)程來控制每秒并發(fā)數(shù)量。用公式表達(dá)如下:
from time import sleep req_groups = [ requests[i: i+rate] for i in range(0, len(requests), rate) ] ret = [] for req_group in req_groups: ret += grequests.map(req_group) sleep(1) print(ret)
令牌桶(token bucket)方法
這種方法較精確,可以確保誤差不超過±1(當(dāng)然前提是你的電腦和目標(biāo)服務(wù)器都能承受的了高并發(fā))。以下是耗時(shí)的公式表示:
from time import time class Throttle: def __init__(self, rate): self.rate = rate self.tokens = 0 self.last = 0 def consume(self, amount=1): now = time() if self.last == 0: self.last = now elapsed = now - self.last if int(elapsed * self.rate): self.tokens += int(elapsed * self.rate) self.last = now self.tokens = ( self.rate if self.tokens > self.rate else self.tokens ) if self.tokens >= amount: self.tokens -= amount else: amount = 0 return amount throttle = Throttle(rate) req_groups = [ requests[i: i+rate] for i in range(0, len(requests), rate) ] ret = [] for req_group in req_groups: ret += grequests.map(req_group) while throttle.consume(): pass # 阻塞 print(ret)
GRequests-Throttle
這是一個(gè)使用令牌桶(token bucket)方法進(jìn)行封裝的GRequests修改版,使用方法很簡單:
首先安裝grequests-throttle(清華鏡像源更新較慢,推薦使用阿里鏡像源)
pip install grequests-throttle
import grequests_throttle as gt ret = gt.map(requests, rate=rate) print(ret)
總結(jié)
如果并發(fā)請(qǐng)求數(shù)量較小,可以考慮使用time.sleep(1)簡單快捷;當(dāng)并發(fā)請(qǐng)求數(shù)量較大時(shí),使用令牌桶(token bucket)方法能最大化利用每一秒;如果不想寫太多代碼,可以使用GRequests-Throttle包進(jìn)行請(qǐng)求流量控制。
到此這篇關(guān)于Python并發(fā)請(qǐng)求下限制QPS(每秒查詢率)實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python并發(fā)請(qǐng)求下限制QPS(每秒查詢率)實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python對(duì)象與json數(shù)據(jù)的轉(zhuǎn)換問題實(shí)例詳解
JSON(JavaScript?Object?Notation)?是一種輕量級(jí)的數(shù)據(jù)交換格式,很受廣大用戶喜愛,今天通過本文給大家介紹Python對(duì)象與json數(shù)據(jù)的轉(zhuǎn)換問題,需要的朋友可以參考下2022-07-07基于Python+Flask實(shí)現(xiàn)一個(gè)簡易網(wǎng)頁驗(yàn)證碼登錄系統(tǒng)案例
當(dāng)今的互聯(lián)網(wǎng)世界中,為了防止惡意訪問,許多網(wǎng)站在登錄和注冊(cè)表單中都采用了驗(yàn)證碼技術(shù),驗(yàn)證碼可以防止機(jī)器人自動(dòng)提交表單,確保提交行為背后有一個(gè)真實(shí)的人類用戶,本文將向您展示如何使用Python的Flask框架來創(chuàng)建一個(gè)簡單的驗(yàn)證碼登錄系統(tǒng)2023-09-09selenium XPath定位的實(shí)現(xiàn)示例
XPath是一種在XML文檔中定位和選擇節(jié)點(diǎn)的語言,通過路徑表達(dá)式遍歷XML樹,支持節(jié)點(diǎn)選取、字符串匹配、數(shù)值計(jì)算、邏輯運(yùn)算等功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10如何基于opencv實(shí)現(xiàn)簡單的數(shù)字識(shí)別
現(xiàn)在很多場景需要使用的數(shù)字識(shí)別,比如銀行卡識(shí)別,以及車牌識(shí)別等,在AI領(lǐng)域有很多圖像識(shí)別算法,大多是居于opencv 或者谷歌開源的tesseract 識(shí)別,下面這篇文章主要給大家介紹了關(guān)于如何基于opencv實(shí)現(xiàn)簡單的數(shù)字識(shí)別,需要的朋友可以參考下2021-09-09