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

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

问题分析

  1. 全局列表管理逻辑无效:仅保留两个生成器实例的规则无法适配多客户端场景,且未针对客户端主动断开连接的场景做处理,生成器资源无法被正确回收。
  2. 流式响应与gzip冲突:gzip.gzip_page装饰器会缓冲响应内容,破坏multipart/x-mixed-replace的分帧传输逻辑,同时加重服务器资源消耗。
  3. 生成器无终止触发机制:默认情况下,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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:06:02