推荐学习书目
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
edis0n0
V2EX  ›  Python

aiohttp 糊的服务端如何快速实现防阻塞?

  •  
  •   edis0n0 · Mar 13, 2023 · 2633 views
    This topic created in 1163 days ago, the information mentioned may be changed or developed.
    现在有一个外包写的程序,主要逻辑在其它语言写的 exe 中,aiohttp server 收到 API 请求就调用一个 exe ,把 exe 输出到控制台的内容加工一下再返回。目前的问题是前一个请求处理完之前根本无法接受下一个请求,这个 api 经常一千并发,假设 exe 执行一次 1 秒,api 全返回就要 1000 秒,接受不了,外包已经联系不到了,想改成非阻塞的请问怎么处理?不怎么会写 python ,但这个加工逻辑用其它语言重构也很麻烦

    **(不要提 chatgpt 重构,试过效果非常差)**
    13 replies    2023-03-21 11:27:33 +08:00
    Yanickkk
        1
    Yanickkk  
       Mar 13, 2023
    多开几个呗,前面 nginx 负载下,这个主要卡点是 exe 呀,不管怎么样处理需要 1 秒,没办法解决
    edis0n0
        2
    edis0n0  
    OP
       Mar 13, 2023
    @yannxia #1 exe 的资源占用非常小,同时开几千个都没问题。
    learningman
        3
    learningman  
       Mar 13, 2023
    就是不阻塞主 thread 呗,开个单独的 process 当 daemon 处理,async 通信。
    图方便就每个请求进来都开,就是压力交给操作系统的调度了。
    des
        4
    des  
       Mar 13, 2023 via iPhone
    开线程池吧,主要还是看你这 exe 占不占系统资源
    zhuangzhuang1988
        5
    zhuangzhuang1988  
       Mar 13, 2023
    https://docs.python.org/3/library/asyncio-subprocess.html



    proc = await asyncio.create_subprocess_shell(
    cmd,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE)
    ClericPy
        6
    ClericPy  
       Mar 13, 2023
    https://docs.python.org/zh-cn/3/library/asyncio-subprocess.html

    asyncio 子进程

    对协程不熟悉的话真不建议用协程, 不然会经历很多痛苦的地方: CPU 密集阻塞事件循环, 同步代码阻塞异步任务, 多线程开太多切换成本太大.....等等
    edis0n0
        7
    edis0n0  
    OP
       Mar 13, 2023
    @zhuangzhuang1988 #5
    @ClericPy #6 发现加工返回数据的 python 逻辑也很慢(好几个 http 请求,都用的 requests ,没有统一包装,改起来很麻烦,但资源消耗不高),有办法把这部分逻辑也放到主线程外吗?
    westoy
        8
    westoy  
       Mar 13, 2023
    开一个队列进程去执行那个 exe

    直接给原来的 popen 打猴子补丁, 劫持成扔队列
    ClericPy
        9
    ClericPy  
       Mar 13, 2023
    @edis0n0 可以, run_in_executor 吧
    wangyongbo
        10
    wangyongbo  
       Mar 13, 2023
    如果你不会 python ,那你不如再找一个新的外包帮你改吧。
    lysoul
        12
    lysoul  
       Mar 14, 2023
    python 的协程要求所有调用的方法都支持协程,否则该阻塞还是阻塞,还是开多线程吧
    lolizeppelin
        13
    lolizeppelin  
       Mar 21, 2023
    你这个需求从一开头就错了...根本就不是 python 的问题
    http 本身就是一来一回的,http 请求都必须等待数据返回协议才结束.
    无论你用协程还是线程执行 exe.都要等待结果才能返回,http 协议才能结束,连接才能结束.

    想要异步 http 1.x 协议下只能这样做
    创建一个 http 请求,服务端把请求的具体执行插入队列,然后立刻返回一个唯一识标,然后返回
    客户端通过唯一识标反复重试去拿结果.

    否则得用 websocket,这样改动更大

    这是 http 协议的问题不是 python 的问题
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3956 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 00:56 · PVG 08:56 · LAX 17:56 · JFK 20:56
    ♥ Do have faith in what you're doing.