Python http异步与连接池

引用页

概念

假如你有手上有4个任务需要分配给甲、乙、丙、丁去完成,你有两种方式,第一种:将第一个任务分配给甲后等他处理完之后告诉你处理后的结果,此时再将第二个任务分配给乙,以此类推下去,如果甲做事的结果对你交代给乙的任务有关联,就必须选择这种方式;
但是如果甲乙丙丁的任务没有任何关联,那么你可以考虑以一种更加快捷的方式来分发任务,你可能会想到,直接将4个任务逐个分发出去,谁处理完后你就先阅读谁的结果,这样的效率是不是提升了好几倍呢?

  • 将如上方式与多线程区分开,因为在分配任务的时候是你独自完成的,所以我们把这种概念称之为,非阻塞IO(协程)

  • http连接池:对于相同socket(协议://ip:端口)会使用已有连接进行请求,以充分利用现有的资源,减少请求时间

阻塞IO示例

  • 普通阻塞IO请求,请求消耗的时间最长,并且每个请求都使用新的socket,耗时约1.2秒

在这里插入图片描述

import requests

res = requests.get("http://www.docrepository.org/")
res1 = requests.get("http://www.docrepository.org/books/faceVerif")
res2 = requests.get("http://hunandalong.com/contact.html")

连接池示例

  • 如下同一个域名下的不同页面就共用了同一个socket,第一个和第二个都使用了61959的本机端口

在这里插入图片描述

http = urllib3.PoolManager(retries=2, timeout=10, num_pools=200, maxsize=200)

res = http.request("GET", "http://www.docrepository.org/")
print('请求1号域名:' + str(len(http.pools)))
res1 = http.request("GET", "http://www.docrepository.org/books/faceVerif")
print('请求另一个1号域名:' + str(len(http.pools)))
res2 = http.request("GET", "http://hunandalong.com/contact.html")
print('请求2号域名:' + str(len(http.pools)))

非阻塞IO与线程池并用

  • 使用aiohttp的Session(),该对象内置了线程池,如下61303-61307被重复使用了
  • 因为请求了两次,如果只看第一次的三个请求,你会发现3.40557-3.789853(第67个包)结束,总共耗时:0.384秒

在这里插入图片描述

import aiohttp


async def send(client, url):
    async with client.get(url) as resp:
        result = await resp.text()

async def send_message():
    async with aiohttp.ClientSession() as client:
        url_list = [
            'http://www.docrepository.org/',
            'http://www.docrepository.org/books/faceVerif',
            'http://www.docrepository.org/books/mybatis-plus',
            'http://www.docrepository.org/books/vue-markdown',
            "http://hunandalong.com/"
        ]
        tasks = list()
        for url in url_list:
            tasks.append(asyncio.create_task(send(client, url)))
        await asyncio.wait(tasks)
        # 此处重复一次该请求,这样就会利用到本机的socket,因为内置http连接的为keepalive,并且超时为15秒,在15秒内都是可以复用连接
        taskss = list()
        for url in url_list:
            taskss.append(asyncio.create_task(send(client, url)))
        await asyncio.wait(taskss)

asyncio.run(send_message())

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值