php的pconnect()

mysql_pconnect() 函数打开一个到 MySQL 服务器的持久连接。

mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别:

  1. 当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接标识而不打开新连接。
  2. 其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由 mysql_pconnect() 建立的连接)

但使用Pconnect会经常的导致Mysql连接失败,提示连接太多,原因在于pconnect后,Apache不会自动关闭mysql的连接.

先来看看APACHE的工作模式
Windows 下,Apache使用一个主进程,加一个辅进程,再由辅进程派生N个线程的方式来提供服务,线程的数量可以在httpd.conf里配置: ThreadsPerChild 500,如果指定为500线程,则apache一启动时就会启动500个线程,但最多也只使用500个线程,如果同时连接数量超过500个(可能300个用户访问就有500个连接,判断当前连接的方法,可以使用netstat -na|grep 80|grep EST|wc -l或者使用apache的status module),那么,多余的连接将会在等待或者连接失败.(所以,Windows下Apache的主要配置参数应该是ThreadsPerChild, 先根据当前的连接数,再看看有没有必要调大一些,一般PC服务器设置为1000算是比较大了.)
Nix下,Apache使用进程的方式来运行,原理相同,需要调整进程数量的参数有几个,比如ServerLimit.

再来看看Apache+PHP+Mysql_pconnect的工作方式
每当客户端向服务端发送一个连接请求(包括图片,HTML,PHP等),apache将会用一个线程来接受这个请求,如果是请求的是一个PHP文件,且 PHP文件里使用了PConnect,则当前线程会判断当前线程有没有打开过pconnect,如果有打开过,则使用原来的mysql connect,如果没有打开过,则新建一个connect,并且,连接断开后,线程仍在运行,而且保持Mysql connect.按这种方式运行一段时间后,完全有可能所有apache的线程都打开过有Pconnect的Php页面,所以,如果apache的 ThreadsPerChild=500的话,则500个线程都找开了mysql连接,并且没有关闭,则就要求,mysql的连接数必须大于或等于 500,如果小于这个值,将会导致PHP页面提示数据库连接失败.

所以,得出结论,Apache+PHP+Mysql下使用 pconnect时,mysql的max_connect必须大于或等于apache的最大线程(进程)数.在一个访问量很大的站点,使用 pconnect可能不太现实,最好的办法是,尽可能的将数据库内容生成为静态文件,而不需要每个页面都连接数据库,并且使用mysql_connect (即使将绝大多数页面生成为静态文件,但仍有mysql_pconnect时,同样要求mysql的max_connect大于apache的线程数,所以这种情况下使用pconnect非常不可取).
 
只从程序上来讲,很空洞。你去自己实际验证下,建立一个pconnect的连接。然后你去mysql下show processlist,看看,然后再建立几个,再去mysql下show processlist。你会发现有很多死连接处于sleep状态。 当这种状态的数量超过了mysql设置的最大连接数,mysql除了root就谁也连不上了。因为mysql总是会为root留一个位置。 这种长连接只有到达my.cnf里面设置的超时时间后才会自动断开,默认好像是8天吧,忘记了。然后你的mysql error日志中会记录一个warnning,翻译过来就是胎死腹中的连接。 所以说实际开发中,如果你的应用属于多用户的,一定不要使用这种连接。除非是那种单人应用的系统,任何时候都只有一个人连接,那这种长连接方式效率会比短 连接更合适。

 

我的理解:至于我一直不明白的mysql_pconnect何时关闭,我想只有数据库关闭的时候才关闭吧。。。。

mysql_connect()根本不是在程序执行完毕就关闭的,因为加入我第一个次执行程序用mysql_connect连接,第二次将连接去 掉,还是能够查询。说明mysql_connect()根本不是在程序执行完毕就关掉,而是有一个保持时间,这就是所谓的,mysql连接时长。

至于mysql_pconnect是一直持续保持连接,没有时长限制,直到数据库关闭连接。mysql_pconnect每次连接时候,会先查找是否有可用连接,原话:当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接标识而不打开新连接。

那么mysql_connect是否也会在连接时候先查找可用连接呢?通过查找php手册,找到相关。原话:如果用同样的参数第二次调用 mysql_connect(),将不会建立新连接,而将返回已经打开的连接标识。

 

 

posted @ 2013-07-18 17:58  西瓜先生  阅读(392)  评论(0)    收藏  举报