帮助 您好,欢迎您来到忆天网络 登陆 注册

服务与支持

选择我们的理由

  • 拥有的资历荣誉值得您的信赖
  • 拥有全部域名管理权
  • 免费支持无限泛域名解析
  • 支持A\CNAME\MX记录及URL转发
  • 免费打印域名证书
  • IDN(国际化域名名称)标准
  • 免费IP指向(A记录)
  • 免费MX邮件记录设定
  • 免费URL转发
  • 完善的7*24小时不间断技术支持


关于PHP出现Too many connections 的问题

关于PHP出现Too many connections 的问题
* 来源 : * 作者 : admin * 发布时间 : 11-11-11 * 浏览 : 30

以前有朋友问过我,为什么他的网站出现Too many connections 错误。因为我自己没有遇到过这个问题,那时候工作也忙,没有时间去考虑这个问题。几个星期前,到现在的公司工作,有朋友告诉我,我现在的公司的网站上出现同样的问题,到了非要搞清楚的地步了,于是在PHP手册里面找关于mysql_connect和mysql_pconnect的资料,下面是在php手册中对这两个函数的描述:

-------- mysql_connect -----------
函数原型:
    resource mysql_connect ( [string server [, string username [, string password [, bool new_link [, int client_flags]]]]])
返回:
    如果成功则返回一个 MySQL 连接标识,失败则返回 FALSE。
描述:
    mysql_connect() 建立一个到 MySQL 服务器的连接。当没有提供可选参数时使用以下默认值:server = 'localhost:3306',username =
服务器进程所有者的用户名,password = 空密码。
   如果用同样的参数第二次调用 mysql_connect(),将不会建立新连接,而将返回已经打开的连接标识。参数 new_link 改变此行为并使
mysql_connect() 总是打开新的连接,甚至当 mysql_connect() 曾在前面被用同样的参数调用过。参数 client_flags 可以是以下常量的组合
:MYSQL_CLIENT_COMPRESS,MYSQL_CLIENT_IGNORE_SPACE 或者 MYSQL_CLIENT_INTERACTIVE。
    注: new_link 参数自 PHP 4.2.0 起可用。
        client_flags 参数自 PHP 4.3.0 起可用。
一旦脚本结束,到服务器的连接就会被关闭。除非之前已经调用了 mysql_close() 来关闭它。
------- mysql_pconnect -------------
函数原型:
resource mysql_pconnect ( [string server [, string username [, string password [, int client_flags]]]])
返回:
如果成功则返回一个正的 MySQL 持久连接标识符,出错则返回 FALSE。
描述:
    mysql_pconnect() 建立一个到 MySQL 服务器的连接。如果没有提供可选参数,则使用如下默认值:server = 'localhost:3306',
username = 服务器进程所有者的用户名,password = 空密码。client_flags 参数可以是以下常量的组合:MYSQL_CLIENT_COMPRESS,
MYSQL_CLIENT_IGNORE_SPACE 或者 MYSQL_CLIENT_INTERACTIVE。
    server 参数也可以包括端口号,例如 "hostname:port",或者是本机套接字的的路径,例如 ":/path/to/socket"。
    注: 对 ":port" 的支持是 3.0B4 版添加的。
        对 ":/path/to/socket" 的支持是 3.0.10 版添加的。
   
-------- 两者之间的区别 --------------
mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别。
    首先,当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接
标识而不打开新连接。
    其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由
mysql_pconnect() 建立的连接)。
    可选参数 client_flags 自 PHP 4.3.0 版起可用。
此种连接称为"持久的"。

看到这里,写一条代码来测试一下
/*
* pconnect_test.php
*/
$link = mysql_pconnect("localhost", "mysql_user", "mysql_password")
        or die("Could not connect: " . mysql_error());
    print ("Connected successfully");
    通过刷新网页的方式执行这条代码,发现每执行一次,mysql的进程数就增加一个。在这里我不禁有了疑问。上面说mysql_pconnect这个函
数的使用的时候,不是说"当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到
,则返回此标识而不打开新连接"么?为什么我每刷新一次页面他就给我打开一个新的连接呢?
    考虑到这有可能是PHP的bug,我到PHP的bug列表中找关于和too many connections 有关的条目。
相关的话题主要有三个,分别是
#11966        mysql_pconnect opens new connections with the same parameters
#26117        Persistent connection not reused
#13589        Persistent connections stay open and accumulate
    描述比较长,我就不在这里贴,具体的内容你自己去看。重点主要是"当一个进程打开一个mysql的持续连接,只要该进程还存在,这个持续
的连接就不会断开,而且每一个进程会打开一个mysql的持续连接,而不能使用其他进程打开的持续连接"。
    到这里,我把相关的信息发给上海的朋友张宏,他提示我把apache的子进程数限制到不高于mysql的最大连接数。我问了我们的系统管理员
,他说我们的服务器上apache的最大子进程数是256,而mysql的最大连接数限制为600。就是说mysql的最大连接数已经远远超过httpd的进程数
,为什么还会出现Too many connections 这样的错误呢?答案就在于PHP程序。打开以前同事写的程序,发现同一个运行脚步中过多的调用
mysql_pconnect函数。如果在应用服务器上,每一个httpd子进程使用一个php脚本,每一个php脚本打开不止一个mysql的连接。因为httpd所产
生的子进程的生存期是apache服务器指定的,一般服务器不重启,这些进程就一直存在。就算服务器重启,也可以指定保存这些进程。由于进
程的存在,那么这些连接都不会断掉,并且每个进程打开几个连接数,那么统计起来,连接数就达到了mysql限制的最大连接数。这时就出现
Too many connections 错误。
    小结一下,要保证你的系统不会出现Too many connections 错误,需要注意两点:
    1.保证你的apache的最大进程数不超过mysql的最大连接数;
    2.不要在程序里面用过多mysql_pconnect连接到同一个数据库服务器(一个就够了).这需要好的编码习惯和规范.特别是不断的给系统增加
    新的功能,如果不注重系统架构和编码规范,当系统的复杂度到了一定的程度,整个系统就变得无法维护了.出现问题的时候解决起来就很麻烦了.