mysql短连接 长连接
最近做项目中遇到一个问题,那就是mysql连接问题,下面分享下经验: php的mysql持久化连接。 对于做为apache模块运行的php来说,要实现mysql持久化连接,首先得取决于apache这个web服务器是否支持Keep-Alive。 Keep-Alive
Keep-Alive是什么东西?它是http协议的一部分,让我们复习一下没有Keep-Alive的http请求,从客户在浏览器输入一个有效url 地址开始,浏览器就会利用socket向url对应的web服务器发送一条tcp请求,这个请求成功一次就得需要来回握三次手才能确定,成功以后,浏览器 利用socket tcp连接资源向web服务器请求http协议,发送以后就等着web服务器把http返回头和body发送回来,发回来后浏览器关闭socket连接, 然后做http返回头和body的解析工作,最后呈现在浏览器上的就是漂亮的页面了。这里面有什么问题呢?tcp连接需要三次握手,也就是来回请求三次方 能确定一个tcp请求是否成功,然后tcp关闭呢?来回需要4次请求才能完成!每次http请求就3次握手,4次拜拜,这来来回回的不嫌累啊,多少时间和 资源都被浪费在socket连接关闭上了,能不能一次socket tcp连接发送多次http请求呢?于是Keep-Alive就应运而生,http/1.0里需要客户端自己在请求头加入 Connection:Keep-alive方能实现,在这里我们只考虑http1.1了,只需要设置一下apache,让它默认就是Keep- Alive持久连接模式(apache必须1.2+才能支持Keep-Alive).在httpd.conf里找到KeepAive配置项,果断设置为 On,MaxKeepAliveRequests果断为0(一个持久tcp最多允许的请求数,如果过小,很容易在tcp未过期的情况下,达到最大连接,那 下次连接就又是新的tcp连接了,这里设置0表示不限制),然后对于mysql_pconnect最重要的选项KeepAliveTimeout设置为 15(表示15秒).
好了,重启apache,测试一下
echo”Apache进程号:”.getmypid();
很简单,获取当前php执行者(apache)的进程号,用浏览器浏览这个页面,看到什么?对,有看到一串进程号数字,15秒内,连续刷新页面,看看进程 号有无变化?木有吧?现在把手拿开,交叉在胸前,度好时间,1秒,2秒,3,…15,16。好,过了15秒了,再去刷新页面,进程号有没有变化?变了!又 是一个新的apache进程了,为什么15秒后就变成新的进程了?记得我们在apache里设置的KeepAliveTimeout吗?它的值就是15 秒.现在我们应该大致清楚了,在web服务器默认打开KeepAlive的情况下,客户端第一次http成功请求后,apache不会立刻断开 socket,而是一直监听来自这一客户端的请求,监听多久?根据KeepAliveTimeout选项配置的时间决定,一旦超过这一时间,apache 就会断开socket了,那么下次同一客户端再次请求,apache就会新开一个进程来相应。所以我们之前15内不停的刷新页面,看到的进程号都是一致 的,表明是浏览器请求给了同一个apache进程。
mysql的wait_timeout和interactive_timeout
说完Keep-Alive,该到mysql了,说的是mysql_pconnect,怎么能绕开mysql的设置。
影响mysql_pconnect最重要的两个参数就是wait_timeout和interactive_timeout,它们是什么东西?先撇一边,首先让我们把上面的代码改动一下
$conn=mysql_pconnect(“localhost”,”root”,”123456″) or die(“Can not connect to mysql”); echo ”Mysql线程号:”.mysql_thread_id($conn); echo”Apache进程号”.getmypid();
刷新下页面,mysql那边开始刷show processlist,这回Time > 30也不会被kill,>60才被kill了,说明设置了MYSQL_CLIENT_INTERACTIVE,就会被mysql视为 interactive connection,那么这次php的mysql连接在120秒内未刷新页面的情况下,何时作废将取决于mysql的 interactive_timeout的配置值。
总结
#1.php的mysql_pconnect要达到功效,首先必须保证apache是支持keep alive的,然后KeepAliveTimeOut应该设置多久呢,要根据自身站点的访问情况做调整,时间太短,keep alive没啥意义,时间太长,就很可能为一个闲客户端连接牺牲很多服务器资源,毕竟hold住socket监听进程是要消耗cpu内存的. #2.apache的KeepAliveTimeOut配置得和mysql的time out配置要有个平衡点,联系以上的观察,假设mysql_pconnect未带上第4个参数,如果apache的KeepAliveTimeOut设置 的秒数比wait_timeout小,那真正对mysql_pconnect起作用的是apache而不是mysql的配置.这时如果mysql的 wait_timeout偏大,并发量大的情况下,很可能就一堆废弃的connection了,mysql这边如果不及时回收,那就很可能Too many connections了.可是如果KeepAliveTimeOut太大呢,又回到之前的问题,所以貌似 Apache.KeepAliveTimeOut不要太大,但比Mysql.wait_timeout 稍大,或者相等是比较好的方案,这样可以保证keep alive过期后,废弃的mysql连接可以及时被回收.
PS