python 异步库aiohttp报错

python 异步库aiohttp报错


# ! -*- encoding:utf-8 -*-

from flask import Flask
import aiohttp  # 导入异步 HTTP 请求库 aiohttp
import asyncio  # 导入异步编程库 asyncio
import time
app = Flask(__name__)

async def main():
    # 此处为要运行的程序
    # 因泄露隐私, 故用打印 hello world 代替运行程序
    print("hello world")


@app.route("/")  # 匹配请求的位置
def hello():
    return asyncio.run(main())

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5005, debug=True)


请求一次时不会发生以下错误,但是在前一次的请求还未完成之前,再次请求,就会报错
RuntimeError: asyncio.run() cannot be called from a running event loop

img

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7786714
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:Python异步之aiohttp
  • 除此之外, 这篇博客: python异步--aiohttp中的 注意点 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 等待异步response时,记得使用await,response.read()是一个异步操作,这意味着它不会立即返回结果,仅仅返回生成器。这些生成器需要被调用跟运行,但是这并不是默认行为,Python3.4中加入的yield from以及Python3.5中加入的await便是为此而生。它们将迭代这些生成器
    • 极限并发问题
      • 10K连接数问题:因为连接数太大而导致的异常。一种解决办法就是把限制的连接数量提高,但是不太明智。另一种好的办法是加入一些同步机制,可以在asyncio.Samaphore()加入最大任务限制为1000(不要超过1024)

     会出现连接数过大的异常:

    
    import requests
    r = 10000
    url = "http://localhost:8080/{}"
    
    
    for i in range(r):
        res = requests.get(url.format(i))
        delay = res.headers.get("DELAY")
        d = res.headers.get("DATE")
        print("{}:{} delay {}".format(d, res.url, delay))
    

    设置最大连接的数的代码:

    import random
    import asyncio
    from aiohttp import ClientSession
    
     
    
    async def fetch(url):
          async with ClientSession() as session:
          async with session.get(url) as response:
          delay = response.headers.get("DELAY")
          date = response.headers.get("DATE")
          print("{}:{} with delay {}".format(date, response.url, delay))
          return await response.read()
     
    
    async def bound_fetch(sem, url):
        # getter function with semaphore
        async with sem:
            await fetch(url)
    
     
    async def run(loop,  r):
        url = "http://localhost:8080/{}"
        tasks = []
        # create instance of Semaphore
        sem = asyncio.Semaphore(1000)
    
        for i in range(r):
            # pass Semaphore to every GET request
            task = asyncio.ensure_future(bound_fetch(sem, url.format(i)))
            tasks.append(task)
            responses = asyncio.gather(*tasks)
            await responses
     
    
    number = 10000
    loop = asyncio.get_event_loop()
    future = asyncio.ensure_future(run(loop, number))
    loop.run_until_complete(future)