首页 > 其他分享 >FastApi框架异步调用同步问题

FastApi框架异步调用同步问题

时间:2025-01-10 15:22:26浏览次数:1  
标签:异步 调用 run FastApi 同步 result FastAPI import

Fastapi项目,在接口中调用同步方法,如果该同步方法,耗时较长(比如连接redis超时),会造成整个项目接口的阻塞,这是任何接口的访问都会被阻塞超时

一、为什么会阻塞

FastAPI 是基于异步框架(如 asyncioanyio)构建的,它的核心是一个事件循环(Event Loop)。事件循环负责调度和执行所有的异步任务。当你在异步函数中直接调用同步阻塞代码时,事件循环会被阻塞,无法继续处理其他任务,直到同步代码执行完毕。

from fastapi import FastAPI
import time

app = FastAPI()

def sync_function():
    time.sleep(5)  # 模拟一个耗时的同步操作
    return "Done"

@app.get("/")
async def root():
    result = sync_function()  # 直接调用同步函数
    return {"result": result}

在这个例子中time.sleep(5) 是一个同步阻塞操作,它会阻塞事件循环 5 秒钟。在这期间,FastAPI 无法处理其他请求,整个应用的并发性能会大幅下降。

二、如何避免阻塞

将同步代码放到线程池或进程池中执行,将同步代码改为异步实现。有以下几种常用解决方案

1. 使用 run_in_threadpoolasyncio.to_thread

将同步代码放到线程池中执行,避免阻塞事件循环。

from fastapi import FastAPI
from fastapi.concurrency import run_in_threadpool
import time

app = FastAPI()

def sync_function():
    time.sleep(5)  # 模拟一个耗时的同步操作
    return "Done"

@app.get("/")
async def root():
    result = await run_in_threadpool(sync_function)  # 在线程池中运行
    return {"result": result}

2 使用 run_in_processpool

对于 CPU 密集型的同步代码,可以使用进程池来避免阻塞事件循环。

 

from fastapi import FastAPI
from fastapi.concurrency import run_in_processpool
import time

app = FastAPI()

def cpu_intensive_function():
    # 模拟一个 CPU 密集型的操作
    result = sum(i * i for i in range(10**6))
    return result

@app.get("/")
async def root():
    result = await run_in_processpool(cpu_intensive_function)  # 在进程池中运行
    return {"result": result}

3. 将同步代码改为异步实现

如果可能,尽量将同步代码改为异步实现。例如,使用 asyncio.sleep 代替 time.sleep,或者使用异步库代替同步库。

from fastapi import FastAPI
import asyncio

app = FastAPI()

async def async_function():
    await asyncio.sleep(5)  # 异步等待
    return "Done"

@app.get("/")
async def root():
    result = await async_function()  # 直接调用异步函数
    return {"result": result}

4. 使用 anyio.to_thread.run_sync

如果你使用的是 anyio 库,可以使用 anyio.to_thread.run_sync 来运行同步代码。

from fastapi import FastAPI
import anyio
import time

app = FastAPI()

def sync_function():
    time.sleep(5)  # 模拟一个耗时的同步操作
    return "Done"

@app.get("/")
async def root():
    result = await anyio.to_thread.run_sync(sync_function)  # 在线程池中运行
    return {"result": result}

总结

  • 直接调用同步代码会阻塞事件循环,导致整个应用的性能下降。

  • 解决方案

    • 对于 I/O 密集型任务,使用 run_in_threadpoolasyncio.to_thread

    • 对于 CPU 密集型任务,使用 run_in_processpool

    • 尽量将同步代码改为异步实现。

  • 最佳实践:在 FastAPI 中,尽量避免直接调用同步阻塞代码,始终使用异步或线程池/进程池来处理同步任务。

 

标签:异步,调用,run,FastApi,同步,result,FastAPI,import
From: https://www.cnblogs.com/ltyc/p/18664047

相关文章

  • 多继承背景下的调用逻辑【MRO】
    MROMRO(MethodResolutionOrder,方法解析顺序)是指在多继承情况下,Python解释器按照特定的顺序来查找和调用方法的规则。classA:passclassB:passclassC(A,B):passprint(C.__mro__)#输出:(<class'__main__.C'>,<class'__main__.A'>,<class......
  • 聊一聊 C#异步 任务延续的三种底层玩法
    一:背景1.讲故事最近聊了不少和异步相关的话题,有点疲倦了,今天再写最后一篇作为近期这类话题的一个封笔吧,下篇继续写我熟悉的 生产故障 系列,突然亲切感油然而生,哈哈,免费给别人看程序故障,是一种积阴德阳善的事情,欲知前世因,今生受者是。欲知来世果,今生做者是。在任务延续方面......
  • 聊一聊 C#异步 任务延续的三种底层玩法
    一:背景1.讲故事最近聊了不少和异步相关的话题,有点疲倦了,今天再写最后一篇作为近期这类话题的一个封笔吧,下篇继续写我熟悉的生产故障系列,突然亲切感油然而生,哈哈,免费给别人看程序故障,是一种积阴德阳善的事情,欲知前世因,今生受者是。欲知来世果,今生做者是。在任务延续方面,我个......
  • UART异步串行通信协议
    UART概述UART的定义USART指通用同步收发器,UART指通用异步收发器这些通用收发器提供了一种灵活的方式与外部设备进行单工/半双工/全双工方式的数据交互,并且可选择多种波特率,支持多种通信协议和功能模式等UART的类别STM8S单片机片内总共有3个串口资源:UART1/2/3(STM8S105则只......
  • FastAPI使用异步 ORM 进行高效数据库操作与管理
    FastAPI使用异步ORM进行高效数据库操作与管理目录......
  • FastAPI 依赖注入、异步任务与分布式调度
    FastAPI依赖注入、异步任务与分布式调度目录......
  • 使用API方式远程调用ollama模型
    在有GPU的环境启动一个ollama大模型,非常简单:注意,ollama启动时默认监听在127.0.0.1:11434上,可以通过配置OLLAMA_HOST环境变量修改点击查看代码exportOLLAMA_HOST="0.0.0.0:11434"ollamaserve&ollamarunqwen2.5:7b-instruct然后就可以在远端访问:点击查看代......
  • C# 调用YoloSharp.Gpu,调用Microsoft.ML.OnnxRuntime.Gpu出错126
    今天使用C#调用YoloSharp.Gpu,加载onnx模型,然后检测,代码很简单。//LoadtheYOLOpredictorpredictor??=newYoloPredictor(@"pathtoyour.onnx");//Runmodelvarresult=predictor.Detect(@"pathtoyourimage");一运行就爆错ONNXRuntimeError:1:FAIL:LoadL......
  • 玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
    系列文章目录01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南文章目录系列文章目录前言一、LangChain环境搭建与初始配置1.1安装依赖1.2环境变量加载1.2.1具体步骤1.2.2注意事项1.3初始化模型客户端二、基础示例:与模型交互2.1直接调用模型2.1.1......
  • 在 Go 应用中 如何像 FastAPI 一样优雅地构建控制器
    文章精选推荐1JetBrainsAiassistant编程工具让你的工作效率翻倍2ExtraIcons:JetBrainsIDE的图标增强神器3IDEA插件推荐-SequenceDiagram,自动生成时序图4BashSupportPro这个ides插件主要是用来干嘛的?5IDEA必装的插件:SpringBootHelper的使用与功能特点6A......