golang 线程创建失败
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
简要描述
接了个报警,一个后台服务挂了,看了下 nohup 打出来的日志,发现线程创建过多,资源分配不过来,进程直接被杀死了。
问题分析
分析了一下日志
crontab服务正在启动,PID: 12123 ,时间: 2021-01-01 15:00:00
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
goroutine 0 [idle]:
goroutine 1 [chan receive, 40 minutes]:
pkg/graceful.WaitExit()
pkg/graceful/grace.go:36 +0x97
main.main()
/main.go:106 +0x86f
goroutine 19 [syscall]:
goroutine 34 [syscall]:
goroutine 36 [syscall]:
...
结论
其实很明显能看到,大量线程陷入系统调用,可能是io读写、网络请求之类的接口性能很差,导致线程回收不及时,新起的线程无法分配到资源,导致上述的问题。
然后根据日志,具体计算了一下打的最频繁的日志
cat nothup.out | sort | uniq -c | sort -n -r | head -n 10
# ...
# 289 growingio/upload.go:117 +0x437
# 289 syscall/zsyscall_linux_386.go:473 +0x3d
# 289 src/syscall/asm_linux_386.s:20 +0x5
# 289 /src/os/file_posix.go:127 +0x3d
# ...
大概发现是 growingio 的问题,大概率是服务商挂了,导致接口请求迟迟未响应,应用层面又喜欢用协程,资源耗尽也正常。
golang 虽然号称上万协程没问题,但是如果每个协程都是在做系统调用、网络调用,那还是很危险的,linux 对文件句柄开始有挺多限制的。