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

Python Flask API无法处理多请求,寻求技术排查指导

问题排查与解决方案

你的问题核心是单个请求的OCR处理就耗尽了系统全部线程,叠加多请求后,Flask线程池+OCR线程完全占满CPU,导致系统无响应、资源枯竭。以下是具体的排查和解决方向:

1. 限制OCR的并发线程数

不要让OCR引擎直接占用全部可用线程,手动控制并发数:

  • 用concurrent.futures.ThreadPoolExecutor封装OCR任务,设置合理的max_workers,比如取CPU核心数的1/2到2/3(避免单个请求占满资源)。示例代码:
import concurrent.futures
import os

def ocr_single_page(image):
    # 单个页面的OCR逻辑
    pass

def ocr_all_pages(images):
    max_workers = os.cpu_count() // 2  # 比如用一半核心
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(ocr_single_page, images))
    return results
  • 如果你的OCR引擎(如Tesseract)自带线程参数,直接设置对应参数(比如Tesseract的--threads),不要让它默认占用全部线程。

2. 替换Flask开发服务器为生产级WSGI服务器

Werkzeug(Flask自带服务器)的threaded=True没有线程数限制,生产环境下无法有效控制资源,换成Gunicorn或uWSGI:

  • 用Gunicorn启动,控制进程和线程数:
gunicorn --workers 2 --threads 4 --timeout 300 app:app -b 0.0.0.0:6996
  • --workers:进程数,一般设为CPU核心数或核心数+1
  • --threads:每个进程的线程数,结合OCR线程数,控制总线程数不超过系统承载能力
  • --timeout:延长超时时间,适配长任务

3. 引入异步任务队列解耦请求与处理

把OCR和深度学习模型处理放到异步任务中,避免请求长时间阻塞Flask线程:

  • 用Celery+Redis作为任务队列:
    1. 配置Celery连接Redis
    2. 把OCR+模型处理逻辑封装为Celery任务
    3. Flask只负责接收PDF、提交任务,返回任务ID给客户端
    4. 客户端通过任务ID轮询获取处理结果
  • 好处:可通过Celery的worker数控制并发任务数,避免资源瞬间占满,同时Flask能快速响应请求,不会被长任务阻塞。

4. 定位资源瓶颈

  • 用htop观察CPU占用:如果OCR阶段CPU拉满,重点优化OCR并发数;如果模型推理阶段占比高,考虑:
    • 改用GPU加速模型推理(若当前用CPU)
    • 限制模型并发数(比如同一时间只允许1-2个推理任务)
    • 复用模型实例,避免每次请求重新加载模型(模型加载极耗资源)
  • 用free -m监控内存,排查是否存在内存泄漏或内存不足的情况。

5. 优化任务流程

  • PDF转图像时,在不影响OCR精度的前提下,降低图像分辨率、灰度化,减少OCR计算量
  • 简化文本清洗逻辑,避免不必要的字符串操作或正则匹配
  • 若多个深度学习模型可并行处理,用多进程(而非多线程,Python GIL限制下CPU密集型任务多进程更高效)处理,但需严格控制并发数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:26:25