尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

深度解析 DeepFlow 如何采集大模型服务的业务指标:从 eBPF 到 Wasm 的配置骨架

发布时间:2026/9/26 3:47:30

资讯中心
01
ARTICLE

深度解析 DeepFlow 如何采集大模型服务的业务指标:从 eBPF 到 Wasm 的配置骨架

深度解析 DeepFlow 如何采集大模型服务的业务指标:从 eBPF 到 Wasm 的配置骨架
1. 大模型服务为什么需要业务指标采集大模型服务上线之后基础设施层面的 CPU、内存、网络吞吐这些指标通常很快就能接上但真正让运维和研发头疼的是业务侧的可观测性。你可能会遇到这样的场景客服大模型调用基础模型时用户反馈“回答变慢了”但看 CPU、内存、网络都正常问题到底出在哪一段是首 Token 生成慢了还是每个 Token 的输出节奏变慢了这些信息传统监控给不出来。大模型服务的调用链路和普通微服务不太一样。普通 HTTP 接口的响应时延基本能反映用户体验但大模型走的是流式输出一次请求的响应时间被拆成了很多个分块用户感知的“快慢”其实取决于两个关键指标TTFTTime To First Token首 Token 生成时间和 TPOTTime Per Output Token每个输出 Token 的生成时间。TTFT 决定了用户等待第一句话的时间TPOT 决定了后续内容吐出的流畅度。这两个指标如果采集不到优化就无从下手。问题在于大模型应用往往跨多个云、多个基础模型供应商团队之间职责边界清晰业务团队通常不允许在容器里装 APM 探针传统侵入式方案推不动。这时候 eBPF 的价值就体现出来了它可以在内核层面抓取网络流量对业务进程零侵扰。但 eBPF 原生只能解析到协议层对于 HTTP Chunked 流式响应里的 Token 级信息它看不懂。于是 Wasm 插件就成了补齐这最后一公里的关键用 eBPF 拿到流量用 Wasm 插件解析业务语义两者协作才能把 TTFT、TPOT、Token 产出率这些业务指标算出来。这篇文章会从实际配置出发给出 DeepFlow Agent 侧可复制的配置片段、Wasm 插件的挂载骨架以及如何通过 TaoToken 统一 Key/API 通道接入大模型服务后用请求量、时延、Token 消耗做一次端到端验证。适合正在做 LLM 可观测性、或者被流式接口指标采集卡住的工程师。2. TaoToken 前置统一 Key 与 API 通道在讲 DeepFlow 配置之前先说一下大模型服务接入侧的事情。因为要做端到端验证你总得有一个稳定的大模型 API 入口来产生流量。很多团队在测试阶段会同时对接多个模型供应商Key 管理混乱请求地址不统一导致 DeepFlow 采集到的流量来源五花八门指标对比困难。我试过用 TaoToken 来做统一入口它提供 OpenAI 兼容的 API 通道你可以把不同模型的调用都收敛到同一个 Base URL 和同一套 Key 体系下。这样 DeepFlow Agent 在抓取流量时看到的请求路径、Header 结构是一致的Wasm 插件解析逻辑不用为每个供应商写一套适配。具体操作上你需要在 TaoToken 控制台创建一个 API Key然后拿到统一的 API 地址。模型对话调试可以直接在网页端做确认 Key 可用长期跑编码或 Agent 场景的话可以看下 Coding Plan 的额度方式。接入文档里有各语言 SDK 的 Base URL 替换示例这里不展开。关键点是把大模型服务的出口统一到 TaoToken 的 API 通道后你的 DeepFlow 采集点只需要面对一种请求格式。请求量、时延、Token 消耗这些指标在 Grafana 上做聚合时不会因为供应商不同而出现维度爆炸。后面第 4 节的验证请求也是基于这个通道来发。3. DeepFlow Agent 配置与 Wasm 插件挂载骨架3.1 Agent 侧基础配置DeepFlow Agent 通常以 DaemonSet 方式部署在 Kubernetes 集群里负责 eBPF 数据采集和 Wasm 插件加载。你需要确认 Agent 的配置文件里开启了 Wasm 插件支持并且指定了插件分发路径。以下是一个可复制的 ConfigMap 片段重点在wasm相关字段apiVersion: v1 kind: ConfigMap metadata: name: deepflow-agent-config namespace: deepflow-system data: deepflow-agent.yaml: | controller: endpoints: - 10.0.0.100:30035 agent: # 开启 eBPF 采集 ebpf: enabled: true # 采集模式根据内核版本选择 collector: auto # Wasm 插件配置 wasm: enabled: true # 插件从 server 下发后的本地缓存目录 plugin_dir: /var/lib/deepflow/wasm # 单个插件内存上限防止解析大流量时 OOM max_memory_bytes: 67108864 # 插件执行超时单位毫秒 timeout_ms: 50 # 日志级别调试插件时开到 debug log_level: info这里有几个参数需要根据实际情况调整。max_memory_bytes默认可能偏小大模型流式响应分块多插件里维护的httpStreammap 会随并发流数量增长建议至少给到 64MB。timeout_ms如果设得太短插件在解析大响应体时可能被中断导致指标丢失50ms 是一个比较稳的起点。3.2 Wasm 插件挂载与编译DeepFlow 的 Wasm 插件用 TinyGo 编写编译成 Wasm 二进制后通过deepflow-ctl上传到 Server再由 Server 下发给 Agent。整个过程不需要重启 Agent 服务热插拔生效。编译命令如下注意-target wasi和-schedulernone是必须的因为插件运行在沙箱里不需要 Go 的调度器tinygo build -o llm.wasm \ -target wasi \ -gcprecise \ -panictrap \ -schedulernone \ -no-debug \ ./llm/llm.go上传插件到 DeepFlow Serverdeepflow-ctl plugin create \ --type wasm \ --image llm.wasm \ --name llm \ ./llm/llm.go查看已上传插件列表确认状态是enableddeepflow-ctl plugin list插件挂载的核心逻辑在代码的HookIn方法里它告诉 eBPF SDK 在哪个钩子点调用插件。大模型流式解析需要挂载在HOOK_POINT_PAYLOAD_PARSE也就是 payload 解析阶段func (p *llmParser) HookIn() []sdk.HookBitmap { return []sdk.HookBitmap{ sdk.HOOK_POINT_PAYLOAD_PARSE, } }OnCheckPayload负责判断这个流量是不是大模型流式请求。实际生产里不同供应商的流式接口路径不一样比如 vLLM 常用/generate_streamOpenAI 兼容接口可能是/v1/chat/completions且带stream: true。你可以在checker函数里根据路径或 Header 做匹配func checker(payload []byte) (protoNum uint8, protoStr string) { req, err : http.ReadRequest(bufio.NewReader(bytes.NewReader(payload))) if err ! nil { return 0, } query : req.URL.Path // 匹配流式接口路径可按实际供应商扩展 if strings.Contains(query, /generate_stream) || strings.Contains(query, /v1/chat/completions) { return 1, http_stream } return 0, }OnParsePayload是计算 TTFT 和 TPOT 的主逻辑。它按方向处理请求方向记录reqTime响应方向逐块读取 Chunked 数据第一个带 Token 的块记录respFirstChunkedTime后续块累加totalToken遇到结束块0时计算差值并写入 L7 协议信息的Kv字段case sdk.DirectionResponse: r : bufio.NewReader(bytes.NewReader(payload)) bs, _, err : r.ReadLine() if err io.EOF { return sdk.ActionNext() } // 跳过 HTTP 状态行 regex : regexp.MustCompile(^HTTP/[1-2]\.[01] \d{3} .*$) if regex.MatchString(string(bs)) { return sdk.ActionNext() } // 结束块计算指标 if string(bs) 0 { attr []sdk.KeyVal{ { Key: ttft, Val: fmt.Sprintf(%d, p.httpStream[flowId].respFirstChunkedTime- p.httpStream[flowId].reqTime), }, { Key: tpot, Val: fmt.Sprintf(%d, (baseCtx.Time-p.httpStream[flowId].respFirstChunkedTime)/ p.httpStream[flowId].totalToken), }, } info : sdk.L7ProtocolInfo{ Req: sdk.Request{}, Resp: sdk.Response{}, Kv: attr, } delete(p.httpStream, flowId) return sdk.ParseActionAbortWithL7Info([]*sdk.L7ProtocolInfo{info}) } // 首个带 Token 的块 if p.httpStream[flowId].flag 0 { p.httpStream[flowId].flag 1 p.httpStream[flowId].respFirstChunkedTime baseCtx.Time p.httpStream[flowId].totalToken uint64(len(bs)) return sdk.ActionNext() } // 后续块累加 Token p.httpStream[flowId].totalToken uint64(len(bs)) return sdk.ActionNext()这里有个细节totalToken用的是字节长度不是真正的 Token 数。因为 Wasm 插件里没法调用 tokenizer用字节长度作为近似值在趋势监控和计费估算上够用但如果要做精确的 Token 计费需要结合模型侧的 usage 字段做校准。这一点在排障章节会再提。4. 验证请求与成功结果配置完成后你需要发一次真实的流式请求来验证指标是否被采集到。用 curl 通过 TaoToken 的统一 API 通道发起请求注意stream参数要打开curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, stream: true, messages: [ {role: user, content: 用一句话解释什么是 eBPF} ] }请求发出后DeepFlow Agent 会在 eBPF 层抓到这段流量Wasm 插件解析 Chunked 响应计算出 TTFT 和 TPOT写入 L7 协议信息。你可以在 DeepFlow 的 Grafana 仪表板里查询这两个指标。如果用的是 DeepFlow 自带的观测面板可以在应用 - 协议视图里筛选http_stream协议查看ttft和tpot的时序曲线。成功的结果表现为请求发出后几秒内Grafana 上出现对应的数据点ttft值在几百毫秒到几秒之间取决于模型和网络tpot值在几十毫秒量级。同时请求量指标复用应用指标的请求速率和 Token 产出率也能在同一个面板里看到。如果ttft有值但tpot为空通常是totalToken为 0 导致除零检查结束块判断逻辑是否被正确触发。端到端验证的完整链路是curl 请求 → TaoToken API 通道 → 大模型服务 → 流式响应 → eBPF 抓包 → Wasm 插件解析 → 指标写入 → Grafana 展示。任何一环断了指标都出不来。5. 本篇常见错排查插件上传后 Agent 没加载。先看deepflow-ctl plugin list里插件状态是否为enabled再看 Agent 日志里有没有llm wasm plugin loaded这行。如果没有检查 Agent 配置里wasm.enabled是否为 true以及plugin_dir目录权限是否可写。Agent 拉取插件有延迟通常几十秒内生效不用重启。TTFT 数值异常大或为负。检查reqTime和respFirstChunkedTime的单位是否一致都是纳秒级时间戳。如果请求和响应跨了不同的 eBPF 事件时间戳可能来自不同时钟源需要确认 Agent 版本是否支持统一时钟。另外如果请求方向没被checker匹配到reqTime为 0算出来的 TTFT 就会是一个巨大的值。TPOT 除零或数值离谱。根因通常是totalToken为 0。检查结束块判断string(bs) 0是否真的命中了。有些服务端在结束块之前会发一个空行ReadLine读到的可能是空字符串而不是0。可以在插件里加日志把每个块的长度打出来确认分块格式。指标在 Grafana 里查不到。确认查询的协议名是http_stream并且时间范围覆盖了请求时间。DeepFlow 的 L7 协议信息写入后需要几秒到十几秒的聚合延迟。如果还是查不到检查 Wasm 插件的OnCheckPayload返回值protoNum必须是非 0 才会进入解析流程。大流量下插件内存增长。httpStreammap 里的条目在流正常结束时会被 delete但如果流异常中断比如客户端提前断开条目会残留。建议在插件里加一个基于时间的清理逻辑或者依赖 Agent 的max_memory_bytes做兜底。生产环境建议把max_memory_bytes设到 128MB 以上。6. 接入与排障资源如果你在配置 DeepFlow Agent 或编写 Wasm 插件时遇到接入问题可以先从 API Key 和接入文档入手确认 TaoToken 通道的请求格式和 Header 是否正确。模型对话页面可以用来快速验证 Key 是否可用避免在 DeepFlow 侧排查时把通道问题误判成采集问题。对于需要长期跑编码或 Agent 场景的团队Coding Plan 提供了更稳定的额度管理方式配合 DeepFlow 的请求量和 Token 消耗指标可以做成本侧的持续观测。控制台里可以查看各 Key 的调用统计和 Grafana 上的指标做交叉验证。排障时优先看 Agent 日志和插件日志log_level开到debug能看到每个 payload 的解析过程。确认插件逻辑没问题后再回到 Grafana 看指标聚合结果。整个链路里eBPF 负责“抓到”Wasm 负责“看懂”两者配合才能把大模型服务的业务指标真正落到可观测性平台上。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。