fastapi在处理上传文件时会偶尔卡死
因为想要在日志中打印请求信息,包含请求体,响应信息等,因此在工厂函数中添加了自定义的中间件:
app.add_middleware(RequestContextLogMiddleware)
#中间件定义如下
class RequestContextLogMiddleware(BaseHTTPMiddleware):
"""
所有的请求都会使用此中间件
"""
async def set_body(self,request:Request):
receive_ = await request._receive()
async def receive():
return receive_
request._receive = receive
async def dispatch(
self, request: Request, call_next: RequestResponseEndpoint
) -> Response:
start_time = time.time()
await self.set_body(request)
body = await request.body()
try:
body = await request.json()
except Exception as err:
pass
logger.info(f" start request [request id = {request.headers.get('x-request-id', '')}] path={request.url.path}")
logger.info(parse_http_request(request,body))
response = await call_next(request)
if response.headers.get('content-type') in config.ECHO_HEADERS \
and request.url.path not in config.NO_ECHO_LOG_PATH:
response_body = [chunk async for chunk in response.body_iterator]
response.body_iterator = iterate_in_threadpool(iter(response_body))
logger.info(f"The request {request.url.path}:response_body={response_body[0].decode()}")
process_time = (time.time() - start_time) * 1000
formatted_process_time = '{0:.2f}'.format(process_time)
logger.info(f"The request [request id = {request.headers.get('x-request-id','')}] completed_in="
f"{formatted_process_time}ms status_code={response.status_code}")
return response
处理上传文件的路由如下:
@api.post(f"{BASEURL}importAchieve",tags=["数据录入"],summary="批量导入数据")
def import_achieve(
achieve_file: UploadFile = File(..., description="批量录入业绩"),
x_request_id: str = Header(..., description="request_id信息"),
db_mysql_conn=Depends(db_mysql_conn, use_cache=True),
db_ch_conn=Depends(db_ch_conn, use_cache=True),
user_info = Depends(checkUserProfileAuthRpc)
):
user_name = user_info.get("user_name", "")
return handle_import_achieve_request(db_mysql_conn,db_ch_conn,achieve_file,x_request_id,user_name,DumpDataType.MANUAL_DUMP)
这个接口有时候可以成功,有时候卡死,出现卡死的时候,整个程序全部都会卡死,所有的接口都访问不了;卡死的时候,日志中不会打印任何信息,控制台上也不会有输出?