You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在Azure App Service的FastAPI Docker应用抛出TaskCanceledException问题求助

提问:FastAPI+SQLAlchemy应用部署在Azure App Service出现请求转发超时挂起问题

问题背景

我将一个基于FastAPI + SQLAlchemy(PostgreSQL Supabase)的应用通过Docker容器部署在Azure App Service上,已配置服务保持活跃,不存在冷启动问题。但应用会不定期在日志中出现错误,同时发生挂起——API完全无响应,既不超时也不返回结果,目前未发现明确的触发规律。网上未找到相关文档或类似案例,想问问有没有人遇到过该问题,以及对应的解决方法是什么?

错误日志

Failed to forward request to http://1xx.xx.xx.2:8000. Encountered a System.Threading.Tasks.TaskCanceledException exception after 300021.816ms with message: The request was canceled due to the configured HttpClient.Timeout of 300 seconds elapsing.. Check application logs to verify the application is properly handling HTTP traffic.

已尝试的优化措施

  • 提升数据库配置规格
  • 使用Supabase提供的连接池服务
  • 缓存数据库查询结果以减少数据库调用
  • 提升Azure App Service的配置规格

相关代码片段

# db.py

SQLALCHEMY_DATABASE_URL = os.environ["SQLALCHEMY_DATABASE_URL"]
def get_engine():
    return create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True)
SessionLocal = sessionmaker(
    autocommit=False, autoflush=False, bind=get_engine())


# main.py 

def get_db():
    db = SessionLocal()
    try:
        yield db
        db.commit()
    except:
        # 发生任何异常时回滚事务
        db.rollback()
        raise
    finally:
        db.close()

# 路由中通过Depends传入会话
def test_auth0(token=Depends(token_auth_scheme), db: Session = Depends(get_db)):
    # 路由逻辑省略

可能的解决思路与方案

1. 排查应用内部请求阻塞问题

Azure的超时提示核心是:转发层把请求发给容器的8000端口后,容器未在300秒内返回响应,导致转发超时。这说明问题大概率在应用内部,而非单纯资源不足(你已升级过规格)。

  • 给数据库查询加强制超时:在create_engine中添加连接参数,防止慢查询卡住整个请求,比如:
    create_engine(
        SQLALCHEMY_DATABASE_URL,
        pool_pre_ping=True,
        connect_args={"options": "-c statement_timeout=30000"}  # 30秒超时
    )
    
    如果有长时间运行的业务逻辑,必须改成异步执行(比如用Celery+Redis),不能让请求线程一直挂起等待。
  • 调整事务生命周期:你当前在yield db之后才执行commit,意味着整个请求处理过程中事务始终处于打开状态。如果请求中包含耗时操作,会长期占用数据库连接,甚至耗尽连接池导致后续请求排队挂起。建议在业务逻辑完成后手动触发commit,或者优化事务范围,避免不必要的长事务。另外,异常捕获不要用宽泛的except:,改为捕获具体的数据库异常,防止吞掉其他类型的错误。

2. 检查Docker容器网络与进程状态

  • 确认FastAPI监听地址:容器内的FastAPI必须监听0.0.0.0:8000,不能只监听127.0.0.1,否则Azure转发层无法访问。
  • 排查僵死进程:通过Azure日志或docker exec进入容器,查看是否有挂起的Python进程。如果存在,大概率是某个请求触发了死锁或无限循环,需要结合请求日志定位具体代码。

3. 调整Azure App Service转发配置

  • 关闭ARR粘性会话:如果开启了ARR Affinity,可能导致请求集中在某个实例上引发过载,建议关闭该选项测试。
  • 确认端口映射:检查WEBSITES_PORT配置是否和容器内FastAPI的监听端口一致,避免端口不匹配导致转发失败。

4. 增加应用级日志监控

给每个请求添加唯一ID,记录请求进入、数据库操作开始/结束、响应返回的时间点,定位卡环节点。比如添加FastAPI中间件:

from fastapi import Request
import uuid
import time

@app.middleware("http")
async def log_request_details(request: Request, call_next):
    request_id = str(uuid.uuid4())
    print(f"[{request_id}] 请求开始: {request.method} {request.url}")
    start_time = time.time()
    response = await call_next(request)
    process_duration = time.time() - start_time
    print(f"[{request_id}] 请求结束: 耗时{process_duration:.2f}s,状态码{response.status_code}")
    return response

5. 优化SQLAlchemy连接池配置

结合Supabase的连接池服务,调整本地连接池参数避免冲突:

create_engine(
    SQLALCHEMY_DATABASE_URL,
    pool_pre_ping=True,
    pool_size=10,  # 根据并发量调整
    max_overflow=20,
    pool_recycle=300  # 小于Supabase PGBouncer的超时时间,防止连接被回收后复用
)

内容的提问来源于stack exchange,提问作者Savio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:42:51