PHP数据库长连接mysql

  • 时间:
  • 浏览:2
  • 来源:uu快3app赚钱_uu快3大小计划注册

  这样 ,PHP的MySQL连接资源是缘何被hold住的呢,这才时会 查看PHP的mysql_pconnect的函数代码,我看后下,大约的做法为社 让mysql_pconnect根据当前Apache系统进程号,生成hash key,找hash表内有无对应的连接资源,这样 则推入hash表,有则直接使用。类事代码片段才能说明(具体可查看PHP5.3.8源码ext/mysql/PHP_mysql.c文件690行PHP_mysql_do_connect函数)

  [sql] view plaincopy

  对于作为Apache模块运行的PHP来说,要实现MySQL持久化连接,首先得取决于Apache你类事

}

,最后呈现在浏览器上的为社 让漂亮的页面了。这上面有那些问题图片呢?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秒)。

/* try to find if we already have this link in our persistent list */

hashed_details_length = spprintf(&hashed_details, 0, "MySQL__%s_", user);

$conn = mysql_pconnect("localhost","root","123456") or die("Can not connect to MySQL");

else

?>

  2   echo "Apache系统进程号:". getmypid();

if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {

?>

/* we don't */

  2 wait_timeout        = 1000

  浏览器是缘何知道才能 才能 重新进行TCP连接就才能直接发送http请求呢?为社 让http返回头里就会带上Connection:keep-alive,Keep-alive:15两行,意思为社 让让客户端浏览器明白,这次socket连接我这边还没关闭呢,给你在15内继续使用你类事连接,并发送http请求,于是乎浏览器就知道应该缘何做了。

}

  好了,重启Apache,

  以上的代码没啥好解释的,让给你们都用浏览器浏览你类事页面,看后那些?看后好哪几个 多显眼的数字。好哪几个 多是MySQL系统进程号,好哪几个 多是Apache系统进程号,好了,15秒后再刷新你类事页面,发现类事个多id都变了,为社 让为社 让是新的Apache系统进程了,系统进程id是新的,hash key就变了,PHP只好重新连接MySQL,连接资源推入persistent list。为社 让15内刷新呢?Apache系统进程肯定不变,MySQL系统进程号会变吗?答案得问MySQL了。首先你类事MySQL_thread_id是那些东西?shell土法子登录MySQL后执行命令'show processlist;',看后了那些?

  +-----+------+-----------+------+--------+-----+------+-----------------+

#2.为社 让未找到已有资源,就推入hash表,名字叫persistent_list,为社 让找到就直接使用

...

  | Id  | User | Host      | db   | Command| Time| State| Info            |

  | 349 | root | localhost | NULL | Sleep  |    2|      | NULL            |

  1<?php

echo "MySQL系统进程号:".MySQL_thread_id($conn)."<br />";

  配置事先,重启MySQL,shell登录MySQL,这事先show processlist才能发现才时会 当前系统进程。为社 让运行那个包含mysql_pconnect的PHP页面,再回来MySQL端show processlist可发现,多了好哪几个 多Commond为Sleep的系统进程,不停的show processlist(方向键上+enter键)观察Time列的变化2,5,10...14!,老要那个Sleep系统进程程被kill掉了,咋回事,还没到1000秒呢,噢!忘了修改一下Apache keepalive的参数了,把KeepAliveTimeOut从15改成120(只为观察,才这样 改),重启Apache。刷新那个页面,好,刚结束不停的show processlist,2..5..10..14,15,..20...26....28,29!系统进程被kill,这次是为社 让wait_timeout起了作用,浏览器那边停了1000秒,1000内为社 让浏览器刷新,那你类事Time又会从0刚结束计时。你类事连接不属于interactive connection(MySQL shell登录那种连接就属于interactive connection),要是采用了wait_timeout的值。为社 让mysql_pconnect的第好哪几个 多参数改改呢

new_le.ptr = mysql;

echo "Apache系统进程号". getmypid();

...

//hashed_details为社 让hash key

  MySQL的wait_timeout和interactive_timeout

echo "MySQL系统进程号:". MySQL_thread_id($conn). "<br />";

mysql = (PHP_mysql_conn *) le->ptr;//直接使用对应的sql连接资源

  说完Keep-Alive,该到MySQL家串串门了,说的是mysql_pconnect,缘何能绕开MySQL的设置。影响mysql_pconnect最重要的好哪几个 多参数为社 让wait_timeout和interactive_timeout,它们是那些东西?先撇一边,首先让给你们都把上面的代码改动一下PHP代码

  Keep-Alive是那些东西?它是http协议的一次责,让给你们都复习一下这样 Keep-Alive的http请求,从客户在浏览器输入好哪几个 多有效url地址刚结束,浏览器就会利用socket向url对应的web服务器发送二根TCP请求,你类事请求成功一次就得才时会 来回握三次手才能选则,成功事先,浏览器利用socket TCP连接资源向web服务器请求http协议,发送事先就等着web服务器把http返回头和body发送回来,发回来后浏览器关闭socket连接,为社 让做http返回头和body的解析

}

/* hash it up(推入hash表) */

  1 interactive_timeout = 1000

  | 348 | root | localhost | NULL | Query  |    0| NULL | show processlist|

{/* The link is in our list of persistent connections(连接已在hash表里)*/

...

$conn = mysql_pconnect('localhost','root','123456',MySQL_CLIENT_INTERACTIVE);

...

user=php_get_current_user();//获取当前PHP执行者(Apache)的系统进程唯一标识号

...

  很简单,获取当前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系统进程。

zend_hash_find比较容易看明白,原型是zend_hash_find(hash表,key名,key长,value);为社 让找到,value全部时会值了。

  发现了不为社 要的信息,你类事processlist列表为社 让记录了正在跑的系统进程,忽略Info列为show processlist那行,那行有你在当前shell登录MySQL的系统进程。PHP连接MySQL的系统进程为社 让Id为349那行,为社 让读者另一方做测试,应该知道你类事Id=349在你的测试环境里是另外好哪几个 多值,给你们都把你类事值和网页里输出的MySQL_thread_id($conn)做做比较,对!给你们都是一样的。接下来最重要的是观察Command列和Time列,Command = Sleep,表明那些?表明给你们都mysql_pconnect连接后就老要在sleep,Time字段就告诉给你们都,你类事系统进程Sleep了多久,这样 Sleep了多久你类事系统进程才能作废呢?那为社 让wait_timeout为社 让interactive_timeout要做的工作了,给你们都默认的值全部时会8小时,天啊,不多了,要是为社 让说web服务器关掉KeepAlive支持,那个你类事processlist很容易就被撑爆,就爆出那个Too many connections的错误了,max_connectiosns配置得再多也没用。为了观察类事个多参数,给你们都才能在MySQL配置文件my.cnf里设置类事个多值,找到[MySQLd]节点,在上面设置多两行

  3?>

<?php

...

PHP的

服务器有无支持Keep-Alive。

  Keep-Alive

  刷新下页面,MySQL那边刚结束刷show processlist,这回Time > 1000为社 让会被kill,>1000才被kill了,说明设置了MySQL_CLIENT_INTERACTIVE,就会被MySQL视为interactive connection,这样 这次PHP的MySQL连接在120秒内未刷新的情況下,何时作废将取决于MySQL的interactive_timeout的配置值。

Z_TYPE(new_le) = le_plink;

持久化连接,美好的目标,却拥有糟糕的口碑,往往令人敬而远之。这到底是缘何么。近距离观察后发现,这家伙为社 让容易啊,要看Apache的脸色,还得听MySQL指挥。

...

一下,赶紧写行东西:

  +-----+------+-----------+------+--------+-----+------+-----------------+

  mysql> show processlist;

  PHP的mysql_pconnect要达到功效,首先才时会 保证Apache是支持keep alive的,其次KeepAliveTimeOut应该设置多久呢,要根据自身站点的访问情況做调整,时间太短,keep alive没啥意义,时间太长,就很为社 让为好哪几个 多闲客户端连接牺牲要是服务器资源,毕竟hold住socket监听系统进程是要消耗cpu内存的。最后Apache的KeepAliveTimeOut配置得和MySQL的time out配置要有个平衡点,联系以上的观察,假设mysql_pconnect未带上第好哪几个 多参数,为社 让Apache的KeepAliveTimeOut设置的秒数比wait_timeout小,那真正对mysql_pconnect起作用的是Apache而全部时会MySQL的配置。这时为社 让MySQL的wait_timeout偏大,并发量大的情況下,很为社 让就一堆废弃的connection了,MySQL这边为社 让不及时回收,那就很为社 让Too many connections了。为社 让为社 让KeepAliveTimeOut不多呢,又回到事先的问题图片,要是貌似Apache。KeepAliveTimeOu未必不多,但比MySQL。wait_timeout 稍大,为社 让相等是比较好的方案,为社 让才能保证keep alive过期后,废弃的MySQL连接才能及时被回收。   

echo "Apache系统进程号:".getmypid();

  总结

最新内容请见作者的GitHub页:http://qaseven.github.io/

<?php

if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {

  +-----+------+-----------+------+--------+-----+------+-----------------+

...

  PHP缘何做