V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
anxiousPumpkin
V2EX  ›  Python

前端摸索后端小白,请教各位一个服务端的问题,关于 Python sanic 用法

  •  
  •   anxiousPumpkin · 2022-03-15 22:49:02 +08:00 · 2224 次点击
    这是一个创建于 969 天前的主题,其中的信息可能已经有所发展或是发生改变。
    import asyncio
    
    from sanic import Sanic
    from sanic.response import json
    
    app = Sanic(__name__)
    
    
    @app.route("/")
    async def test(request):
        print('func invoke!')
        await asyncio.sleep(3)
        return json({"hello": "world"})
    
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8000, workers=2)
    

    我想请教下关于 sanic 处理接口并发请求。 比如上述我的test接口函数,该方法处理逻辑直到返回需要 3s ,此时同时有 5 次请求进入。

    我期望的结果是同时输出 5 次func invoke!,然后依次返回 response 。 但是目前情况是队列效果,进入函数输出func invoke!,3s 后返回 response ,紧接着输出下一个func invoke!

    觉得是服务端很基础的问题,但是实在是没有在 google 中找到想要的答案...请各位大佬赐教

    6 条回复    2022-03-15 23:28:58 +08:00
    lucays
        1
    lucays  
       2022-03-15 23:03:08 +08:00   ❤️ 1
    你需要并发请求接口,而不是 for 循环请求。

    例如:

    from concurrent.futures import ThreadPoolExecutor, as_completed

    import requests


    def request(url):
    r = requests.get(url)
    print(r.text)


    url = 'http://127.0.0.1:8000'
    with ThreadPoolExecutor(8) as e:
    tasks = [e.submit(request, url) for i in range(8)]
    for task in as_completed(tasks):
    task.result()
    lucays
        2
    lucays  
       2022-03-15 23:05:25 +08:00   ❤️ 1
    额,v2 回复后缩进没了,你自己处理下上面代码的缩进吧
    raycool
        3
    raycool  
       2022-03-15 23:10:05 +08:00   ❤️ 1
    from sanic.response import json

    app = Sanic(__name__)

    async def task():
    print('func invoke!')


    @app.route("/")
    async def test(request):
    loop = request.app.loop
    loop.create_task(task())
    await asyncio.sleep(5)
    return json({'hello': 'world'})

    if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, workers=2)
    ClericPy
        4
    ClericPy  
       2022-03-15 23:12:23 +08:00   ❤️ 1
    客户端代码呢...
    anxiousPumpkin
        5
    anxiousPumpkin  
    OP
       2022-03-15 23:28:01 +08:00
    @lucays 我明白了,刚才自测是用浏览器多 tab 模拟多请求,所以导致了串行,postman 、curl 包括你这个代码是可行的。十分感谢
    anxiousPumpkin
        6
    anxiousPumpkin  
    OP
       2022-03-15 23:28:58 +08:00
    @ClericPy @raycool 感谢回复,明白问题了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 01:30 · PVG 09:30 · LAX 17:30 · JFK 20:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.