连接池
长连接的好处这么大,自然大家都用长连接。慢慢就搞出一套长连接维护的工具 - 数据库连接池。
设计连接池也没有多么复杂,大致的步骤就是:
初始化连接;业务取出连接;业务发送请求;放回连接。
除了上面的基本功能以外,还要处理并发问题,多数据库服务器和多用户,事务处理,连接池的配置与维护。大概就这些功能。有了连接池之后,连接的建立和释放跟业务就没有关系,交给交接池来维护。
2. MYSQL 能支持多少连接
MYSQL 的最大连接数在5.7版本中默认是151, 最大可以达到16384(2^14)。如何设置最大连接数在于你的服务器性能,查看 MYSQL连接数信息命令如下:
mysql> show variables like '%max_connections%';+-----------------+-------+| Variable_name | Value |+-----------------+-------+| max_connections | 5050 |+-----------------+-------+1 row in set (0.00 sec)
我们生产环境MYSQL的最大连接数设置为 5050,注意不能设置的太小,太小造成的后果是连接失败:“query failed Error 1040: Too many connections“ 错误。太大且当连接该数据库的机器比较多的时候则会对当前MYSQL的性能产生影响。
MYSQL官网给出了一个设置最大连接数的建议比例:
Max_used_connections / max_connections * 100% ≈ 85%
即已使用的连接数占总上限的85%左右,如果目前已使用的连接数与最大连接数比例小于10%那很显然设置的过大。
查询当前数据库已建立连接数:
mysql> show status like 'Threads_connected';+-------------------+-------+| Variable_name| Value |+-------------------+-------+| Threads_connected | 89 |+-------------------+-------+1 row in set (0.00 sec)
Mysql的配置可以在全局变量中查询和设置,相关的配置主要可以查询下面这些:
3. 连接池设置多少连接才合适
设置连接池的大小肯定不是越大越好,需要考虑的是当前服务所在机器的性能,网络状况,数据库机器性能,数据库特性等等。同时也要做到不浪费系统资源,内存,端口,同步信号量等等。
比如说应用服务器Tomcat设置的最大线程池缺省值200,最大假设每个线程会用到一个数据库连接,那么线程池大小应该小于等于200。
另外需要考虑的是,每申请一个长连接都会在物理网络上建立一个用于长连接维护的进程,而进程的执行跟物理机的CPU核数有关。理论上一个8核的服务器将连接池设置为8最佳,每一个核同时处理一个线程,超过8的并发就有线程上下文切换的开销。
这里有一个 Oracle 性能小组发布的简短视频,连接池测试分2个部分:
测试视频1/pls/apex/f?p=44785:112:11510768535381::::P112_CONTENT_ID:9565
测试视频2
/pls/apex/f?p=44785:112:11510768535381::::P112_CONTENT_ID:9566
视频中调整了线程池大小为2048的时候数据库性能陡然下降,后面调整到144就恢复了。PostgreSQL提供了一个设置预期线程池大小的公式:
connections = ((core_count * 2) + effective_spindle_count)
该公式来自于:/brettwooldridge/HikariCP/wiki/About-Pool-Sizing。
其中,core_count
是CPU核心,effective_spindle_count
的含义是有效主轴数,如果你的服务器使用的是带有16个磁盘的RAID,那么valid_spindle_count=16
。它实质上是服务器可以管理多少个并行I / O请求的度量。旋转硬盘一次(通常)一次只能处理一个I / O请求,如果你有16个,则系统可以同时处理16个I / O请求。