Django服务器视频流创建问题:未关闭连接致CPU负载过高
Django视频流连接泄漏导致CPU负载过高的解决思路
问题描述
每次客户端调用get_stream_video视图时,都会创建新的连接实例;未正常关闭的流响应会持续占用CPU资源,导致负载攀升。尝试通过全局列表管理并关闭生成器,但未解决问题。
原代码:
generator_list = [] @gzip.gzip_page def get_stream_video(request, stream_link): if len(generator_list) == 2: generator_list[1].close() del(generator_list[1]) try: generator = detect_stream(stream_link) generator_list.append(generator) stream = StreamingHttpResponse(generator, content_type="multipart/x-mixed-replace;boundary=frame") return stream except: pass
问题分析
- 全局列表管理逻辑无效:仅保留两个生成器实例的规则无法适配多客户端场景,且未针对客户端主动断开连接的场景做处理,生成器资源无法被正确回收。
- 流式响应与gzip冲突:
gzip.gzip_page装饰器会缓冲响应内容,破坏multipart/x-mixed-replace的分帧传输逻辑,同时加重服务器资源消耗。 - 生成器无终止触发机制:默认情况下,
StreamingHttpResponse不会在客户端断开时主动终止生成器,导致生成器持续运行占用CPU。
解决方案
1. 移除gzip压缩装饰器
流式视频帧不需要gzip压缩,该装饰器会干扰分帧传输,直接删除@gzip.gzip_page。
2. 按请求实例跟踪生成器
用字典替代全局列表,以请求实例的唯一标识为键跟踪活跃生成器,确保每个连接的资源能精准回收。
3. 绑定请求结束信号终止生成器
通过Django的request_finished信号,在请求结束时触发生成器终止逻辑;同时在生成器内部增加终止判断,及时停止帧生成。
修改后的示例代码:
from django.http import StreamingHttpResponse, HttpResponse from django.core.signals import request_finished from django.dispatch import receiver # 按请求实例跟踪活跃生成器 active_generators = {} def detect_stream(stream_link): # 给生成器添加终止标记 detect_stream.should_stop = False while not detect_stream.should_stop: # 原帧生成逻辑示例 frame = get_frame_from_stream(stream_link) # 替换为实际取帧逻辑 yield b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n' @receiver(request_finished) def cleanup_generator(sender, **kwargs): request = kwargs.get('request') if request and id(request) in active_generators: # 标记生成器终止 gen = active_generators.pop(id(request)) gen.should_stop = True def get_stream_video(request, stream_link): try: generator = detect_stream(stream_link) active_generators[id(request)] = generator stream = StreamingHttpResponse( generator, content_type="multipart/x-mixed-replace;boundary=frame" ) return stream except Exception as e: print(f"视频流错误: {str(e)}") return HttpResponse("视频流不可用", status=503)
额外说明
- 若
detect_stream使用第三方视频流库,需确认库本身是否提供连接关闭的API,优先调用原生关闭方法终止流。 - 可结合客户端IP、SessionID等标识优化生成器跟踪逻辑,避免请求实例ID冲突。
内容的提问来源于stack exchange,提问作者Basil the dev
相关产品推荐
相关产品推荐

