NewVFX OpenAI 兼容 API 流式链路取消机制:测试与思考方案”

› 社区话题 › NewVFX OpenAI 兼容 API 流式链路取消机制:测试与思考方案”

6
  • 该话题为空。
正在查看 0 条回复
  • 作者
    帖子
    • #1520

      追光
      管理员

      NewVFX OpenAI 兼容 API 流式链路测试与取消机制方案

      一、测试目标

      本次测试主要验证 NewVFX

      /v1/chat/completions

      流式 API 从客户端发起请求,到 NewVFX 网关、上游模型 API,再返回 SSE 数据的完整链路,并重点解决一个核心问题:

      当客户端主动中断流式连接时,NewVFX 是否能够及时停止当前任务,释放 PHP、cURL 及上游 HTTP 连接,避免多个任务并行导致服务器资源耗尽。

      同时验证

      /v1

      公共入口是否能够正确映射内部

      nvfx-openai/v1

      路由,以及 OpenAI 兼容接口的基本可用性。


      二、完整链路

      当前链路可以概括为:

      客户端 / OpenAI SDK
      →

      https://www.newvfx.com/v1/chat/completions

      → WordPress Rewrite
      →

      nvfx-openai/v1

      → NewVFX API Key 鉴权
      → 模型、计费、审计及 Request ID
      → 流式处理器
      → PHP cURL
      → 上游 LLM API
      → SSE 数据返回
      → 客户端

      其中 NewVFX 实际承担的是统一 AI 算力网关角色,而不是单纯的接口转发。

      请求进入网关后生成

      chatcmpl-*

      类型 Request ID,并建立任务状态。上游产生数据后,由 cURL 接收,再通过 SSE 持续发送给客户端。


      三、第一阶段:公共 API 路由测试

      首先测试:

      /v1/models

      未携带 API Key 时返回

      401 missing_key

      ,说明:

      1. /v1

        已进入 NewVFX API;

      2. API Key 鉴权正常;
      3. 未授权请求不会直接访问模型。

      随后测试

      /v1

      根路径,可以正确返回

      nvfx-openai/v1

      REST 路由信息,并能够看到:

      • models
      • chat/completions
      • embeddings
      • images/generations
      • cancel

      说明公共

      /v1

      与内部 API 路由之间的 Rewrite 已经打通。


      四、第二阶段:流式调用测试

      使用 OpenAI 兼容格式请求:

      POST /v1/chat/completions

      设置:

      • stream: true
      • 指定 NewVFX 已配置模型
      • Authorization Bearer API Key

      实际测试得到 HTTP 200,并能够持续收到 SSE 数据,同时响应中返回:

      X-NVFX-Request-ID: chatcmpl-xxxx

      证明完整的:

      客户端 → NewVFX → 上游模型 → NewVFX → 客户端

      流式链路已经正常工作。


      五、第三阶段:发现并解决中断问题

      最初测试发现:客户端 Ctrl+C 或主动关闭连接以后,PHP 后端仍可能继续执行。

      原因并不是上游模型,而是 PHP 默认的客户端断开处理机制。

      如果 PHP 因客户端断开而提前结束执行,NewVFX 就失去了继续运行取消检测、停止 cURL 的机会。

      因此增加:

      ignore_user_abort(true)

      使 PHP 在客户端断开后仍保持执行,从而能够主动检测连接状态并执行取消逻辑。

      这是整个取消机制能够成立的关键。


      六、最终取消链路

      当前已经形成完整的:

      客户端断开
      →

      connection_aborted()

      → NewVFX 检测到

      CLIENT_DISCONNECT

      →

      AUTO_CANCEL_TRIGGERED

      → 写入取消信号
      → cURL progress callback 检测取消
      → 中止 cURL
      →

      CURL_EXEC_RETURNED

      → 任务以

      aborted / 499

      结算
      → usage / ledger / audit 正常收尾
      → 清理取消状态

      实际日志已经完整证明这一链路。

      测试中:

      • connection_aborted = 1
      • AUTO_CANCEL_TRIGGERED
      • store_ok = 1
      • CURL_PROGRESS_CANCEL
      • curl_errno = 23
      • canceled = 1
      • 最终
        status = aborted
      • HTTP 状态结算为
        499

      其中 cURL

      errno 23

      在这个场景下不是系统故障,而是客户端连接已经关闭后,继续向输出目标写数据失败。由于同时存在

      canceled=1

      和

      client_disconnect

      ,因此属于正常取消结果。


      七、取消机制的边界

      需要明确区分两个层次:

      1. NewVFX 网关层

      这一层已经可以做到通用。

      无论上游是 LM Studio、其他 HTTP LLM 服务,还是未来接入其他 AI API,只要通过 NewVFX cURL 网关访问,当客户端断开后,NewVFX 都可以终止自己的 HTTP 请求和相关 PHP 执行链路。

      2. 上游模型计算层

      NewVFX 无法绝对保证上游模型进程已经停止。

      如果上游服务能够感知 HTTP 连接断开并取消生成,那么模型计算也会停止;如果上游服务本身采用独立异步任务机制,即使 HTTP 连接关闭,模型仍可能继续运行。

      因此 API 文档不能承诺:

      “断开连接必然停止所有模型计算。”

      正确表述应该是:

      NewVFX 会在客户端断开后终止当前上游 HTTP 请求;上游实际模型计算是否同时停止,由上游服务自身的取消机制决定。


      八、最终方案

      NewVFX 采用两级取消设计:

      一级:断开流式连接即取消任务

      这是普通客户端、浏览器、OpenAI SDK 最自然的使用方式,也是默认方案。

      二级:

      POST /v1/cancel

      通过

      request_id

      主动取消任务,用于后台服务、管理系统、异步任务以及无法直接控制原始 HTTP 连接的场景。

      因此最终架构原则是:

      正常情况下:断开流式连接 = 取消当前任务。

      高级场景:使用

      /v1/cancel

      主动取消指定 Request ID。

      本次测试证明 NewVFX 已经从单纯的“API 转发”进一步形成了完整的请求生命周期管理体系:请求、流式传输、客户端状态检测、取消、计量、账本、审计和最终清理均处于同一链路中。

      下一阶段重点应从“能否取消”转向“高并发、异常断网、上游超时、重复取消、进程异常退出以及不同上游服务的取消行为”进行压力测试,以验证整个网关在生产环境下的稳定性。

正在查看 0 条回复
  • 在下方一键注册,登录后就可以回复啦。