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

Sanic+Tortoise-ORM中CancelledError致进程崩溃问题求助

解决Sanic+Tortoise-ORM查询超时引发的CancelledError进程崩溃问题

1. 优先解决查询慢的根源:添加数据库索引

你的查询超时本质是id_nunmber和deleted字段无索引,导致全表扫描。直接给这两个字段加联合索引:

CREATE INDEX idx_students_idnumber_deleted ON students (id_nunmber, deleted);

同时在Tortoise-ORM的Students模型里显式声明索引(确保ORM和数据库结构同步):

class Students(models.Model):
    id_nunmber = models.CharField(max_length=64)
    deleted = models.BooleanField(default=False)
    # 其他字段...

    class Meta:
        indexes = [
            models.Index(fields=["id_nunmber", "deleted"])
        ]

2. 捕获CancelledError,阻止异常蔓延导致进程崩溃

在查询代码外层添加异常捕获,处理asyncio.CancelledError,同时返回合理的业务错误:

import asyncio
from sanic.exceptions import HTTPException

# 在你的check_applyexam_data方法中修改
try:
    student: Students = await Students.filter(id_nunmber=data.id_nunmber, deleted=False).first()
except asyncio.CancelledError:
    # 记录日志,抛出业务级超时异常
    logger.error("查询学生信息超时")
    raise HTTPException(status_code=504, detail="服务超时,请稍后重试")

也可以通过Sanic全局异常处理器统一拦截这类异常,避免单个请求的异常拖垮进程:

from sanic import Sanic
from sanic.response import json

app = Sanic("my_app")

@app.exception(asyncio.CancelledError)
async def handle_cancelled_error(request, exception):
    logger.error(f"请求超时被取消: {request.path}")
    return json({"error": "服务超时"}, status=504)

3. 配置Tortoise-ORM的连接超时与连接池参数

调整Tortoise的数据库配置,设置合理的连接超时、查询超时,以及连接池存活检测,避免使用已中断的连接:

TORTOISE_ORM = {
    "connections": {
        "default": {
            "engine": "tortoise.backends.mysql",
            "credentials": {
                "host": "your_db_host",
                "port": 3306,
                "user": "your_user",
                "password": "your_pass",
                "database": "your_db",
                # 连接超时时间(秒)
                "connect_timeout": 10,
                # 单个查询超时时间(秒)
                "query_timeout": 5,
                # 连接池配置
                "minsize": 5,
                "maxsize": 20,
                # 自动回收超过1小时的连接,防止数据库主动断开
                "pool_recycle": 3600,
                # 获取连接前自动ping数据库,验证连接有效性
                "pool_pre_ping": True
            }
        }
    },
    "apps": {
        "models": {
            "models": ["your_app.models"],
            "default_connection": "default",
        }
    }
}

4. 调整Sanic的请求超时设置

Sanic默认的请求超时可能过短,导致查询未完成就被强制取消。在Sanic配置中调整:

app.config.RESPONSE_TIMEOUT = 10  # 单位:秒,根据业务需求调整
app.config.KEEP_ALIVE_TIMEOUT = 75

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:26:18