`
stephen830
  • 浏览: 2964610 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

小心#Golang#官方文档中没有详细说明的陷阱

 
阅读更多

 

 

小心#Golang#官方文档中没有详细说明的陷阱

近日在高负载时使用 Golang 的 sql driver 时碰到泄漏问题,最后终于发现 database/sql 的文档和 Examples 都没有很好的说明下面2个关键点:

一、 每个 Golang 进程只需要 sql.Open() 一次

最 初,想当然的做法是每次有sql请求都先 sql.Open() 。 这实际上是不对的。 database/sql 自己会维护连接池,每次 sql.Open() 会新建一套连接池。虽然不会报错,但是会导致资源浪费。而且我发现在系统资源紧张时会导致锁死的 goroutine 释放不掉, sql.DB.Close() 也未能解决。

二、 每次 Query() 之后,一定要记得 Row.Close() 。

Golang 官方文档的Example完全没有关于 Row.Close() 的代码的。实际上 Query() 之后务必要记得 defer rows.Close()。如果不 Close,这个row就一直保持着与当前 connection pool 中的 sql 连接的依赖关系,连接也就不会被释放。最终导致资源不必要的堆积,甚至崩溃!

rows, err := db.Query("SELECT name FROM users WHERE age=?", age)

if err != nil { log.Fatal(err) }

defer rows.Close() // 文档中没有提及的部分

---- 

上面两种不当使用的情形并不会导致代码报错,但在负载高时就会产生泄漏。祝 #golang 爱好者不要重蹈我的覆辙。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics