Waitress服务器连接数无法提升问题及流媒体替代方案咨询
1. Waitress连接上限问题分析与解决
核心原因
你遇到的4连接上限,大概率是启动命令的应用入口写错,导致Waitress没有加载你设置的线程参数,而是使用了默认的4线程配置。你的代码里定义的是全局app对象,但启动命令里写的是img:create_app(工厂函数),而你的代码中并没有create_app函数,Waitress会尝试创建一个默认的Flask应用,忽略你在命令行设置的--threads=24参数,自然只能处理4个并发长连接(MJPEG流是长连接,每个连接占用一个线程)。
另外,即使入口正确,Waitress作为同步服务器,每个长连接会持续占用一个线程,若你的gather_img函数里有阻塞操作(比如time.sleep、OpenCV读取摄像头的阻塞调用),线程会被一直占用,无法处理新连接。
解决步骤
- 修正启动命令:如果你的代码文件是
img.py,且里面的Flask实例是app,启动命令应该改为:waitress-serve --listen=*:8080 --threads=24 img:app - 补充连接数配置:若仍有上限,可添加
--connection-limit参数提高总连接限制(默认100,可按需调整):waitress-serve --listen=*:8080 --threads=24 --connection-limit=100 img:app - 优化阻塞逻辑:将摄像头读取等阻塞操作改为异步方式,或者使用线程池处理帧采集,避免占用请求线程。
2. 低延迟实时流推送方案推荐
方案一:异步框架+MJPEG(优化现有方案)
用FastAPI+Uvicorn(异步服务器)替代Flask+Waitress,异步服务器可以用少量线程处理大量长连接,适合MJPEG这类长连接场景。示例代码:
from fastapi import FastAPI, Response import cv2 import numpy as np import asyncio app = FastAPI() async def gather_img(): while True: await asyncio.sleep(0.2) img = np.random.randint(0, 255, size=(128, 128, 3), dtype=np.uint8) _, frame = cv2.imencode('.jpg', img) yield b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + frame.tobytes() + b'\r\n' @app.get("/get-image") async def mjpeg(): return Response(gather_img(), media_type='multipart/x-mixed-replace; boundary=frame')
启动命令:uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4,异步模型可轻松处理数十甚至上百个并发连接,延迟和MJPEG一致(约0.2秒左右)。
方案二:WebSocket传输压缩帧
通过WebSocket推送压缩后的图像帧(如JPEG/WebP),客户端接收后解码渲染,延迟比MJPEG更低(可控制在100ms以内)。核心思路:
- 服务端:用FastAPI/Flask-SocketIO建立WebSocket连接,定期推送编码后的帧数据。
- 客户端:监听WebSocket消息,将二进制数据转为Blob,更新
<img>标签的src。
方案三:WebRTC(最低延迟)
WebRTC是专为实时音视频设计的协议,端到端延迟可控制在50ms以内,适合对延迟要求极高的场景。无需中间服务器转发(或仅需信令服务器),支持自适应带宽调整。但实现复杂度较高,需要处理信令、ICE协商等逻辑。
内容的提问来源于stack exchange,提问作者Arctic

