news 2026/4/23 12:49:57

FastAPI 流式响应中,如何优雅处理客户端断连后的数据库操作?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastAPI 流式响应中,如何优雅处理客户端断连后的数据库操作?

问题出现过程

1. 客户端发起流式对话请求

我们从一个典型的流式对话接口开始。我们使用依赖注入来获取一个 SQLAlchemy 的 AsyncSession,在对话开始时创建消息,在对话结束后更新 AI 的回答。

流式对话原始代码(伪代码)

2. 客户端取消对话(主动断开)

当用户取消发送时,会抛出这个异常

pymysql.err.InterfaceError:

原因:当客户端断开时 ,FastAPI 会立即把它的 session连接回收掉,底层的那个物理连接被标记为 Cancelled,然后执行finally的时候,再往下传原来session连接就不对了,save_conversation函数就会抛pymysql.err.InterfaceError。

问题解决尝试

尝试一:在 save_conversation 函数中创建新连接

一个自然的想法是:既然旧的 session 不能用了,那就在保存的时候检查一下,如果不可用就创建一个新的。

代码更新

结果:失败! 没想到,即使创建了新的 session,依然抛出了 pymysql.err.InterfaceError。

原因分析:之所以还会抛错误,原因是这个新会话 依然在使用已经被取消的连接池资源,因为 FastAPI/Starlette 在主请求取消时,会把整个 AsyncSessionLocal() 对象的连接都标记为 “cancelled”。即便你重新 async with AsyncSessionLocal(),底层复用的还是同一个数据库连接池里的连接,而那个连接刚被 cancel。

重新创建个数据库引擎 是肯定可以的,但是只是对话后更新,这么搞完全没必要。

或者创建个独立线程,在新线程中去创建新连接,应该是可以的,个人还是感觉比较重,浪费资源。

尝试二:创建个协程去执行save_conversation

代码更新

疑惑点:asyncio.create_task 启动的协程仍然跑在同一个线程和进程里,也会复用那个全局的连接池,理论上确实还有可能拿到刚才那个被 cancel 的连接啊?

主要在于操作的时序和上下文隔离:

先清理,后执行

当原始请求被取消后,FastAPI 会立即开始清理与该请求相关的资源(包括回收它持有的数据库连接)。这个清理动作在 finally 块中调用 create_task 之前就已经触发了。我们派生出的后台任务是在这个清理逻辑之后才启动的。

上下文隔离

这个后台协程已经完全不挂在 HTTP 请求的上下文上了。客户端断开与否,都影响不了它的独立运行。只要连接池中还有任意一个好连接,它就能完成写入。

高成功率

因为顺序已经变成了:先断开、先清理 → 再新建、再执行,所以新任务向连接池请求时,拿到那个“坏掉”连接的概率已经大大降低。连接池会优先分配一个健康的、空闲的连接。

即使在极端情况下又拿到了旧连接,它也很有可能在 session.begin() 阶段就失败,我们还可以在后台任务的 try...except 块里加入重试逻辑(比如 await asyncio.sleep(0.1) 后重试),进一步提高健壮性。

大量测试后,发现真没问题😁。

结论

对于需要确保最终操作(如数据写入)一定执行的流式 API,asyncio.create_task 提供了一种轻量级且非常有效的解决方案。它避免了引入像 Celery 这样复杂的任务队列,同时优雅地解决了因客户端断连导致资源状态污染的问题。

通过将关键的收尾工作与不稳定的 HTTP 请求生命周期解耦,我们能构建出更加健壮和可靠的 FastAPI 应用。"

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 9:25:24

规模化IoT节点维护成本与能量采集方案设计要点

在PoC原型阶段,节点BOM成本计算通常集中在MCU、传感器与低价电池等部件,整体成本较低。然而,当节点数量从1,000扩展到100,000级别,并部署于数平方公里的化工厂或复杂智慧楼宇中时,维护周期成为影响总成本的核心变量。 …

作者头像 李华
网站建设 2026/4/23 10:49:07

孤能子视角:从“奇点“到意识文明

(从"哲学"研究意识是一件头疼的事。这里让千问先梳理,信兄稍为解释。)主要问题:1.从奇点到有高等动植物的里程碑过程。2.生命演化过程中,关键基因突变推动进化。3.当前的意识学研究程度和结论。1.从奇点到有高等动植物的里程碑过程。千问:这是…

作者头像 李华
网站建设 2026/4/23 12:14:08

普源DS6000系列分段存储深度优化方案

普源DS6000系列示波器以其高精度和强大的功能, 为电子工程师提供了出色的信号捕获与分析能力。其分段存储(Segmented Memory)功能设计使用户能够在处理复杂信号时高效地管理存储资源,从而提高测试的灵活性与准确性。然而,在实际应…

作者头像 李华
网站建设 2026/4/23 12:20:40

运维远控工具盘点排名第一:为何大公司都选择选择ToDesk

在数字化转型的浪潮中,运维工作作为保障企业业务连续性的基石,正经历着前所未有的深刻变革。传统运维模式下,工程师们往往疲于奔命,效率瓶颈与安全隐忧如影随形。如今,以ToDesk为代表的下一代远程控制技术,…

作者头像 李华
网站建设 2026/4/22 4:36:36

Java毕设项目:基于SpringBoot的少儿编程在线教育网站设计与开发基于Java的scratch少儿编程学习网站系统的设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华