python使用第三方庫gevent模擬高併發請求

因爲工作中有個測試場景需要在1s內發送100個請求,需要併發,本來想用多線程或協程實現的,但最後發現gevent這個第三方庫,真的很好用。

gevent簡介:
gevent在python後臺開發中是必不可少的工具庫,它的強大在於它能使同步的python代碼在IO等待時間掛起,並執行其它任務,達到異步的運行效果,從而提高程序的運行效率,達到高併發的功能。

PS: 期待我後面的文章講解如何在生產環境正確使用gevent大幅度提高服務器性能吧:>)

廖雪峯的python教程是這樣說的:
gevent是第三方庫,通過greenlet實現協程,其基本思想是:
當一個greenlet遇到IO操作時,比如訪問網絡,就自動切換到其他的greenlet,
等到IO操作完成,再在適當的時候切換回來繼續執行。由於IO操作非常耗時,
經常使程序處於等待狀態,有了gevent爲我們自動切換協程,就保證總有greenlet在運行,
而不是等待IO。

官方文檔介紹如下:
gevent是一個基於libev的併發庫。它爲各種併發和網絡相關的任務提供了整潔的API。

直接上代碼:

from gevent import monkey
import gevent
import requests

monkey.patch_socket()   # 實現高併發,這個猴子補丁是必須的

n = 100  # 併發數量

def worker(i):
    """執行任務"""
	resp = requests.get(url)
    if resp.response_code == 200:
    	print(f'the {i} time request end')
        
               
def run():
    """開始運行"""
    workers = [gevent.spawn(worker, i) for i in range(n)]   # 傳參數i
    gevent.joinall(workers)  # 等所有請求結束後退出,類似線程的join
    print('Done!')


if __name__ == "__main__":
    run()

但是上面的請求有個問題是,100次的併發請求是瞬間就發出去的,和我們的1s鍾剛好發送100個請求不符合,這時,可以使用gevent.spawn_later() 實現定時發送,就是上一個請求和下一個請求之間隔了1/100秒,這樣就正好1s發送了100個請求
代碼如下:

from gevent import monkey
import gevent
import requests

monkey.patch_socket()   # 實現高併發,這個猴子補丁是必須的

n = 100  # 併發數量

def worker(i):
    """執行任務"""
	resp = requests.get(url)
    if resp.response_code == 200:
    	print(f'the {i} time request end')
        
               
def run():
    """開始運行"""
    workers = [gevent.spawn_later(i/n, worker, i) for i in range(n)]   # 其實和上面的代碼就這裏不一樣
    gevent.joinall(workers)  # 等所有請求結束後退出,類似線程的join
    print('Done!')


if __name__ == "__main__":
    run()

代碼解析: gevent.spawn_later函數中的 i/n 參數就是等待的秒數,如果是固定的值如10,則意思是10秒後才發送高併發請求,但如果是i/n,則代表每個請求之間間隔1/n秒,所有請求發完就是一秒,如果你想在2s鍾發完請求,那就是2/n。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章