V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Suger828
V2EX  ›  程序员

Python 使用 fastapi 框架阻塞问题

  •  
  •   Suger828 · 2025 年 5 月 15 日 · 2561 次点击
    这是一个创建于 247 天前的主题,其中的信息可能已经有所发展或是发生改变。

    fastapi 部署的 web 后端,很多时候会阻塞,前端发请求他一点响应没有 ctrl+ c 一下就动了, gpt 说是同步的一些任务导致的阻塞,但是不可能一直阻塞无论多长时间都不释放吧

    23 条回复    2025-05-19 15:13:49 +08:00
    hmxxmh
        1
    hmxxmh  
       2025 年 5 月 15 日 via Android
    代码贴出来看看
    nagisaushio
        2
    nagisaushio  
       2025 年 5 月 15 日 via Android
    windows ?
    Suger828
        3
    Suger828  
    OP
       2025 年 5 月 15 日
    Suger828
        4
    Suger828  
    OP
       2025 年 5 月 15 日
    @hmxxmh 公司代码 不太方便
    Suger828
        5
    Suger828  
    OP
       2025 年 5 月 15 日
    网络连接或 Socket 问题详解
    在 Web 服务器中,特别是像 FastAPI/Uvicorn 这样的异步服务器,网络连接和 socket 配置可能会导致您遇到的症状。具体来说:
    1. Socket 状态管理问题
    当客户端连接到服务器时,会创建一个 socket 连接。这个连接在以下情况可能会出问题:

    半开连接(Half-open connections): 当客户端断开连接但服务器没有正确检测到这种情况时,socket 可能处于"半开"状态,占用资源但不再有效。
    TIME_WAIT 状态: 当连接关闭后,socket 可能会进入 TIME_WAIT 状态,在一段时间内仍然占用端口。

    在 Windows 上,这种 socket 状态管理问题可能更为严重,因为 Windows 的网络堆栈实现与 Unix 系统有所不同。
    2. 连接池耗尽
    您的服务器可能有一个连接池限制,当所有连接都被占用时,新的请求无法被处理:

    默认情况下,许多服务器有最大连接数限制
    如果连接没有正确关闭,可能会导致连接池逐渐耗尽

    3. SO_REUSEADDR 设置问题
    在 Windows 上,socket 选项 SO_REUSEADDR 的行为与 Unix 系统不同:

    在 Unix 系统上,它允许绑定到处于 TIME_WAIT 状态的地址
    在 Windows 上,它的行为更宽松,允许多个进程绑定到同一地址,可能导致意外行为

    4. Windows 特有的阻塞行为
    Windows 上的网络 API 在某些情况下可能会表现出异步不友好的阻塞行为:

    某些网络操作可能会阻塞事件循环,尽管它们声明是非阻塞的
    Windows 的 WSA(Windows Socket API)与标准 BSD sockets 有细微但重要的差异

    为什么 Ctrl+C 会"修复"这个问题?
    当您按下 Ctrl+C 时,以下事情会发生:

    强制关闭活动连接: 所有活动的 socket 连接会被强制关闭
    释放端口绑定: 服务器会释放之前绑定的端口
    清理半开连接: 半开连接和处于异常状态的 socket 会被清理
    重置内部状态: 服务器内部状态会被部分重置,但由于您的服务器没有完全退出,一些组件会继续运行
    事件循环重新调度: 事件循环通常会响应中断信号,重新调度任务

    这些操作相当于"重置"了服务器的网络状态,允许它重新开始接受新连接。



    上面是 ai 回答的不确定对不对
    72
        6
    72  
       2025 年 5 月 15 日
    多开几个 works 就好了
    dcsuibian
        7
    dcsuibian  
       2025 年 5 月 15 日 via Android
    不会是 windows 命令行的编辑模式吧
    thevita
        8
    thevita  
       2025 年 5 月 15 日
    火焰图照一下,缩小范围,看看有不有没注意到的同步调用.
    neoblackcap
        9
    neoblackcap  
       2025 年 5 月 15 日
    是不是有接口是长连接的?然后直接在业务处理的地方进行了 busy loop 的处理?
    Suger828
        10
    Suger828  
    OP
       2025 年 5 月 16 日 via Android
    @neoblackcap 有可能
    Suger828
        11
    Suger828  
    OP
       2025 年 5 月 16 日 via Android
    @dcsuibian win 命令行哪有编辑模式
    darksword21
        12
    darksword21  
    PRO
       2025 年 5 月 16 日 via iPhone
    没加 async worker 只开了一个?
    luckyc
        13
    luckyc  
       2025 年 5 月 16 日
    worker 几个撒?
    Suger828
        14
    Suger828  
    OP
       2025 年 5 月 16 日
    darksword21
        15
    darksword21  
    PRO
       2025 年 5 月 16 日 via iPhone
    @Suger828 那肯定阻啊….
    Suger828
        16
    Suger828  
    OP
       2025 年 5 月 16 日
    @darksword21 async 有的 但是 worker 开了一个
    yh7gdiaYW
        17
    yh7gdiaYW  
       2025 年 5 月 16 日
    @Suger828 你用的库不都是支持异步的吧,有一个地方是同步的卡死,整个应用就全卡死了
    fulln
        18
    fulln  
       2025 年 5 月 16 日
    是不是入口没写 async..
    Suger828
        19
    Suger828  
    OP
       2025 年 5 月 16 日
    @fulln 写了
    Suger828
        20
    Suger828  
    OP
       2025 年 5 月 16 日
    @yh7gdiaYW 基本上都是异步,非异步的一些也不是耗时的任务
    llsquaer
        21
    llsquaer  
       2025 年 5 月 16 日
    首先你得想想有没有啥同步耗时的代码卡在哪里了。里面有咩有写 time() 先关的东西。。异步里面是不是搞了线程?还带个 Lock 。 其次才是底层链接问题。
    chaunceywe
        22
    chaunceywe  
       2025 年 5 月 16 日
    检查下有没有在异步接口内定义什么同步且耗时的操作
    yh7gdiaYW
        23
    yh7gdiaYW  
       2025 年 5 月 19 日
    @Suger828 python 常用的 requests 、数据库驱动等三方库都是同步的,标上 async 也不会自动变成异步。有一个协程在调这些库,这个 worker 里所有的协程都要等
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2646 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:20 · PVG 19:20 · LAX 03:20 · JFK 06:20
    ♥ Do have faith in what you're doing.