日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python asyncio tcp转发_aiohttp + asyncio 异步网络请求基本操作

發(fā)布時(shí)間:2023/12/15 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python asyncio tcp转发_aiohttp + asyncio 异步网络请求基本操作 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:matrix

被圍觀: 1,949 次

發(fā)布時(shí)間:2019-11-26

無評(píng)論 ?

💡NOTICE:這是一個(gè)創(chuàng)建于 379 天前的主題,其中的信息可能已經(jīng)有所發(fā)展或是發(fā)生改變。最近修改:2020-08

asyncio異步操作需要關(guān)鍵字async,await。

async用來聲明方法函數(shù),await用來聲明耗時(shí)操作。

但是await關(guān)鍵字后面要求為awaitable對(duì)象 且只能在async方法內(nèi)部使用,不能在外部入口中使用。asyncio的語法其實(shí)是系統(tǒng)內(nèi)部實(shí)現(xiàn)了yield from協(xié)程。

aiohttp用來代替requests的請(qǐng)求庫,且支持異步操作。

主要優(yōu)點(diǎn)體現(xiàn)在并發(fā)請(qǐng)求多個(gè)耗時(shí)任務(wù)時(shí),自動(dòng)安排耗時(shí)時(shí)的操作,避免cpu等待一個(gè)一個(gè)請(qǐng)求。

單個(gè)請(qǐng)求操作

import aiohttp

import asyncio

#get 請(qǐng)求

async def get():

async with aiohttp.request('GET','https://api.github.com/users/Ho',params={'arg1':123}) as response:

# response.request_info # 請(qǐng)求信息

return await response.json()

rel = asyncio.run(get())

# 或者使用下面方式 手動(dòng)關(guān)閉異步事件循環(huán)

# loop = asyncio.get_event_loop()

# rel = loop.run_until_complete(get())

# loop.close()

print(rel)

多個(gè)并發(fā)請(qǐng)求操作

主要區(qū)別在于異步任務(wù)的添加操作,運(yùn)行。

請(qǐng)求測試url:

http://link/await/1 # delay 1sec

http://link/await/2 # delay 2sec

...

請(qǐng)求測試:

import aiohttp

import asyncio

#get 請(qǐng)求

async def get():

async with aiohttp.request('GET','http://link/await/1') as response:

return await response.text()

# 所有請(qǐng)求任務(wù)

async def all_req():

#async with asyncio.Semaphore(5): 設(shè)置并發(fā)的連接數(shù)

# https://docs.python.org/zh-cn/3/library/asyncio-sync.html#asyncio.Semaphore

task = []

#添加請(qǐng)求任務(wù)

for i in range(5):

task.append(asyncio.create_task(get()))

#create_task 方法等同于 ensure_future()方法

#手冊(cè)建議首選 create_task方法

# https://docs.python.org/zh-cn/3/library/asyncio-future.html?highlight=ensure_future#asyncio.ensure_future

return await asyncio.gather(*task)#傳入?yún)?shù) tuple類型 作為位置參數(shù)

# 等同于 asyncio.gather(get(),get())

# gather()方法用于收集所有任務(wù)完成的返回值,如果換成wait()方法會(huì)返回任務(wù)tuple對(duì)象,(done,pending)

rel = asyncio.run(all_req())

print(rel)

# 總共5個(gè)請(qǐng)求任務(wù)返回:

# 總耗時(shí)1秒多,相比同步的5秒+好N多。

"""

['sleep 1 second is done', 'sleep 1 second is done', 'sleep 1 second is done', 'sleep 1 second is done', 'sleep 1 second is done']

[Done] exited with code=0 in 1.955 seconds

"""

tell why??

測試發(fā)現(xiàn)Semaphore方法設(shè)置的請(qǐng)求并發(fā)數(shù)量跟本不起作用,nginx的access.log以及Proxifier看到的一次性請(qǐng)求量都不是代碼中設(shè)置的數(shù)量。

使用uvloop優(yōu)化異步操作

uvloop用于提升協(xié)程的速度。

uvloop使用很簡單,直接設(shè)置異步策略就好了。

import asyncio

import uvloop

#聲明使用 uvloop 事件循環(huán)

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

測試遇到很多報(bào)錯(cuò),基本上都是await和async使用的問題。

異步請(qǐng)求的分塊chunk并發(fā)控制

自行chunk操作

自己按照所有任務(wù)的list列表進(jìn)行chunk切割,然后分塊進(jìn)行請(qǐng)求,每塊中固定chunk數(shù)量的任務(wù)。基本可以實(shí)現(xiàn)想要的并發(fā)限制操作

async def _bulk_task(num,current_page = 1):

"""批量創(chuàng)建異步任務(wù)

"""

task = []

for i in range(num):# 每次10個(gè)連接并發(fā)進(jìn)行請(qǐng)求

task.append(asyncio.create_task(get(current_page)))

current_page += 1

return await asyncio.gather(*task)

# 主要進(jìn)行chunk操作的函數(shù)

def run_task(total,chunk,offset_start_page = 1):

"""運(yùn)行分塊處理的批量任務(wù)

Arguments:

total int 總請(qǐng)求數(shù)

chunk int 每次并發(fā)請(qǐng)求數(shù)

offset_start_page int 初始分塊開始的頁數(shù)(偏移頁數(shù)),正常默認(rèn)為1

Yields:

返回收集的異步任務(wù)運(yùn)行結(jié)果

"""

length = math.ceil(total/chunk)

for i in range(length):

start_page = i * chunk + offset_start_page # 當(dāng)前分塊開始的頁數(shù)

haldle_num = chunk# 當(dāng)前需要并發(fā)處理的數(shù)量

#處理結(jié)尾的塊

if i == length - 1:

# print(':::',chunk,start_page + chunk - offset_start_page)

haldle_num = min(chunk,total + offset_start_page - start_page)

# print('當(dāng)前分塊下標(biāo):{},當(dāng)前分塊需要處理的總數(shù):{},當(dāng)前分塊開始頁數(shù):{}'.format(i,haldle_num,start_page))

rel = asyncio.run(_bulk_task(haldle_num,start_page))

yield rel

rel = run_task(123,10)# 123總?cè)蝿?wù) 每10條并發(fā)請(qǐng)求

for i in rel:

print(i)

TODO

參考:

https://hubertroy.gitbooks.io/aiohttp-chinese-documentation/content/aiohttp%E6%96%87%E6%A1%A3/ClientUsage.html#%E6%84%89%E5%BF%AB%E5%9C%B0%E7%BB%93%E6%9D%9F

https://docs.Python.org/zh-cn/3/library/asyncio-eventloop.html#asyncio.get_running_loop

https://segmentfault.com/q/1010000008663962

http://www.ruanyifeng.com/blog/2019/11/python-asyncio.html

https://blog.csdn.net/qq_37144341/article/details/89471603

https://www.jianshu.com/p/8f65e50f39b4

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的python asyncio tcp转发_aiohttp + asyncio 异步网络请求基本操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。