Python并發(fā)請求下限制QPS(每秒查詢率)的實(shí)現(xiàn)代碼
前兩天有一個(gè)需求,需要訪問某API服務(wù)器請求數(shù)據(jù),該服務(wù)器限制了QPS=2(哈哈應(yīng)該都知道是哪個(gè)服務(wù)器了吧_(:з」∠)_),因?yàn)镼PS很小所以就使用阻塞式請求。后來開通了服務(wù),QPS提高到了20,阻塞式請求滿足不了這個(gè)QPS了,于是使用了GRequests來并發(fā)請求數(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 請求/秒
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ā)請求數(shù)量較小,可以考慮使用time.sleep(1)簡單快捷;當(dāng)并發(fā)請求數(shù)量較大時(shí),使用令牌桶(token bucket)方法能最大化利用每一秒;如果不想寫太多代碼,可以使用GRequests-Throttle包進(jìn)行請求流量控制。
到此這篇關(guān)于Python并發(fā)請求下限制QPS(每秒查詢率)實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python并發(fā)請求下限制QPS(每秒查詢率)實(shí)現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python+selenium 點(diǎn)擊單選框-radio的實(shí)現(xiàn)方法
今天小編就為大家分享一篇python+selenium 點(diǎn)擊單選框-radio的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
Python?ttkbootstrap?制作賬戶注冊信息界面的案例代碼
ttkbootstrap 是一個(gè)基于 tkinter 的界面美化庫,使用這個(gè)工具可以開發(fā)出類似前端 bootstrap 風(fēng)格的 tkinter 桌面程序。本文重點(diǎn)給大家介紹Python?ttkbootstrap?制作賬戶注冊信息界面的案例代碼,感興趣的朋友一起看看吧2022-02-02
Python寫一個(gè)基于MD5的文件監(jiān)聽程序
這篇文章主要給大家介紹了關(guān)于利用Python如何寫一個(gè)基于MD5的文件監(jiān)聽程序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
談?wù)勅绾问謩?dòng)釋放Python的內(nèi)存
Python不會(huì)自動(dòng)清理這些內(nèi)存,這篇文章主要介紹了談?wù)勅绾问謩?dòng)釋放Python的內(nèi)存,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12
Python周期任務(wù)神器之Schedule模塊使用詳解
這篇文章主要為大家詳細(xì)介紹了Python中的周期任務(wù)神器—Schedule模塊的安裝和初級(jí)、進(jìn)階使用方法,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-04-04

