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

在Gunicorn运行的FastAPI端点中使用Django ORM时偶发崩溃的排查求助

在Gunicorn运行的FastAPI端点中使用Django ORM时偶发崩溃的排查求助

大家好,我遇到了一个非常棘手的偶发问题,想请教一下有没有人遇到过类似情况或者有排查思路:

我现在是在异步FastAPI端点中脱离Django应用单独使用Django ORM,服务用Gunicorn来运行。大部分时候所有功能都正常,但偶尔会出现诡异的状况:某个worker进程会突然变成“僵尸进程”,完全无法处理任何请求,原因是数据库连接断开了。

之前我看到相关问题里提到,可以用django.db的close_old_connections方法,或者遍历Django的所有连接,对每个连接调用close_if_unusable_or_obsolete方法。我自己写了一个FastAPI中间件来做这件事,但问题还是没有解决,代码如下:

class OptOutOfRandomConnectionCrashFastapiMiddleware(BaseHTTPMiddleware):
    def __init__(self, app: ASGIApp, *args, **kwargs) -> None:
        super().__init__(app)

    async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
        # Pre-processing
        response = await call_next(request)  
        app = request.app
        if not hasattr(app.state, "last_pruned"):
            app.state.last_pruned = 0
            
        if app.state.last_pruned + 5 < time.time():
            start = time.time()
            app.state.last_pruned = start
            for conn in connections.all():
                conn.close_if_unusable_or_obsolete()
            print(f"Pruned all connections. Took {round((time.time() - start) * 1000, 1)} miliseconds")
        

        # Post-processing
        return response

补充一下我的环境和配置细节:

  • 数据库用的是PostgreSQL,数据库端没有设置短超时参数
  • 数据库连接配置我已经开启了每次请求的健康检查,本以为这样能避免“失效连接”的问题:
DATABASES = {
    "default": dj_database_url.config(
        default="postgres://postgres:pass@localhost:5432/db_name",
        conn_max_age=300,
        conn_health_checks=True,
    )
}

但偶尔还是会出现worker崩溃的情况,我附上了当时的堆栈跟踪,但完全看不懂这些错误信息到底在说什么:

Traceback (most recent call last):                                                                         
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in
 run_asgi                                                                                                  
    result = await app(  # type: ignore[func-returns-value]                                                
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in
 __call__                                                                                                  
    return await self.app(scope, receive, send)                                                            
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                            
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__ 
    await super().__call__(scope, receive, send)                                                           
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)                                                      
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __c
all__                                                                                                      
    raise exc                                                                                              
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __c
all__                                                                                                      
    await self.app(scope, receive, _send)                                                                  
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/middleware/cors.py", line 85, in __call
__                                                                                                         
    await self.app(scope, receive, send)                                                                   
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/honeybadger/contrib/asgi.py", line 109, in _run_a
sgi3                                                                              File "/home/ubuntu/py_venv/lib/python3.12/site-packages/honeybadger/contrib/asgi.py", line 118, in _run_a
pp                                                                                                         
    raise exc from None                                                                                    
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/honeybadger/contrib/asgi.py", line 115, in _run_a
pp                                                                                                         
    return await callback()                                                                                
           ^^^^^^^^^^^^^^^^                                                                                
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in 
__call__                                                                                                   
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)                               
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wra
pped_app                                                                                                   
    raise exc                                                                                              
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wra
pped_app                                                                                                   
    await app(scope, receive, sender)                                                                      
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__     
    await self.middleware_stack(scope, receive, send)                                                      
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app          
    await route.handle(scope, receive, send)                                                               
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle       
    await self.app(scope, receive, send)                                                                   
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app           
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)                                 
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wra
pped_app                                                                                                   
    raise exc                                                                                              
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wra
pped_app                                                                                                   
    await app(scope, receive, sender)                                                                      
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app           
    response = await f(request)                                                                            
               ^^^^^^^^^^^^^^^^                                                                            
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app            
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                            
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_fu
nction                                                                                                     
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/stateshift/main.py", line 181, in email_exists                            
    user = await User.objects.filter(email=email).afirst()               ^^^^^^^^^^^^^^^^
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/py_venv/lib/python3.12/site-packages/fastapi/routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/stateshift/main.py", line 181, in email_exists
    user = await User.objects.filter(email=email).afirst()

这个问题已经严重影响了服务的稳定性,因为不知道什么时候就会有worker挂掉。有没有人能给我一些排查的方向或者解决思路?


备注:内容来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:18:20