昨天和一个面试官聊以前的系统出了这个问题,意见不一起了争执,我的意见是:php调用了外部接口导致速度慢,他说PHP执行慢和这个没关系,肯定是慢查询导致,所以今天回来特意测试一下。
目的:研究 mysql 连接数过多,探讨一下出现too many connections的原因
首先了解一下MySQL的一些参数,
查看数据库的连接数
SHOW STATUS LIKE “Threads%” ;
解释一下这几个值的含义:
threads_connected: 数据库当前的连接线程数。这是动态变化的。
当threads_connected == max_connections 时,数据库系统就不能提供更多的连接数了,这时再有新的连接过来,就会出错了;并报错提示“Too many connections”
Thread_ cache :这是为了提高客户端请求创建连接过程的性能,提供的一个连接池,将空闲的连接线程放在连接池中,而不是立即销毁.这样的好处就是,当有新的请求, mysql不会立即去创建连接线程,而是先去 thread _Cache中去查找空闲的连接线程,如果存在则直接使用,不存在才创建新的连接线程,相关的配置是cache的大小,thread_cache_size,可以在配置文件中进行修改;
threads_created表示创建过的 线程 数:此数据越大,说明数据库创建的线程越多,对系统消耗越大,可适当增大 thread_cache_size的值来改善;
threads_running :活跃的连接,数值过大,说明并发量高,此指标经常与cpu使用和慢查询有直接关系,几个因素可能相互影响;
查看最大连接数,如果不设置,默认是100。最大是16384
show variables like ‘%max_connections%’;
My.ini文件里有,可以配置最大连接数
max_connections=100 ,这里默认是100
最大连接数,并不是说越大越好,需要考虑服务器的配置,性能等因素。
言归正传,开始测试,使用ab工具,对 laravel 框架写的页面进行压力测试:
100个并发:
Ab -c 100 –t 60 localhost:89/ ,
监控状态,连接数只有几个,创建了20 ,thread_cache_size=16达到了设置最大值;
增加并发数量,连接数并没有增加,说明大部分是空闲连接;这时系统cpu已经被php-cgi
程序占满了。
为了方便测试,设置最大连接数为10 ,否则直接报错502 ,根本测不出数据库的问题。
测试数据 200w+ ,查询语句
SELECT COUNT (*) FROM blogs WHERE good_num > 1000 AND title LIKE “%Ab” ;
没有索引
查询报错了,Too many connections,连接数 达到上限了
我们换一个简单的查询,重新测试:
同样的压力,只有两个连接数 ,页面也访问正常。
总结:
1.PHP的高并发量并不一定会导致数据库无法连接,只要数据库处理的足够快就没问题。
2.慢查询会导致too many connections 错误, 会影响系统的并发量,另外系统硬件资源不足也会影响并发量;
3. 502 错误一般PHP处理不过来导致的;
另一个问题,php与MySQL的连接是短链接,每次请求执行完就会销毁 ,每次刷新 ,id都是不一样的;
Laravel框架可以通过如下配置,MySQL为长连接
长连接 也不是一直存在,可以设置wait_timeout
空闲多长时间后关闭 ,长连接的利与弊类似http和tcp协议,要不要用自行判断。
最后,若有不当之处,欢迎各位同行一起交流指正!