systemd 守护的一个使用golang 实现的tcp服务,
这个服务使用了github.com/jinzhu/gorm ,每隔一小时 服务就会被重启一次,毫无头绪,无从下手,哪位大神可指点指点,怎么排查
如果不确定是不是未捕获的panic导致的话。加个环境变量GOTRACEBACK=crash后运行。这样崩溃后会产生croedump。然后用gdb或dlv还原现场。注意崩溃时内存占用大小,这个和croedump大小有关。
如果不是panic,那么通过dmesg查看系统日志
#10
更多评论
在容易出错的地方要加上容错的机制,使用panic recover机制抓住错误信息就可以定位问题在哪里,然后再解决问题。
个人觉得常出错的地方有使用了nil的数据、数组越界了是最常见的,另外还有一些不容易发现的比如没有关闭链接之类的。
最好是能上源码,如果不关乎行业机密的话。
#1
panic 在日志里没有发现,有,我写个伪代码吧
```golang
func main() {
for {
conn, e := ln.Accept()
if e != nil {
if ne, ok := e.(net.Error); ok && ne.Temporary() {
logger.Init("异常").Info("接收错误信息:%v" + fmt.Sprintf("accept temp err: %v", ne))
continue
}
}
// 解析连接消息 路由模式开启
go goHandleConn(conn)
}
}
func goHandleConn(conn net.Conn) {
defer func() {
if conn != nil {
conn.Close()
}
if err := recover(); err != nil {
//获取程序名称
appExeName := os.Args[0]
pid := os.Getegid()
logger.Init("POSP中台").Error("goHandleConn:引发panic异常",
zap.Reflect("error", err),
zap.Reflect("app", appExeName),
zap.Reflect("pid", pid),
zap.Reflect("strack", string(debug.Stack())),
zap.Reflect("LogId", logId),
)
notice.NoticeMsg("goHandleConn:引发panic异常", fmt.Sprintf("LogId:%s %v:app:%v:pid:%v:strack:", logId, err, appExeName, pid, string(debug.Stack())))
}
return
}()
// todo 查询数据库 这个地方用到gorm
_, err = conn.Write(recBuf)
return
}
```
#2