• asyncio与gevent并发性能测试


    asyncio与gevent并发性能测试

    在对网站进行扫描或者暴破时需要对网站进行高并发操作,然而requests+concurrent多线程性能上不太理想,了解到python用得比较多的并发库有asynciogevent,于是就有了如下测试。

    0x00 协程

    asynciogevent都是基于携程来进行并发操作的。协程也被称为微线程。
    协程只是在单一的线程里进行切换不同的协程,因此无法使用多CPU能力,对于CPU密集型程序还是使用多进程比较好。
    协程相比较进程和线程来说占用的内容更少,同样的线程切换更多的是靠操作系统来控制,而协程的执行则由我们自己控制。
    并发原理:当其中一个协程遇到io等待时,将会切换到另一个协程继续运行。

    0x01 grequests

    grequests是对requestsgevent库的封装
    测试代码:

    #!/usr/bin/python3.7
    import grequests
    import time
        
    if __name__ == '__main__':
        start = time.time()
        greenlets = []
        for _ in range(10):
            greenlets.append(grequests.get("http://150.xx.xx.xx"))
        rets = grequests.map(greenlets)
        for ret in rets:
            print(ret)
        end = time.time()
        print("grequests visit_async tasks %.2f seconds" % (end - start))
    

    grequests.map()参数说明:
    def grequests.map(requests, stream=False, size=None, exception_handler=None, gtimeout=None)

    参数说明备注
    size 协程的并发度(相当于线程数) 当一个协程在IO等待时,会将CPU交给其他协程
    exception_handler 异常处理函数 用于处理单个请求出现异常的函数
    gtimeout 设置所有请求的超时时间  

    grequests的底层是request,所以它也支持回调函数:

    def print_url(r, *args, **kwargs):
        print(r.url)
    res = grequests.get(url, callback=print_url)
    

    测试结果:

     
    grequsts并发性能测试

    0x02 asyncio + uvloop

    由于gevent的猴子补丁的缘故,requests可以和gevent结合使用,但是在不清楚内部实现的情况下,requests库经常比较容易出现Failed to establish a new connection:的情况,在使用grequests库之后该情况得到解决。
    uvloop是用Cython写的,目前不支持windows,它基于libuv.uvloop使得asyncio更快,基于性能的测试接近于go。
    可以通过两种方式来使用uvloop:

    import uvloop
    import asyncio
    
    #1. 通过设置策略
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) 
    #2. 直接创建一个新的event_loop
    asyncio.set_event_loop(uvloop.new_event_loop())
    

    由于asycnio采用异步操作,它在使用的过程中所有的模块也都得是异步的,所以在进行http请求时也需要异步,即aiohttp
    测试代码:

    #!/usr/bin/python3.7
    import asyncio
    import aiohttp
    import uvloop
    import time
    
    async def access_url(url):
        async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
            async with session.get(url) as response:
                status_code = response.status
                print(status_code)
    
    async def visit_async():
        start = time.time()
        tasks = []
        for _ in range(10):
            tasks.append(access_url("http://150.xx.xx.xx"))
        await asyncio.gather(*tasks)
        end = time.time()
        print("asyncio visit_async tasks %.2f seconds" % (end - start))
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        future = asyncio.ensure_future(visit_async())
        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
        loop.run_until_complete(future)
    

    测试结果:

     
    asyncio 并发性能测试

    0x03 优缺点

    asyncio由于是异步操作,且代码库生态不够完善,部分异步代码库存在问题可能查不到,且编写代码时行数较多,影响阅读,而且代库函数全部重构,上手有难度,但是并发执行的速度较快,对于暴破、端口扫描等比较适用。
    gevent采用了requests模块,在使用了猴子补丁后对于扫描网站路径等可以有效即时针对扫描结果进行深层扫描。

    请求内容:

     
    请求内容

    参考:


     
     
  • 相关阅读:
    Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test)
    maven打包报错:Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test
    关于log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).的问题
    maven-source 1.3 中不支持注释请使用 -source 5 或更高版本以启用注释
    <Android基础>(二) Activity Part 1
    <Android基础>(一)
    数制
    第二次实验报告:使用Packet Tracer分析应用层协议
    在Windows Server 2003中搭建DNS服务器
    第一次作业:使用Packet Tracer分析HTTP包
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/11957406.html
Copyright © 2020-2023  润新知