我如何优化此Asyncio代码片段以在突发期间每秒发出更多请求?

所以这是我的一小段代码.这只是一个异步循环,向Twilio发送10个发布请求:

import time
import aiohttp
import asyncio


async def asynchronous():
    tasks = [f('NumberFrom','NumberTo','asyncio imo'),f('NumberFrom','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个帖子请求.

这是我现在使用asyncio的表现:

>>> 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个请求.我没想到,我只是想我可以从异步中获得更多数量级的性能.

我的代码中是否存在明显的错误,该错误会降低asyncio或其他工具的效率?还是这仅仅是asyncio可以做到的高峰?我对Python并不陌生,但是对asyncio却并不陌生,所以我不知道我在这里做什么.请说明任何明显的内容.

作为参考,我正在运行4核3.2GHz intel i7处理器,该脚本是当时唯一运行的脚本.我知道我的CPU不是瓶颈.

运行此程序时,我的互联网峰值速度约为250Kbps,但这远不及我的ISP上限3.5Mbps.我知道我的互联网不是瓶颈.

我正在IDLE shell中的Python 3.7.2中运行此脚本.

最佳答案
您应该将自定义连接器传递给会话:

connector = aiohttp.TCPConnector(limit=None)
async with aiohttp.ClientSession(connector=connector) as session:
    # ...

这样做的原因解释了here的更多细节.

还要注意,关于发出百万个请求的article并不能保证“每秒”.

您可能会将它与article混淆,以使用Japronto在服务器端处理请求,这是完全不同的(更不用说本文有其自己的issues).

更新:

总是有与准备请求相关的开销.您可以尝试使用单个会话来节省一些时间:

import time
import aiohttp
import asyncio


async def asynchronous():
    async with aiohttp.ClientSession() as session:
        tasks = [f('NumberFrom','asyncio imo',session),session)]
        await asyncio.gather(*tasks)


async def f(NumberFrom,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())

相关文章

Python中的函数(二) 在上一篇文章中提到了Python中函数的定...
Python中的字符串 可能大多数人在学习C语言的时候,最先接触...
Python 面向对象编程(一) 虽然Python是解释性语言,但是它...
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定...
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非...
在windows下如何快速搭建web.py开发框架 用Python进行web开发...