sql.DB 连接池的配置信息

接下来讲解下几个配置信息:

// 设置最大连接数
db.SetMaxOpenConns(100)

// 设置最大空闲连接数
db.SetMaxIdleConns(25)

// 设置每个链接的过期时间
db.SetConnMaxLifetime(5 * time.Minute)

SetMaxOpenConns 最大连接数

设置连接池最大打开数据库连接数,<= 0 表示无限制,默认为 0。

问:应该设置多大呢?

实验表明,在高并发的情况下,将值设为大于 10,可以获得比设置为 1 接近六倍的性能提升。而设置为 10 跟设置为 0(也就是无限制),在高并发的情况下,性能差距不明显。

问:是否越大越好?

需要考虑的是不要超出数据库系统设置的最大连接数。MySQL 数据库可使用以下命令来查询:

show variables like 'max_connections';

MySQL5.7默认是300:
MySQL 8 默认是 151:

file

设置时不应该超过这个值,否则会出现 MySQL 错误:

MySQL: ERROR 1040: Too many connections

另外,还需要注意这个值是整个系统的,如有其他应用程序也在共享这个数据库,这个可以合理地控制小一点。

SetMaxIdleConns 空闲连接数

设置连接池最大空闲数据库连接数,<= 0 表示不设置空闲连接数,默认为 2。

实验表明,在高并发的情况下,将值设为大于 0,可以获得比设置为 0 超过 20 倍的性能提升

这是因为设置为 0 的情况下,每一个 SQL 连接执行任务以后就销毁掉了,执行新任务时又需要重新建立连接。很明显,重新建立连接是很消耗资源的一个动作。

设置空闲连接数,当有新任务进来时,直接使用这些随时待命的连接传输数据,以此达到节约资源,提高执行效率的目的。

问:是不是数值越大越好?

首先此值不能大于 SetMaxOpenConns 的值,大于的情况下 mysql 驱动会自动将其纠正。

其次需要考虑的是,长时间打开大量的数据库连接需要占用系统的内存和 CPU 资源。

还有一个情况是 MySQL 会有一个 wait_timeout 的设置,连接超过这个时间就会被自动关闭,默认情况下是 8 个小时。当 MySQL 关闭连接时,sql.DB 请求到的就是一个坏的连接,虽然 sql 包里已经做了处理,当请求到坏连接时会自动重连。但是在这种情况下,单次请求相当于建立了两次连接,消耗比设置为 0 还大,得不偿失。

所以回答上面的问题,不是越大越好,应根据实际情况选择合理的值。

SetConnMaxLifetime 过期时间

设置连接池里每一个连接的过期时间,过期会自动关闭。理论上来讲,在并发的情况下,此值越小,连接就会越快被关闭,也意味着更多的连接会被创建。

设置的值不应该超过 MySQL 的 wait_timeout 设置项(默认情况下是 8 个小时)。

此值也不宜设置过短,关闭和创建都是极耗系统资源的操作。

设置此值时,需要特别注意 SetMaxIdleConns 空闲连接数的设置。假如设置了 100 个空闲连接,过期时间设置了 1 分钟,在没有任何应用的 SQL 操作情况下,数据库连接每 1.6 秒就销毁和新建一遍。

这里的推荐,比较保守的做法是设置五分钟:

db.SetConnMaxLifetime(5 * time.Minute)

SetConnMaxLifetime 要求传参的是一个 time.Duration 对象,所以这里使用了 time.Minute,这也是我们初次使用标准库里的关于处理时间的包 —— time 。