FastAPI异步任务执行问题求助:外部服务调用异常排查
解决方案
1. 异步函数未执行的问题(场景1)
异步函数调用后返回的是协程对象,必须显式通过await触发执行,或者将协程交给事件循环后台执行(不阻塞主请求)。如果不想让主服务等待DB Writer的请求结果,可以用asyncio.create_task将异步任务丢到后台:
修改主应用中的调用代码:
import asyncio # ... 其他代码 ... async def manager_api(raw_input:arrival_requests) : # ... 前面的逻辑保持不变 ... # 后台执行DB写入请求,不阻塞主响应返回 asyncio.create_task(db_writer_requests(depart_json,dict(pred_output))) return send_msg
这样主服务会直接返回send_msg,DB Writer的请求在后台异步执行,不会影响终端用户的响应速度。
2. 目标服务不可用时主服务报错的问题(场景2)
需要在db_writer_requests中添加异常捕获,处理连接失败、超时、HTTP错误等情况,避免未处理的异常导致主服务返回500错误。同时优化HTTPClient的使用(复用客户端而非每次创建):
优化后的db_writer_requests代码:
import aiosonic from aiosonic.timeout import Timeouts from aiosonic.exceptions import TimeoutException, ConnectionError # 全局复用HTTPClient,避免重复创建开销 client = aiosonic.HTTPClient() async def db_writer_requests(arrival_input, prediction_out): timeouts_settings = Timeouts(sock_connect=10, sock_read=10) try: await client.post( 'http://127.0.0.1:8082/api/motor/writer/test1', headers={'Content-Type': 'application/json'}, json=arrival_input, timeouts=timeouts_settings ) except TimeoutException: # 处理超时情况,可替换为日志记录 print("DB Writer请求超时") except ConnectionError: # 处理连接失败(服务不可用)情况 print("无法连接到DB Writer服务") except Exception as e: # 捕获其他未知异常 print(f"DB Writer请求出错: {str(e)}")
补充:应用关闭时关闭HTTP客户端
在FastAPI中,可以添加shutdown事件处理函数来关闭全局的HTTPClient:
@app.on_event("shutdown") async def shutdown_event(): await client.shutdown()
关键说明
- 异步协程必须通过
await或asyncio.create_task触发执行,否则只会创建协程对象但不会实际运行。 - 捕获异常可以避免未处理的错误导致主服务返回500,建议用专业日志模块(如
logging)替代print做错误记录。 - 复用HTTPClient可以减少TCP连接创建的开销,提升服务性能。
内容的提问来源于stack exchange,提问作者N7TKat
相关产品推荐
相关产品推荐

