生产环境如何追踪 Go Panic(无需重启应用)
OpenResty XRay 基于非侵入式动态追踪技术,无需重启或重新编译即可追踪生产环境中 Go 应用的 panic,包括导致进程崩溃的 panic 和被捕获、不会崩溃的 panic。它会自动解读 Go 语言级别的异常火焰图,精确定位抛出 panic 的具体代码路径,并将性能开销降到最低,适合对延迟敏感的生产环境。
本教程将演示如何使用 XRay 的引导式分析(Guided Analysis)功能,在一个真实的 Go 应用中追踪 panic——从启动分析到查看自动生成的报告。
用 XRay 引导式分析追踪 Go Panic
打开 XRay 控制台并运行 Go Panic 引导式分析
本文将演示如何线上分析任意正在运行的 Go 应用中的程序异常,或者说 panic。我们使用的是 Linux 发行版自带的未经修改的 Go 编译器。
目标 Go 程序是使用普通的 go build 命令编译的。不需要做任何更改,无需添加任何特殊选项。
在浏览器中打开 OpenResty XRay 的 Web 控制台。
确保当前分析的机器是正确的。
如果不对,我们可以在下面的列表重新选择。
进入 “Guided Analysis” 页面。
这里可以看到系统能分析的不同类型的问题。
选择 “Errors & exceptions”。
点击 “Next”。
选择之前的 Go 应用。
选择之前的目标进程。
确保应用的类型是正确的。通常默认值就是对的。
这里的语言级别就只有 “Go” 了。
我们还可以设置最长的分析时间。这里保持默认的 300 秒不变。
开始分析。
系统将持续执行多轮分析。目前它正在运行第一轮分析。
第一轮分析已经完成,现在进入第二轮。对这个例子来说,运行一轮分析就够了。
停止分析。
追踪第一个 Go Panic:gopanic 引发的除零错误
可以看到自动生成了一份分析报告。
这是我们要分析的问题类型,“Errors & exceptions”。
看一下第一条抛出异常的 Go 代码路径。
Go 最终会通过其运行时的 gopanic 函数抛出异常。
在这条代码路径中,gopanic 函数由运行时的 panicdivide 函数调用。意味着这是一个除零错误。
根据调用上下文,是函数 calculate 抛出了程序异常。这个函数属于业务层面的代码。
handleHTTPRequest 函数属于 golang 的 Gin 这个 Web 框架。该函数负责处理传入的 HTTP 请求。
点击 “More”。
这条热代码路径是从这个 Go 级别的异常火焰图自动推导出来的。
下面是对问题更详细的解释和建议。它提到了上面的程序异常,是由除零错误引起的。
这是一个能修复这个错误的代码示例。
回到原始的热代码路径。将鼠标悬停在 calculate 函数的绿框上。
在提示框中可以看到这个函数的源文件名和完整路径。
这行源码的行号是 25。
点击这个图标,复制这个函数的源文件路径。
用 vim 编辑器打开源文件。粘贴我们刚才复制的文件路径。您可以使用任何您喜欢的编辑器。
正如 OpenResty XRay 建议的那样跳转到第 25 行。
如我们刚刚在代码路径看到的,这行代码正是在 calculate 函数内部。我们应该先检查除数 b 是否为零。
追踪第二个 Go Panic:goPanicIndex 引发的数组越界
接下来,查看第二条抛出程序异常的代码路径。
这是和上面类似的 gopanic 函数。
goPanicIndex 函数也属于 Go 的标准运行时。在这条代码路径中,这个程序异常是由运行时的 goPanicIndex 函数触发的。
可能是这个 weekday.Handler 函数中的数组或切片索引发生了越界访问。这个 Go 函数是业务代码级别的。
将鼠标悬停于这个函数上方,在提示框中可以看到它的源文件路径。
这行源码的行号是 17。
复制它的源文件路径。
在终端上打开源文件。粘贴刚才复制的文件路径。
跳转到第 17 行。可以看到,确实是在通过索引访问数组元素。
这个数组变量名为 weekDays。
该函数没有确认索引变量 i 的值范围。
而这个 i 变量可以从客户端请求中获取任意整数值。
无需引导式分析:Go Panic 自动报告
OpenResty XRay 也可以自动监控在线进程,并生成分析报告。
切换到 “Insights” 页面。
您可以在 “Insights” 页面中找到以日和周为周期的自动报告。其实您不是非得用 “Guided Analysis” 功能。
当然,“Guided Analysis” 对于应用的开发和演示是很有用的。
常见问题
Q: OpenResty XRay 是如何在不重启应用的情况下检测 Go Panic 的?
A: XRay 基于非侵入式动态追踪技术——底层由 Y 语言驱动,支持 Stap+、eBPF+、GDB 等多种运行时——从进程外部观测正在运行的、未经修改的 Go 进程。不需要任何特殊编译选项或重新编译,普通 go build 生成的二进制文件即可直接使用。
Q: 已经被捕获、不会导致崩溃的 Go panic,XRay 还能检测到吗? A: 可以。即使 panic 被捕获、不会导致进程崩溃,XRay 仍能检测到,暴露出大多数基于日志的方案会漏掉的代码路径。
Q: gopanic 是什么,它如何帮助追踪 Go panic?
A: gopanic 是 Go 运行时中所有 panic 最终都会经过的函数。它的调用者——比如除零错误对应的 panicdivide,数组越界对应的 goPanicIndex——在你查看业务代码之前,就已经告诉你这是哪一类 panic。
Q: 不运行引导式分析,要怎么查看 Go panic 报告? A: XRay 控制台的 “Insights” 页面会自动生成日报和周报,不需要每次都手动跑一次引导式分析。
关于 OpenResty XRay
OpenResty XRay 是一个动态追踪产品,它可以自动分析运行中的应用,以解决性能问题、行为问题和安全漏洞,并提供可行的建议。在底层实现上,OpenResty XRay 由我们的 Y 语言 驱动,可以在不同环境下支持多种不同的运行时,如 Stap+、eBPF+、GDB 和 ODB。
关于作者
章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。
章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴, 是 “边缘计算“、”动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用动态追踪技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl 等,并编写过 60 多个开源软件库。
关注我们
如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:
翻译
我们提供了英文版原文和中译版(本文)。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!






































































