Golang Go语言压测程序异常退出

发布于 1周前 作者 nodeper 来自 Go语言

我正在写一个 TCP 长连接网关的压测代码,在 client 与 server 建立了 6w 个 conn 后,运行几分钟时间后 client 就异常退出了,没有 panic ,但控制台打印了很多下面的堆栈信息:

goroutine 119057 [sleep]:
time.Sleep(0x77359400)
        C:/Users/Administrator/sdk/go1.19.7/src/runtime/time.go:195 +0x13c
command-line-arguments.runOneConn(0xc0004ded00, 0xc0008f4b18, 0xc0008f4b10, 0xea60, {0x8c2c91?, 0xc02a8a1fb0?, 0x1cff060?})
        D:/dev_bg/server/src/gateway/main_test.go:201 +0x24d
command-line-arguments.TestTCPServer.func2(0x0?)
        D:/dev_bg/server/src/gateway/main_test.go:120 +0x8a
created by command-line-arguments.TestTCPServer
        D:/dev_bg/server/src/gateway/main_test.go:110 +0x1a6

goroutine 118925 [sleep]: time.Sleep(0x77359400) C:/Users/Administrator/sdk/go1.19.7/src/runtime/time.go:195 +0x13c command-line-arguments.runOneConn(0xc0004ded00, 0xc0008f4b18, 0xc0008f4b10, 0xea60, {0x8c2c91?, 0xc024cc3fb0?, 0x1cff060?}) D:/dev_bg/server/src/gateway/main_test.go:201 +0x24d command-line-arguments.TestTCPServer.func2(0x0?) D:/dev_bg/server/src/gateway/main_test.go:120 +0x8a created by command-line-arguments.TestTCPServer D:/dev_bg/server/src/gateway/main_test.go:110 +0x1a6

…重复的堆栈信息

想请教一下如何排查这个问题,server 端是没有 err 的,server 和 client 都运行在一台机器上。


Golang Go语言压测程序异常退出

更多关于Golang Go语言压测程序异常退出的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

15 回复

单个系统内,client 最大理论发起 65535 ,异常信息应该是没有端口可用

更多关于Golang Go语言压测程序异常退出的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的预期就是 6w 个 conn ,全部连接成功了的,排除这个原因

这个堆栈看不出什么有用信息

我开始推断是 panic ,判断也许是因为输出太多覆盖了,加入了 panic 时写入文件的代码,但实际也没有触发此逻辑,说明也没有 panic 。但输出就是这个,我也懵,想知道有没有其他排查方式

出错的时候,最上面的栈信息应该有用,你可以翻到最上面看一下。

#5 看不到了,输出太多了

准备把 stdout 定向到文件

#2 大概率还是端口的问题,你如果没有修改过的话,可用端口号都是从 3w 多开始的,所以理论上用户可用的端口只有 3w 多

看看系统日志? /var/log/message ,是不是被系统强制 kill 了?

“从 3w 多开始” 这个你有什么根据吗?

#10 关键字 windows 动态端口

#10 之前没注意看,还以为你是 linux 。windows 的默认就更小了,你可以在 powershell 查看: netsh int ipv4 show dynamicport tcp 。默认应该是从 49152 到 65535 。

#12

<br>(venv) PS D:\dev_bg\server&gt; netsh int ipv4 show dynamicport tcp<br><br>协议 tcp 动态端口范围<br>---------------------------------<br>启动端口 : 1024<br>端口数 : 64511<br>

我改过了,所以真不是这个问题。


#3
#5

#8

查到原因了。通过 在 go test 命令加 stdout/stderr 重定向到文件的指令,把信息保存下来了,在首次爆出堆栈的位置看到了原因是 触发了 go test 的默认运行 10m 超时机制 panic ,这个不是测试代码的问题,所以可以忽略了。

针对您提到的Golang压测程序异常退出的问题,这里有几个可能的解决方向和检查点:

  1. 内存管理:Go语言虽然拥有自动垃圾回收机制,但在高并发或大量数据处理的压测场景下,内存泄漏或过度分配仍可能导致程序崩溃。建议检查代码中是否存在未关闭的goroutine、泄露的channel或未释放的大内存对象。

  2. 并发控制:Go的并发模型强大,但不当的并发控制(如竞态条件、死锁)也可能导致程序异常。使用sync包中的工具(如Mutex、WaitGroup)确保数据访问的同步性,并留意可能的死锁情况。

  3. 错误处理:确保所有可能的错误路径都被妥善处理。在压测中,一些边缘情况可能更频繁地触发错误,未被捕获的错误会导致程序崩溃。

  4. 资源限制:检查系统资源限制,如文件描述符数量、CPU和内存使用限制。压测时可能会触及这些限制,导致程序被系统强制终止。

  5. 日志与监控:增强日志记录,特别是在压测开始和结束阶段,以及可能的异常点。使用监控工具跟踪程序运行时的资源使用情况,帮助定位问题。

  6. 复现与简化:尝试简化压测脚本和程序逻辑,逐步排除问题区域。如果可能,使用更小的数据集或降低并发级别来复现问题,便于调试。

希望这些建议能帮助您定位和解决问题。如果需要更具体的帮助,提供详细的错误日志和代码片段将非常有助于进一步分析。

回到顶部