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
edis0n0
V2EX  ›  Python

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

  •  
  •   edis0n0 · 2023-03-13 21:17:22 +08:00 · 1312 次点击
    这是一个创建于 401 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在有一个外包写的程序,主要逻辑在其它语言写的 exe 中,aiohttp server 收到 API 请求就调用一个 exe ,把 exe 输出到控制台的内容加工一下再返回。目前的问题是前一个请求处理完之前根本无法接受下一个请求,这个 api 经常一千并发,假设 exe 执行一次 1 秒,api 全返回就要 1000 秒,接受不了,外包已经联系不到了,想改成非阻塞的请问怎么处理?不怎么会写 python ,但这个加工逻辑用其它语言重构也很麻烦

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

    asyncio 子进程

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

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

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

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

    这是 http 协议的问题不是 python 的问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5470 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 05:57 · PVG 13:57 · LAX 22:57 · JFK 01:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.