接下来讲解下几个配置信息:
// 设置最大连接数
db.SetMaxOpenConns(100)
// 设置最大空闲连接数
db.SetMaxIdleConns(25)
// 设置每个链接的过期时间
db.SetConnMaxLifetime(5 * time.Minute)
设置连接池最大打开数据库连接数,<= 0 表示无限制,默认为 0。
问:应该设置多大呢?
实验表明,在高并发的情况下,将值设为大于 10,可以获得比设置为 1 接近六倍的性能提升。而设置为 10 跟设置为 0(也就是无限制),在高并发的情况下,性能差距不明显。
问:是否越大越好?
需要考虑的是不要超出数据库系统设置的最大连接数。MySQL 数据库可使用以下命令来查询:
show variables like 'max_connections';
MySQL5.7默认是300:
MySQL 8 默认是 151:
设置时不应该超过这个值,否则会出现 MySQL 错误:
MySQL: ERROR 1040: Too many connections
另外,还需要注意这个值是整个系统的,如有其他应用程序也在共享这个数据库,这个可以合理地控制小一点。
设置连接池最大空闲数据库连接数,<= 0 表示不设置空闲连接数,默认为 2。
实验表明,在高并发的情况下,将值设为大于 0,可以获得比设置为 0 超过 20 倍的性能提升。
这是因为设置为 0 的情况下,每一个 SQL 连接执行任务以后就销毁掉了,执行新任务时又需要重新建立连接。很明显,重新建立连接是很消耗资源的一个动作。
设置空闲连接数,当有新任务进来时,直接使用这些随时待命的连接传输数据,以此达到节约资源,提高执行效率的目的。
问:是不是数值越大越好?
首先此值不能大于 SetMaxOpenConns
的值,大于的情况下 mysql 驱动会自动将其纠正。
其次需要考虑的是,长时间打开大量的数据库连接需要占用系统的内存和 CPU 资源。
还有一个情况是 MySQL 会有一个 wait_timeout
的设置,连接超过这个时间就会被自动关闭,默认情况下是 8 个小时。当 MySQL 关闭连接时,sql.DB 请求到的就是一个坏的连接,虽然 sql 包里已经做了处理,当请求到坏连接时会自动重连。但是在这种情况下,单次请求相当于建立了两次连接,消耗比设置为 0 还大,得不偿失。
所以回答上面的问题,不是越大越好,应根据实际情况选择合理的值。
设置连接池里每一个连接的过期时间,过期会自动关闭。理论上来讲,在并发的情况下,此值越小,连接就会越快被关闭,也意味着更多的连接会被创建。
设置的值不应该超过 MySQL 的 wait_timeout
设置项(默认情况下是 8 个小时)。
此值也不宜设置过短,关闭和创建都是极耗系统资源的操作。
设置此值时,需要特别注意 SetMaxIdleConns 空闲连接数的设置。假如设置了 100 个空闲连接,过期时间设置了 1 分钟,在没有任何应用的 SQL 操作情况下,数据库连接每 1.6 秒就销毁和新建一遍。
这里的推荐,比较保守的做法是设置五分钟:
db.SetConnMaxLifetime(5 * time.Minute)
SetConnMaxLifetime 要求传参的是一个 time.Duration
对象,所以这里使用了 time.Minute
,这也是我们初次使用标准库里的关于处理时间的包 —— time 。