首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优化这个Asyncio代码片段,以便在突发期间每秒发出更多请求?

问如何优化这个Asyncio代码片段,以便在突发期间每秒发出更多请求?
EN

Stack Overflow用户
提问于 2019-03-21 04:46:12
回答 1查看 607关注 0票数 3

这是我的小代码。它只是一个异步循环,向Twilio发送10个post请求:

代码语言:javascript
复制
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请求的方式上比线程更高效。

这就是我现在在异步中获得的优势:

代码语言:javascript
复制
>>> 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中运行这个脚本。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-21 07:32:39

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

代码语言:javascript
复制
connector = aiohttp.TCPConnector(limit=None)
async with aiohttp.ClientSession(connector=connector) as session:
    # ...

其原因解释了这里的更多细节。

还要注意的是,关于发出百万次请求的文章并不承诺“每秒”。

您可能会将它与文章混淆在服务器端使用日隆托处理请求,这是完全不同的(更不用说本文有自己的问题)。

Upd:

总是有与准备请求相关的开销。您可以尝试使用单个会话来腾出时间:

代码语言:javascript
复制
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())
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55273927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档