- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
导读
本文以 TEN Framework 开源仓库中的 Go 示例应用pprof_app_go为主线,系统讲解如何为 TEN Framework Go 应用接入 Go 标准库runtime/pprof与net/http/pprof能力,实现运行时的堆内存(heap)周期性采样与在线剖析服务。文章将完整还原该示例应用的可执行逻辑、环境变量配置、构建打包方式,并配套介绍仓库自带的堆剖析数据分析脚本,帮助读者快速搭建一套可落地的 Go 应用内存性能分析工作流。
概述:TEN Framework 的 Go 剖析示例应用
pprof_app_go是 TEN Framework 仓库中的一个Go 语言 app 类型示例包,其官方定位是 "TEN Framework Go application with pprof profiling support for performance analysis",即一个内置 pprof 性能剖析支持的 TEN Framework Go 应用,用于对运行中的 Go 应用(尤其是堆内存占用)进行性能分析。该示例展示了两类剖析手段的组合:
- 在线剖析服务器:通过环境变量
TEN_PROFILER_SERVER_PORT启动net/http监听,提供 Go 标准pprof调试端点; - 周期性堆采样:通过
TEN_HEAP_DUMP_DIR与HEAP_PROFILE_TIME_INTERVAL两个环境变量,驱动runtime/pprof.WriteHeapProfile按固定时间间隔把堆内存快照落盘。
在仓库中,该应用位于 packages/example_apps/pprof_app_go,配套的剖析数据分析工具位于 tools/profiler/pprof,两者共同构成一套从“数据采集”到“数据解读”的完整链路。
特性
- 以 TEN Framework Go 应用(app)形态存在,可作为 TEN 应用的运行入口直接复用;
- 通过标准库
runtime/pprof实现堆内存剖析,不引入第三方剖析依赖; - 剖析行为完全由环境变量驱动,无需改代码即可按需开关;
- 支持两种数据获取方式:
go tool pprof在线访问剖析端点、周期性落盘heap_<timestamp>.out文件; - 仓库自带 Python 脚本,可将堆积的 heap 文件批量转换为文本或汇总成 Excel 报表。
应用结构与入口逻辑解析
该应用的完整 Go 源码仅一个文件 main.go,核心结构如下:
defaultApp结构体:内嵌ten.DefaultApp(来自ten_framework/ten_runtime绑定),并持有stop chan struct{}用于优雅停止剖析协程;new():应用实例工厂;OnInit/OnDeinit:TEN Framework 应用生命周期回调,分别负责启动剖析逻辑与停止剖析协程;dumpHeap():封装pprof.WriteHeapProfile的堆快照落盘函数;main():创建应用实例、Run(true)启动并Wait()等待退出。
入口代码如下(main.go):
func main() { appInstance, err := ten.NewApp(new()) if err != nil { fmt.Println("Failed to create app.") } appInstance.Run(true) appInstance.Wait() }从源码结构看,该应用直接复用了 TEN Framework 的 Go 绑定接口ten.NewApp,并通过manifest.json声明了对系统包ten_runtime与ten_runtime_go的依赖(版本 0.11.73,见 manifest.json),因此它既可以作为示例独立运行,也可以作为编写自研 Go 剖析应用的模板。
环境变量驱动的剖析开关
剖析能力是否启用完全由三个环境变量决定,这是该示例最值得复用的设计。三者的语义与默认行为如下:
| 环境变量 | 作用 | 生效条件 | 说明 |
|---|---|---|---|
TEN_PROFILER_SERVER_PORT | 指定 pprof 在线剖析服务监听端口 | 变量非空即生效 | 底层通过http.ListenAndServe(":<port>", nil)启动默认 HTTP mux,可访问/debug/pprof/系列端点 |
TEN_HEAP_DUMP_DIR | 指定堆快照文件输出目录 | 需与HEAP_PROFILE_TIME_INTERVAL同时非空 | 程序会在该目录下自动创建go子目录,堆文件写入<dir>/go/heap_<unix时间戳>.out |
HEAP_PROFILE_TIME_INTERVAL | 堆快照采样间隔(秒) | 需与TEN_HEAP_DUMP_DIR同时非空 | 通过time.Ticker实现周期触发;解析失败或<= 0会被判定为非法并跳过 |
对应的启动逻辑位于 main.go 的OnInit中:应用初始化完成(OnInitDone())后,在一个独立 goroutine 内读取环境变量并分别启动 HTTP 剖析服务与周期堆采样循环。
这里有一个值得注意的实现细节:堆采样循环中若目录创建失败仅打印错误、不中断,且一旦HEAP_PROFILE_TIME_INTERVAL非法会直接return,因此三个变量的组合使用需要使用者自行保证正确性。仓库配套的 tools/profiler/pprof/README.md 给出了标准用法:
# Heap profiles will be stored in /data/prof export TEN_HEAP_DUMP_DIR=/data/prof # The heap profile will be dumped every 30 seconds export HEAP_PROFILE_TIME_INTERVAL=30 # The pprof server will listen on port 6060 export TEN_PROFILER_SERVER_PORT=6060堆剖析的底层实现:WriteHeapProfile 与 Ticker 采样
周期性堆采样由dumpHeap函数与time.Ticker协同完成(main.go):
func dumpHeap(heapDumpDir string) error { timestamp := time.Now().Unix() heapFile, err := os.OpenFile( fmt.Sprintf(heapDumpDir+"/heap_%d.out", timestamp), os.O_CREATE|os.O_RDWR, 0644, ) if err == nil { pprof.WriteHeapProfile(heapFile) heapFile.Close() } return err }关键点:
- 文件名以 Unix 时间戳命名(
heap_<timestamp>.out),保证多次采样的文件天然按时间有序,便于后续按时间序列分析内存增长趋势; - 首次启动时立即 dump 一次基线快照,之后由
time.NewTicker(interval * time.Second)按固定间隔持续采样; - 应用退出时(
OnDeinit),通过p.stop <- struct{}{}通知剖析协程通过 select 退出循环,避免 goroutine 泄漏(main.go)。
同时,当设置了TEN_PROFILER_SERVER_PORT时,应用会启动一个纯 Go 的 HTTP 服务(main.go)。由于http.ListenAndServe默认使用http.DefaultServeMux,而 Go 的net/http/pprof包在 init 时已向该 mux 注册/debug/pprof/等端点,因此可在线执行:
go tool pprof http://localhost:6060/debug/pprof/heap构建与打包:BUILD.gn 与 Go module
该应用通过 TEN Framework 的 GN 构建系统打包为app类型的 TEN 包(BUILD.gn):
package_kind = "app"声明包类型;resources收集main.go、manifest.json、property.json、LICENSE以及文档目录,并将go_release.mod重命名为go.mod随包发布;deps依赖//core/src/ten_runtime/binding/go,即 TEN Framework 的 Go 运行时绑定;- 在启用
ten_manager的构建中,会额外生成上传任务upload_pprof_app_go_to_server,将产物上传到 TEN 包服务器。
本地开发时,go.mod 通过replace ten_framework => ../../ten_runtime/binding/go/interface指向框架的 Go 绑定源码,便于直接以源码方式调试;发布版本则改用 go_release.mod 中的replace ten_framework => ./ten_packages/system/ten_runtime_go/interface,在安装后的 TEN 应用目录内解析运行时依赖。property.json为空对象{},即该应用本身不需要额外配置属性。
安装方式遵循 TEN Framework 包安装指南(可通过tman从包服务器安装该 app,或按照仓库中其他 example app 的流程集成),安装后作为 TEN 应用的启动入口运行即可。
剖析数据分析工具链
采样只是第一步,仓库在 tools/profiler/pprof 下提供了完整的 heap 文件分析脚本,对 pprof_app_go 产出的.out堆文件做二次加工:
批量转文本:dump_heap_files_to_text.py
dump_heap_files_to_text.py 遍历--heap-dir下所有.out文件,调用go tool pprof -text <heapFile>生成可读的文本报告(写入--text-dir),便于人工或脚本化检查内存分配热点:
python3 dump_heap_files_to_text.py -heap_dir=/data/prof -text_dir=/data/text底层命令构造见 utils/pprof_cmd.py,其中还封装了go tool pprof -http=:<port>用于在浏览器中可视化堆剖析结果:
def convert_heap_to_text_cmd(heapFile, textFile): return f"go tool pprof -text {heapFile} > {textFile}" def show_heap_in_browser_cmd(port, heapFile): return f"go tool pprof -http=:{port} {heapFile}"汇总 Excel 报表:dump_heap_info_to_excel.py
dump_heap_info_to_excel.py 在转文本的基础上,调用 utils/get_total_bytes.py 用正则从 pprof 文本的TOTAL行解析出堆总大小,并按采样间隔推算时间轴,最终用 openpyxl 生成含index / time/s / heap_file_name / text_file_name / total_heap_size/MB五列的 Excel 表格,用于观察堆内存随时间的变化曲线:
python3 dump_heap_info_to_excel.py -heap_dir=/data/prof -output=/data/heap.xlsx其中--sample-interval默认 30 秒,需与HEAP_PROFILE_TIME_INTERVAL保持一致才能得到准确的时间轴;单位换算逻辑(B/KB/MB/GB)集中在 get_total_bytes.py。
实战工作流:从采集到定位内存问题
综合上述组件,一套完整的 Go 应用内存剖析工作流可以归纳为:
- 采集:以 pprof_app_go(或基于其改造的应用)作为 TEN 应用启动,导出
TEN_HEAP_DUMP_DIR=/data/prof、HEAP_PROFILE_TIME_INTERVAL=30,让应用按 30 秒间隔持续落盘堆快照;如需在线分析,同时导出TEN_PROFILER_SERVER_PORT=6060; - 在线探查:运行
go tool pprof http://localhost:6060/debug/pprof/heap,或使用show_heap_in_browser_cmd提供的-http方式在浏览器中查看调用图、火焰图; - 批量分析:采样结束后,用
dump_heap_files_to_text.py将全部.out转为文本,用grep/编辑器对比不同时刻的分配热点差异; - 趋势汇总:用
dump_heap_info_to_excel.py生成堆大小时间序列报表,定位内存持续增长(疑似泄漏)的时间窗口,再回到对应时间点的文本报告排查具体分配调用栈。
需要说明的适用前提:该方案剖析的是Go 运行时侧的内存(含 TEN Framework Go 绑定层),适用于定位 Go 代码中的内存分配热点与增长趋势;若需分析 C 侧(ten_runtime 核心)的内存,则属于另一套工具链(仓库另提供 tools/profiler/gperftools 等方向),不应混淆。
许可证
本示例包是 TEN Framework 项目的一部分,代码头部与包内 LICENSE 均声明采用 Apache License 2.0 开源许可,可直接在遵循该许可的前提下复用、修改其剖析逻辑。
- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
相关推荐
TEN Framework 性能剖析实践:PProf Go App 应用详解与 Go pprof 集成指南
TEN Framework 性能剖析实践:PProf Go App 应用详解与 Go pprof 集成指南 导读 本文聚焦 TEN Framework 仓库中
人工智能AI Agent多模态语音AI 应用CANN/asc-devkit Compare函数API文档
Compare<a name="ZH CN_TOPIC_0000001929827672" </a 产品支持情况<a name="section15505324
人工智能AI Agent多模态语音AI 应用gRPC-Go性能分析:CPU剖析与内存剖析工具
gRPC Go性能分析:CPU剖析与内存剖析工具 痛点:为什么你的gRPC服务性能总是不达标? 还在为gRPC服务性能瓶颈而苦恼?面对复杂的分布式系统,传统的性
后端RPC框架
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考