【Bug已解决】[Bug]: API Connection Error after concurrent API calls 解决方案
【Bug已解决】[Bug]: API Connection Error after concurrent API calls 解决方案一、现象长什么样用客户端高并发打 vLLM 的 OpenAI 兼容 API/v1/chat/completions或/v1/completions时并发量一上去就出现连接错误requests.exceptions.ConnectionError: (Connection aborted., BrokenPipeError(...))或aiohttp.client_exceptions.ClientOSError: [Errno 24] Too many open files或客户端侧httpx.ConnectError: [Errno 60] Operation timed out几个典型表征只在并发高时出现串行/低并发正常说明问题在连接数 / 文件描述符 / 端口复用这类资源上限而非单次请求逻辑。错误是连接层ConnectionError / BrokenPipe / Too many open files不是业务层服务端可能在高并发下用完了文件描述符fd、或没用 keep-alive 导致 TIME_WAIT 堆积、或事件循环被连接建立压垮。服务端可能伴随OSError: [Errno 24] Too many open files这是典型 fd 耗尽每个 TCP 连接占一个 fd并发数 × 每请求连接数超过系统ulimit -n。这不是模型问题而是API server 的连接/资源处理能力在高并发下被耗尽。下面给出定位与修复客户端连接池 服务端 fd/keep-alive 调优。二、背景HTTP 服务在高并发下的连接资源每个 TCP 连接占用一个文件描述符fd。Linux 默认ulimit -n可能是 1024vLLM 的 uvicorn/fastapi 进程若并发接几千连接fd 直接耗尽 →Too many open files→ 新连接被拒 / BrokenPipe。短连接无 keep-alive会留大量 TIME_WAIT每个请求建连断连端口/连接表堆积导致Cannot assign requested address或连接超时。客户端没用连接池每次请求新建requests.Session/ 新httpx.Client连接不复用fd 暴涨。vLLM 默认用 uvicorn 起服务并发连接上限受 fd 和系统 backlog 影响。修复分两端服务端调大ulimit -n、开 keep-alive、限制并发或靠队列排队而非无限制接连接客户端用连接池requests.Session/httpx.AsyncClient复用 限并发 指数退避重试。下面用可运行代码实现客户端连接池 服务端 fd 检测。三、根因拆成三条根因fd 耗尽服务端并发连接数超过进程 fd 上限默认 1024新连接accept失败 →Too many open files/ BrokenPipe。根因是服务端 fd 上限过低 短连接不回收。客户端不复用连接客户端每次请求新建连接没用 Session/Client连接数 请求数fd 在服务端和客户端同时暴涨。根因是缺少连接池 keep-alive 复用。无并发限制 / 重试风暴客户端无脑并发 失败后立刻重试连接数在重试中指数放大把服务端压垮。根因是缺少并发上限 退避重试。修复方向服务端调大 fd 开 keep-alive客户端用连接池复用 Semaphore限并发 指数退避重试。四、最小可运行复现下面复现客户端无连接池导致连接数暴涨的判定逻辑import threading class NaiveClient: 现状每次请求都建新连接连接不复用。 def __init__(self): self.open_connections 0 self._lock threading.Lock() def request(self): with self._lock: self.open_connections 1 # 每次新建 # ... 真实请求 ... with self._lock: self.open_connections - 1 def simulate_concurrent(client, n): threads [] def job(): # 串行化统计峰值朴素客户端峰值 ≈ 并发数 client.request() for _ in range(n): t threading.Thread(targetjob); t.start(); threads.append(t) for t in threads: t.join() c NaiveClient() # 若 n2000且服务端 fd 上限 1024峰值连接会撑爆 print(朴素客户端并发 2000 时服务端需承受约 2000 并发连接易超 fd 上限)真实场景里这 2000 并发连接会直接把服务端 fd 吃满。下面用连接池 限并发修复。五、解决方案第一层最小直接修复最小修复客户端用连接池复用 TCP 连接Semaphore限制并发 指数退避重试。import asyncio import httpx class PooledClient: 带连接池 并发限制 退避重试的客户端。 def __init__(self, base_url, max_concurrency64, max_connections64): self._sem asyncio.Semaphore(max_concurrency) # httpx.AsyncClient 内部维护连接池keep-alive 复用 self._client httpx.AsyncClient(base_urlbase_url, limitshttpx.Limits( max_connectionsmax_connections, max_keepalive_connectionsmax_connections), timeouthttpx.Timeout(60.0)) async def chat(self, payload, retries3): for attempt in range(retries): async with self._sem: # 限制并发 try: r await self._client.post(/v1/chat/completions, jsonpayload) r.raise_for_status() return r.json() except (httpx.ConnectError, httpx.TransportError) as e: if attempt retries - 1: raise # 指数退避避免重试风暴 await asyncio.sleep(0.5 * (2 ** attempt)) async def run_pooled(base_url, n): client PooledClient(base_url, max_concurrency64) tasks [client.chat({model: x, messages: []}) for _ in range(n)] # 并发被信号量限到 64连接池复用fd 稳定 return await asyncio.gather(*tasks, return_exceptionsTrue) # 用法 # asyncio.run(run_pooled(http://localhost:8000, 2000))这一层改动让客户端并发被限制、连接被复用服务端承受的并发连接数稳定在max_connections64而非 2000fd 不再耗尽。六、解决方案第二层结构化改进把服务端 fd / keep-alive 调优也做成结构化检测与配置两端配合客户端限并发 服务端提 fd 开 keep-alive。import resource import os def server_fd_guard(min_fd8192): 服务端启动期检测并尽量提高 fd 上限。 soft, hard resource.getrlimit(resource.RLIMIT_NOFILE) if soft min_fd: new_soft min(min_fd, hard) try: resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, hard)) except ValueError: print(f[warn] 无法提高到 {min_fd}当前软限 {soft}硬限 {hard}) cur_soft, _ resource.getrlimit(resource.RLIMIT_NOFILE) return cur_soft def report_uvicorn_tuning(): 给出 uvicorn 启动建议keep-alive 合理的 backlog。 return { keep_alive: 30, # 开 keep-alive复用连接 backlog: 2048, # 接受队列长度 # uvicorn 启动--limit-concurrency 按 GPU 数限制避免无限制接连接 limit_concurrency: 256, } # 用法服务端 main 入口最早调用 fd server_fd_guard(8192) print(服务端可用 fd 软限:, fd) print(uvicorn 建议:, report_uvicorn_tuning())server_fd_guard在服务端启动早期提高 fd 上限受系统硬限约束report_uvicorn_tuning给出 keep-alive 并发限制建议两端配合消掉高并发连接错误。七、解决方案第三层断言 / CI 守护并发连接错误最怕线上高并发才暴露。用断言守两条不变量def check_concurrency_invariants(base_url, n, max_conn): # 不变量 1客户端并发被信号量限制实际并发连接 max_conn # 用 httpx.Limits 保证连接池上限 client httpx.AsyncClient(base_urlbase_url, limitshttpx.Limits(max_connectionsmax_conn)) assert client._limits.max_connections max_conn # 不变量 2服务端 fd 软限必须 预期并发连接 soft, _ resource.getrlimit(resource.RLIMIT_NOFILE) assert soft max_conn, ffd 软限 {soft} 应 并发 {max_conn} return True def test_concurrency_safe(): import resource check_concurrency_invariants(http://x, 2000, max_conn64) print(OK: 并发连接不变量通过) if __name__ __main__: test_concurrency_safe()把test_concurrency_safe接进 CI用本地 mock server 或只做配置校验锁死客户端限并发 / 服务端 fd 足够。八、排查清单高并发打 vLLM API 报 Connection Error按序查看错误类型Too many open files→ fd 耗尽BrokenPipe→ 服务端在请求中途断了连接常因 fd 满后 accept 失败ConnectError/Timeout→ 连接建立被压垮或端口耗尽。客户端必须用连接池用requests.Session/httpx.AsyncClient内部 keep-alive千万不要每次请求新建 client。连接复用能把 fd 数降一个数量级。限制客户端并发用Semaphoreasyncio或线程池把并发控制在服务端能承受的范围如 64~256别无脑并发 2000。退避重试防风暴连接错误重试要用指数退避且限制重试次数避免失败→立刻重试→连接数翻倍的雪崩。服务端提 fd 上限ulimit -n 8192或写在启动脚本 / systemd 里server_fd_guard在启动期尽量提高软限。服务端开 keep-alive 限并发uvicorn 设--timeout-keep-alive 30复用连接必要时--limit-concurrency按 GPU 数限制避免无限制接连接把 fd 吃满。CI 接test_concurrency_safe校验客户端限并发 / 服务端 fd 足够高并发场景前先过这道闸。九、小结高并发打 vLLM API 报 Connection Error 的根因是连接资源fd / 连接数在高并发下被耗尽服务端 fd 上限过低 客户端不复用连接 无并发限制/重试风暴。三层修复第一层PooledClient用 httpx 连接池复用 TCP 连接 Semaphore限并发 指数退避重试把服务端承受的并发连接数稳定在池上限而非请求数第二层server_fd_guard服务端启动期提高 fd 软限report_uvicorn_tuning给出 keep-alive 并发限制建议两端配合第三层CI 断言守住客户端限并发 / 服务端 fd 足够高并发前先过闸。落实后vLLM API 在高并发下连接被复用、并发被限制、fd 足够不再因Too many open files/BrokenPipe拒绝连接。

相关新闻

sdm性能优化指南:提升Raspberry Pi镜像烧录速度的5个实用技巧

sdm性能优化指南:提升Raspberry Pi镜像烧录速度的5个实用技巧

sdm性能优化指南:提升Raspberry Pi镜像烧录速度的5个实用技巧 【免费下载链接】sdm Raspberry Pi SD Card Image Manager 项目地址: https://gitcode.com/gh_mirrors/sdm1/sdm sdm作为高效的Raspberry Pi SD卡镜像管理器,其烧录速度直接影响开发效…

2026/10/20 20:59:55 阅读更多 →
紧凑型设备中的红外测温方案: S-D1贴片传感器在IoT产品中的应用分析

紧凑型设备中的红外测温方案: S-D1贴片传感器在IoT产品中的应用分析

IoT设备小型化趋势下的测温挑战IoT设备的产品形态正在发生深刻变化——从工业级的大型网关到消费级的可穿戴设备、从固定安装的传感器节点到随身携带的智能终端,“更小、更薄、更省电”是贯穿其中的主旋律。这一趋势对温度传感器提出了一个核心矛盾:传统…

2026/10/16 19:33:52 阅读更多 →
Java面试进阶:从八股文到系统设计,掌握AI时代后端工程师核心能力

Java面试进阶:从八股文到系统设计,掌握AI时代后端工程师核心能力

1. 先搞清楚现在面试到底在考什么,别盲目背题 如果你现在还在用三年前的套路准备Java面试,大概率会碰壁。现在的面试,尤其是面对AI工具普及和降本增效的大环境,已经不再是单纯问你“HashMap原理”或者背出“Spring Bean生命周期”就能过关了。面试官更看重的是 你能否把技…

2026/10/20 19:15:56 阅读更多 →

最新新闻

context-mode:上下文感知的自动模式切换引擎实践

context-mode:上下文感知的自动模式切换引擎实践

最早让我决定做一个 context-mode 项目,是因为一个特别具体的痛点:同一套应用,放在办公室、通勤路上、家里、深夜加班这些不同场景里,使用者的操作习惯和真实需求完全不一样。白天在公司网络下打开后台,你可能希望默认…

2026/10/20 20:59:49 阅读更多 →
AI检测率太高怎么办?一套有效降低AI率的文本改写优化方法

AI检测率太高怎么办?一套有效降低AI率的文本改写优化方法

不知道你有没有遇到过这种尴尬:用AI工具写了一版内容,读起来通顺、逻辑也完整,结果放进检测工具里一查,AI概率直接飙到百分之八九十。改了半天也不知道从哪里下手,只能一边吐槽检测器“不靠谱”,一边重新手…

2026/10/20 20:59:48 阅读更多 →
图结构在智能体系统中的应用:任务编排、记忆检索与多智能体协作

图结构在智能体系统中的应用:任务编排、记忆检索与多智能体协作

1. 图结构在智能体系统里到底解决了什么问题第一次把图结构塞进智能体系统的时候,我其实是带着怀疑的。毕竟那会儿大家都在卷提示词工程,谁有空去折腾数据结构。但做完两个项目之后我改主意了——图不是锦上添花,它解决的是智能体系统里最要命…

2026/10/20 20:59:48 阅读更多 →
基于图卷积神经网络的基因-疾病关联预测实战解析

基于图卷积神经网络的基因-疾病关联预测实战解析

做生信的人对“基因疾病关联”这个词不会陌生。从单基因病的位点筛查,到复杂疾病的多基因风险评分,我们一直在跟“哪个基因通过什么机制影响了哪种疾病”这个问题打交道。但传统做法要么靠体外实验一点一点验证,要么靠统计关联从海量样本里硬…

2026/10/20 20:59:48 阅读更多 →
Git分支与合并实战:从commit整理到冲突解决的协作指南

Git分支与合并实战:从commit整理到冲突解决的协作指南

1. 分支纠结现场:为什么大家的git乱成一锅粥1.1 一个真实困扰:代码怎么又“丢”了上个月某天下午,A同学在公司群里发了一句“我改的代码怎么没了”,紧接着截图里是一堆红色的冲突标记。那一刻我就知道,这不是代码丢了&…

2026/10/20 20:59:48 阅读更多 →
鸿蒙ArkTS生鲜超市实战项目解析与避坑指南

鸿蒙ArkTS生鲜超市实战项目解析与避坑指南

简介:本资源是一套基于华为鸿蒙操作系统(HarmonyOS)开发的生鲜超市行业应用实战项目,面向Android开发者转型鸿蒙生态、高校学生学习分布式应用开发及企业级HarmonyOS项目实践者。项目聚焦线上线下融合购物场景,完整呈现…

2026/10/20 20:58:45 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →