Golang中MySQL连接在空闲约6分钟后自动关闭的问题探讨
Golang中MySQL连接在空闲约6分钟后自动关闭的问题探讨 以下是我的操作步骤:
- 在另一个包的 init() 函数中打开数据库连接(比如 “package model”,而不是 “package main”)
var conn *sql.DB
func init() {
// connect to database
dsn := os.Getenv("DB_USERNAME")+":" + os.Getenv("DB_PASSWORD") + "@tcp("+os.Getenv("DB_HOST")+")/"+os.Getenv("DB_DATABASE")
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal("fail to connect to mysql")
}
conn = db
}
- 当需要查询数据库时,我会调用名为
InitSlave()的方法,该方法会执行conn.Ping()
func (m *Model) InitSlave() {
err := conn.Ping()
log.Println("Ping connection successful...")
if err != nil {
log.Fatal(err)
}
m.Slave = conn
}
-
运行应用程序,监听
8080端口,此时访问网站正常 -
如果让应用程序空闲运行 6 到 7 分钟,再次尝试访问,会收到以下消息
operation timeout...
换句话说,无法再次加载网页…
如果我将 conn 声明为全局变量,我认为它会一直存在于内存中。所以每当我访问网站时,它都会向数据库发起查询,然后调用 conn.Ping(),会建立新连接或重用旧连接。我无法理解为什么在空闲几分钟后页面就无法加载了…
感谢帮助!
更多关于Golang中MySQL连接在空闲约6分钟后自动关闭的问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
确实需要看到更多代码才能充分评估这里的情况,例如我们无法看到您的服务函数,因此不知道您的模型类型是如何实例化的,可能还存在其他相关问题。
能否展示更多代码?
更多关于Golang中MySQL连接在空闲约6分钟后自动关闭的问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我猜你的问题来自于使用了conn变量的副本。不要这样做,在你的程序中的每个查询都使用相同的conn变量。
我注意到的问题是,你在模型包中定义了一个通用模型类型下的连接池,但这个对象在创建实例之前实际上并不存在,而且如果它在函数作用域内创建,会被垃圾回收机制处理。
当我处理这种情况时,我会创建一个包装器,将连接指针从主包作为中间件传递给我的处理程序。
这是源代码
我想知道是否应该在每个请求中都调用 sql.Open(),比如在 func main() 中,而不仅仅是在 package model 的 init() 函数中,不太确定,谢谢:)
func main() {
fmt.Println("hello world")
}
不,sql.Open() 应该在 func init() 中只调用一次,以下是文档说明:
// 返回的 DB 可安全地被多个 goroutine 并发使用 // 并维护自己的空闲连接池。因此,Open // 函数应该只调用一次。很少需要 // 关闭 DB。
包装器解决方案看起来不错,我考虑使用它,谢谢 🙂
我发现了这个问题,情况相同。
我通过将最大连接生存时间设置为1分钟来解决这个问题,如下所示:
conn.SetConnMaxLifetime(time.Duration(1) * time.Minute)
这样任何连接都会在1分钟后被移除,而不会对连接池产生重大影响。
conn 是一个 *sql.DB 指针,文档说明:
DB 是一个数据库句柄,代表零个或多个底层连接的连接池。它可以安全地被多个 goroutine 并发使用。
因此 conn 应该始终是指向连接池的指针,并且可以安全地并发使用。
conn 的副本指向相同的内存地址,代表同一个连接池,所以像这样使用应该是安全的,对吗?
谢谢!

