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 · 89 天前 · 915 次点击
    这是一个创建于 89 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在有一个外包写的程序,主要逻辑在其它语言写的 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  
       89 天前
    多开几个呗,前面 nginx 负载下,这个主要卡点是 exe 呀,不管怎么样处理需要 1 秒,没办法解决
    edis0n0
        2
    edis0n0  
    OP
       89 天前
    @yannxia #1 exe 的资源占用非常小,同时开几千个都没问题。
    learningman
        3
    learningman  
       89 天前
    就是不阻塞主 thread 呗,开个单独的 process 当 daemon 处理,async 通信。
    图方便就每个请求进来都开,就是压力交给操作系统的调度了。
    des
        4
    des  
       88 天前 via iPhone
    开线程池吧,主要还是看你这 exe 占不占系统资源
    zhuangzhuang1988
        5
    zhuangzhuang1988  
       88 天前
    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  
       88 天前
    https://docs.python.org/zh-cn/3/library/asyncio-subprocess.html

    asyncio 子进程

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

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

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

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

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