Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何优化这段异步代码,以便在突发时间内每秒发出更多请求?_Python_Python 3.x_Performance_Python Asyncio_Aiohttp - Fatal编程技术网

Python 如何优化这段异步代码,以便在突发时间内每秒发出更多请求?

Python 如何优化这段异步代码,以便在突发时间内每秒发出更多请求?,python,python-3.x,performance,python-asyncio,aiohttp,Python,Python 3.x,Performance,Python Asyncio,Aiohttp,这是我的一小段代码。它只是一个asyncio循环,向Twilio发送10个post请求: import time import aiohttp import asyncio async def asynchronous(): tasks = [f('NumberFrom', 'NumberTo', 'asyncio imo'), f('NumberFrom', 'NumberTo', 'asyncio imo'), f('Numbe

这是我的一小段代码。它只是一个asyncio循环,向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所获得的性能:

>>> 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次发帖请求。出于某种原因,我认为asyncio会比这更快。我读过Python每秒能够处理1000000个请求的文章。我没想到会这样,我只是觉得我可以从asyncio中获得更高数量级的性能

我的代码中是否存在明显的错误,降低了异步IO或其他方面的效率?或者这只是asyncio所能达到的峰值?我不是Python新手,但我是asyncio新手,所以我不知道我在这里做什么。请解释任何明显的事情

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

我的网速在运行这个程序时会达到250Kbps,但这与我的ISP上限3.5Mbps相差甚远。我知道我的互联网不是瓶颈


我正在空闲shell中用Python 3.7.2运行此脚本。

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

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())

我的脚本只发出5个post请求。您链接的页面讨论了默认情况下aiohttp仅允许100个同时连接。“我不认为这是我的瓶颈,我一次只能建立10个连接。”阿比布什卡我重新阅读了你的问题。现在你发送了10个请求,所有请求都在1秒后完成,对吗?你还期望得到什么结果?我正在发送10个请求,它们都在0.10秒内发送。响应在一秒钟内返回。我想我只是在寻找更多的吞吐量。我认为asyncio可以每秒发送几千个请求。@ArbiBushka asyncio可以并行启动多个请求。然而,每个启动的请求都需要时间通过网络线传输到服务器,然后返回到客户端。即使是服务器和客户端之间的光纤线路,也至少需要一定的线路长度*光速(+一些Python开销)。无论如何你都无法避免。我知道网络请求需要时间。我想我可以每秒发送更多的请求。我问的是我的请求吞吐量,而不是每个请求的速度。