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

Flask应用部署Cloud Run:GCS上传成功但API无响应求助

Flask应用部署Cloud Run后API无响应问题排查与解决方案

核心问题分析

本地运行正常,但Cloud Run部署后出现GCS上传成功但API无响应,移除gunicorn后短期正常但多次请求后失效,本质是耗时任务的并发处理适配问题+Cloud Run资源配置与服务运行模型不匹配。

一、修复gunicorn配置(优先推荐)

移除gunicorn后用Flask自带单线程服务器,生产环境下完全无法应对并发请求,必须重新配置gunicorn适配Cloud Run场景:

  • 启动命令调整(适配2核CPU):
gunicorn --workers=5 --threads=4 --timeout=3600 --bind=0.0.0.0:$PORT app:app
  • --workers=5:遵循CPU核数×2+1的规则,最大化利用2核资源
  • --threads=4:控制单worker线程数,避免CPU密集型任务的上下文切换开销
  • --timeout=3600:与Cloud Run请求超时保持一致,防止worker被提前杀死
  • --bind=0.0.0.0:$PORT:严格匹配Cloud Run的端口要求

二、解决耗时任务阻塞问题

视频处理单请求耗时15-20分钟,同步处理会占满所有worker/线程,导致后续请求无响应:

  1. 异步任务队列改造(最优方案):
    • API收到视频请求后,将任务信息(如视频存储路径)推送至Cloud Pub/Sub或Cloud Tasks,立即返回202 Accepted响应
    • 单独部署一个Cloud Run服务/Cloud Functions作为worker,监听任务队列处理视频、生成CSV并上传GCS
  2. 线程池临时适配(快速验证):
    用concurrent.futures.ThreadPoolExecutor在Flask中异步处理视频任务,避免阻塞主线程:
    from concurrent.futures import ThreadPoolExecutor
    executor = ThreadPoolExecutor(max_workers=4)
    
    @app.route('/process-video', methods=['POST'])
    def process_video():
        # 解析请求参数
        executor.submit(handle_video_processing, video_data)
        return jsonify({"status": "task started"}), 202
    
    def handle_video_processing(video_data):
        # 视频检测、CSV生成、GCS上传逻辑
        pass
    

三、调整Cloud Run配置

  1. 降低单实例并发数:
    当前设置的80并发数远超出2核CPU+8GiB内存的承载能力,建议降至10以内,确保每个请求有足够资源处理
  2. 修改CPU分配策略:
    将“仅在请求处理期间分配CPU”改为“始终分配CPU”,视频处理是持续CPU密集型任务,避免IO等待阶段CPU被回收导致处理停滞
  3. 监控资源使用率:
    在Cloud Run控制台查看实例的内存/CPU曲线,若多次请求后内存持续上涨,说明存在资源泄漏(如未释放OpenCV的VideoCapture、未删除临时文件)

四、排查资源泄漏

在视频处理逻辑中强制释放资源:

import cv2
import os

def process_video(video_path):
    cap = cv2.VideoCapture(video_path)
    try:
        # 视频检测逻辑
        pass
    finally:
        cap.release()  # 释放OpenCV资源
        os.remove(video_path)  # 删除本地临时视频文件

def upload_to_gcs(csv_path):
    try:
        # GCS上传逻辑
        pass
    finally:
        os.remove(csv_path)  # 删除本地CSV文件

五、日志强化排查

在代码关键节点添加日志,定位无响应的具体阶段:

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@app.route('/process-video', methods=['POST'])
def process_video():
    logger.info("Received video processing request")
    # 解析请求
    logger.info("Start video detection")
    # 检测逻辑
    logger.info("CSV generated, start uploading to GCS")
    # 上传逻辑
    logger.info("GCS upload completed, request finished")
    return jsonify({"status": "success"})

通过Cloud Run控制台查看日志,确认请求卡在哪个环节(如视频检测、GCS上传后未返回响应)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:47:37