这是我的小代码。它只是一个异步循环,向Twilio发送10个post请求:
import time
import aiohttp
import asyncio
async def asynchronous():
tasks = [f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo'),
f('NumberFrom', 'NumberTo', 'asyncio imo')]
await asyncio.gather(*tasks)
async def f(NumberFrom, NumberTo, MessageBody):
try:
print('Sent at %s' % time.time())
async with aiohttp.ClientSession() as session:
await session.post('https://api.twilio.com/2010-04-01/Accounts/AuthPass/Messages.json',
data={'From': NumberFrom, 'To': NumberTo, 'Body': MessageBody},
auth=aiohttp.BasicAuth(login='AuthUser', password='AuthPass'))
print('Done at at %s' % time.time())
except Exception as err:
print('Error encountered at %s' % time.time())
asyncio.run(asynchronous())在有人问我之前,我有一个与Twilio的付费帐户,不要免费阅读或垃圾邮件。我不是想用短信轰炸任何人。我只需要偶尔发送一批消息,而每条消息都需要或多或少地同时发送到不同的号码。
目前,我正在使用线程模块进行此操作。我为每条消息启动一个单独的线程。对于一些数字来说,这很好,但是当您需要打开几个线程时,效率就会变得很低。每次我都必须打开20个线程,并且在异步发送20个post请求的方式上比线程更高效。
这就是我现在在异步中获得的优势:
>>> asyncio.run(asynchronous())
0.0
Sent at 1553142004.4640338
Sent at 1553142004.5059218
Sent at 1553142004.5119061
Sent at 1553142004.5178897
Sent at 1553142004.5238738
Sent at 1553142004.5288606
Sent at 1553142004.5348446
Sent at 1553142004.5388453
Sent at 1553142004.5448182
Sent at 1553142004.5488071
Done at 1553142004.9834092
Done at 1553142004.9913745
Done at 1553142005.0013483
Done at 1553142005.0153105
Done at 1553142005.0264556
Done at 1553142005.0342588
Done at 1553142005.0472543
Done at 1553142005.0581958
Done at 1553142005.066205
Done at 1553142005.0731542
>>> 我平均每秒钟发送100个请求。出于某种原因,我认为异步比这个更快。我读过Python的文章,它每秒能够达到1,000,000次请求。我没有料到这一点,我只是觉得我能从异步中获得更大的性能。
我的代码中是否有明显的错误正在降低异步或其他方面的效率?还是这仅仅是异步的峰值呢?我对Python并不陌生,但我对异步操作并不熟悉,所以我不知道我在这里做什么。请解释任何明显的事情。
作为参考,我正在运行一个4 Core3.2GHz英特尔i7处理器,这个脚本是当时唯一运行的。我知道我的CPU不是瓶颈。
我的互联网在运行时会猛增到250 this,但这与我的3.5Mbps的ISP上限相去甚远。我知道我的互联网不是瓶颈。
我使用Python3.7.2在空闲shell中运行这个脚本。
发布于 2019-03-21 07:32:39
您应该将自定义连接器传递给会话:
connector = aiohttp.TCPConnector(limit=None)
async with aiohttp.ClientSession(connector=connector) as session:
# ...其原因解释了这里的更多细节。
还要注意的是,关于发出百万次请求的文章并不承诺“每秒”。
您可能会将它与文章混淆在服务器端使用日隆托处理请求,这是完全不同的(更不用说本文有自己的问题)。
Upd:
总是有与准备请求相关的开销。您可以尝试使用单个会话来腾出时间:
import time
import aiohttp
import asyncio
async def asynchronous():
async with aiohttp.ClientSession() as session:
tasks = [f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session),
f('NumberFrom', 'NumberTo', 'asyncio imo', session)]
await asyncio.gather(*tasks)
async def f(NumberFrom, NumberTo, MessageBody, session):
try:
print('Sent at %s' % time.time())
await session.get('http://httpbin.org/delay/1')
print('Done at at %s' % time.time())
except Exception as err:
print('Error encountered at %s' % time.time())
asyncio.run(asynchronous())https://stackoverflow.com/questions/55273927
复制相似问题