当前位置: 首页 > news >正文

为什么在连接mysql时,设置 SetConnMaxIdleTime 没有作用

目录

  • 测试1
    • go 1.15.15
    • go 1.17.12
  • 测试2
    • go 1.15.15
    • go 1.17.12
  • 参考

在使用golang 连接 mysql时,为了节省连接资源,在连接使用过后,希望在指定长度时间不再使用后,自动关闭连接。
这时,经常会使用SetConnMaxLifetime(),设置最大连接有效时间,
使用SetConnMaxIdleTime(),设置最大空闲连接时间 max idle time。

这两个函数的作用听起来差不多,理论上,都能达到相同效果。
但是在实际使用中,却有些出人意料。

首先看下测试代码,在以下代码中,
设置 max idle time 为传入的参数值,
设置 max life time 为传入的参数值,
设置 max open conn 为1,
设置 max idle conn 为1

package mainimport ("database/sql""log""fmt""os""strconv""time"_ "github.com/go-sql-driver/mysql"
)var dataBase = "root:xxxx@tcp(127.0.0.1:3306)/mysql?timeout=2s&readTimeout=6s&interpolateParams=true"func getVar(name string) int {val := os.Getenv(name)if len(val) == 0 {panic(fmt.Sprintf("error getting: %v", name))}v, err := strconv.Atoi(val)if err != nil {panic(fmt.Sprintf("error parsing %v %v", name, err))}return v
}func main() {db, err :=sql.Open("mysql", dataBase)  // connect to the db of your choice.if err != nil {panic(err)}defer db.Close()db.SetConnMaxIdleTime(time.Second * time.Duration(getVar("MAXIDLE")))db.SetConnMaxLifetime(time.Second * time.Duration(getVar("MAXLIFE")))db.SetMaxIdleConns(1)db.SetMaxOpenConns(1)sleep := time.Second*time.Duration(getVar("SLEEP"))for i := 0; i < 10; i++ {err = db.Ping()if err != nil {log.Fatalln("ping db fail:", err)}time.Sleep(sleep)print("\r", i)}fmt.Printf("\n%+v\n", db.Stats())
}

测试1

MAXIDLE=1 MAXLIFE=0 SLEEP=5 go run .

设置 max idle time 为1s,设置max life time为0s,也就是永不过期,相当于不设置life time。
每次连接之后,sleep 5s。

预期结果,循环10次,每次都会打开一个新的连接,旧的连接由于idle time到期而自动关闭。

go 1.15.15

output

9
{MaxOpenConnections:1 OpenConnections:1 InUse:0 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:0 MaxLifetimeClosed:0}

实际结果,只新建了一个连接,一直在使用,没有关闭连接。
也就是说设置max idle time 并没有生效。

go 1.17.12

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

测试2

MAXIDLE=1 MAXLIFE=2 SLEEP=5 go run .

设置 max idle time 为1s,设置max life time为2s,也就是idle time先到期
每次连接之后,sleep 5s。

预期结果,循环10次,每次都会打开一个新的连接,旧的连接是由于idle time到期自动关闭。

go 1.15.15

output

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

go 1.17.12

output

9
{MaxOpenConnections:1 OpenConnections:0 InUse:0 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxIdleTimeClosed:10 MaxLifetimeClosed:0}

实际结果与预期相符。

总结下,汇总以上测试结果如下表所示:

go版本是否 max idle time是否max life time空闲连接回收是否生效
go 1.15.15YNN
go 1.15.15YYY
go 1.17.12YNY
go 1.17.12YYY

在 go 1.15.15版本 或者其他相近版本中,只设置max idle time,不能自动回收空闲连接。

具体原因,可以参见 issue,或者具体查看go 源码,这应该是一个bug。

参考

database/sql: SetConnMaxIdleTime without SetConnMaxLifetime has no effect #41114

golang mysql 如何设置最大连接数和最大空闲连接数

http://www.lryc.cn/news/20565.html

相关文章:

  • 嵌入式开发利器
  • Qt 的QString类的使用
  • django项目部署(腾讯云服务器centos)
  • 计算机网络笔记、面试八股(一)——TCP/IP网络模型
  • 51单片机入门 - 简短的位运算实现扫描矩阵键盘
  • Mr. Cappuccino的第45杯咖啡——Kubernetes之部署SpringBoot项目
  • vscode在远程服务器提交git的时候无需每次都要输入账号密码的配置
  • 【Spring 基础】
  • 2023年全国最新机动车签字授权人精选真题及答案5
  • 5138: 数字游戏
  • 阅读笔记9——DenseNet
  • PowerAutomation获取邮件附件并删除这个邮件方法
  • websocket报错集锦-不断更新中
  • Spring Cloud Nacos源码讲解(七)- Nacos客户端服务订阅机制的核心流程
  • 【华为OD机试模拟题】用 C++ 实现 - 对称美学(2023.Q1)
  • Go语言内存管理详解-学习笔记
  • Geospatial Data Science (4): Spatial weights
  • JUC-Synchronized相关内容
  • 【c++】文件操作(文本文件、二进制文件)
  • 带你了解IP报警柱的特点
  • 一步步教你电脑变成服务器,tomcat的花生壳设置(原创)
  • Python 卷积神经网络 ResNet的基本编写方法
  • 【索引】什么是索引
  • 【算法刷题】动态规划算法题型及方法归纳
  • PolarDB数据库的CSN机制
  • 使用kubeadm 部署kubernetes 1.26.1集群 Calico ToR配置
  • Servlet笔记(11):Servletcontext对象
  • EM算法是什么
  • C++---线性dp---方格取数(每日一道算法2023.2.25)
  • 《第一行代码》 第八章:应用手机多媒体