wdserver程序运行一段时间就阻塞了
查看日志没有报错
磁盘和内存正常
查看日志最后打印的位置,在这行日志的后面,有个获取redis连接的地方,很可能是这里阻塞了
通过golang的工具,pprof,可以看到一个goroutine的信息
1 @ 0x42ed6c 0x42ee5e 0x441880 0x4642a0 0x70128e 0x7005ff 0x7ae460 0x45d741
# 0x44187f sync.runtime_notifyListWait+0x10f /data/jenkins/tools/org.jenkinsci.plugins.golang.GolangInstallation/go19/src/runtime/sema.go:507
# 0x46429f sync.(*Cond).Wait+0x7f /data/jenkins/tools/org.jenkinsci.plugins.golang.GolangInstallation/go19/src/sync/cond.go:56
# 0x70128d github.com/garyburd/redigo/redis.(*Pool).get+0x74d /data/jenkins/workspace/src/github.com/garyburd/redigo/redis/pool.go:326
# 0x7005fe github.com/garyburd/redigo/redis.(*Pool).Get+0x2e /data/jenkins/workspace/src/github.com/garyburd/redigo/redis/pool.go:181
# 0x7ae45f kafka.doState+0x43f /data/jenkins/workspace/src/wdserver/src/kafka/kafka.go:323
可以看到有wait,初步判断是这里阻塞了
最终的原因是redis连接没有关闭,在一个for循环里用了defer关键字,函数没有结束,连接就不会关闭
tcp连接会自动关闭
因为连接没有使用,被垃圾回收了
批量调用一个接口,会导致cpu占满,goroutine也有很多
出现这个原因是:请求的接口(login),响应body有数据,我在程序中没有关闭。但是我在另一个接口(register)中没有出现这个问题,这是因为这个接口的响应body没有数据。HTTP底层会建立一些goroutine来用于HTTP请求,如果不关闭这个body,这些goroutine也不会释放。所以无论如何,调用了接口就应该关闭body。