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

Flask集成OpenAI Assistant进程被Killed,内存泄漏问题排查与修复

问题原因分析

终端显示“Killed”通常是系统因**内存耗尽(OOM)**主动终止进程,你的代码主要问题出在以下几点:

  • 空闲会话清理时机不合理:kill_idle_sessions()仅在用户发起请求时才会执行,如果服务器长时间没有新请求,空闲会话会一直占用内存无法释放,最终导致内存耗尽。
  • 未释放远程会话资源:删除本地Session对象时,没有调用OpenAI API删除对应的远程Thread资源,本地对象销毁后,远程资源的客户端引用可能存在隐性内存泄漏。
  • 异常场景下会话残留:请求中途失败时,新创建的Session可能未被及时清理,持续占用内存。
修复方案

1. 改用定时任务自动清理空闲会话

创建独立线程定时执行清理逻辑,确保即使没有用户请求,也能定期释放内存:

def start_session_cleanup_thread():
    def cleanup_loop():
        while True:
            kill_idle_sessions()
            time.sleep(60)  # 每分钟执行一次清理
    cleanup_thread = threading.Thread(target=cleanup_loop, daemon=True)
    cleanup_thread.start()

# 在app初始化后启动定时清理线程
if __name__ == '__main__':
    start_session_cleanup_thread()
    app.run(debug=False, ssl_context=..., host='0.0.0.0')

2. 清理Session时同步删除远程Thread

修改kill_idle_sessions()函数,删除本地Session前调用OpenAI API销毁远程Thread,彻底释放资源:

def kill_idle_sessions():
    for sid in list(sessions.keys()):
        scls = sessions[sid]
        if time.time() - scls.last_request > 60*15:
            # 删除远程Thread
            try:
                client.beta.threads.delete(scls.thread.id)
                logger.info(f'Deleted remote thread {scls.thread.id} for session {sid}')
            except Exception as e:
                logger.error(f'Failed to delete thread {scls.thread.id}: {e}')
            # 删除本地Session
            del sessions[sid]
            logger.info(f'Killed {sid} due to idle')

3. 优化异常场景下的Session清理

在ask接口中,确保请求失败时新创建的Session能被及时删除:

@app.route('/ask', methods=['POST'])
def ask():
    """API method to ask the assistant a question"""
    new_session_created = False
    session_id = None
    try:
        # has session id cookie?
        session_id = request.json.get('session_id', None)
        has_session = session_id is not None

        if not has_session:
            session_id = uuid.uuid4().hex
            new_session_created = True

        if has_session and session_id not in sessions:
            return jsonify(dict(type="error", error="Invalid session id"))

        question = request.json['question']

        resp = dict(type="success", response="What do you mean by that...?")

        if not has_session:
            resp['session_id'] = session_id
            sessions[session_id] = Session(session_id)

        sess: Session = sessions[session_id]

        ans = sess.ask(question)

        # save to database
        ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR') or "unknown"

        with dblock:
            db.execute('INSERT INTO queries (ip, question, answer) VALUES (?, ?, ?)', (ip, question, ans))
            db.commit()

        resp['response'] = ans

        return jsonify(resp)
    except Exception as e:
        traceback.print_exc()
        logger.error(f'Error: {e}', exc_info=True)
        # 若为新创建的Session,异常时删除避免内存泄漏
        if new_session_created and session_id in sessions:
            del sessions[session_id]
            logger.info(f'Deleted new session {session_id} due to error')
        return jsonify(dict(type="error", error=f"server error occured, check logs."))

4. 生产环境替换Flask内置服务器

Flask默认开发服务器内存管理和并发能力有限,建议改用gunicorn等生产级服务器,配合进程数限制控制内存:

# 安装gunicorn
pip install gunicorn
# 启动服务器(限制为4个工作进程)
gunicorn --workers 4 --bind 0.0.0.0:5000 your_app_module:app

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:54:53