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

沈晟 · · 1486 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

近日在高负载时使用 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 爱好者不要重蹈我的覆辙。


有疑问加站长微信联系(非本文作者)

本文来自:新浪博客

感谢作者:沈晟

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

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1486 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传