如果所有的用户连接请求都只占用一个持久链接线程,那打个比方,100万用户访问这一个网站,对数据库进行操作,只占用一个数据库线程?? ---------------------------------------------- 那搞个访问队列是必须的了,只有一个连接资源,高并发的情况下,怎么分配给100w个用户,怎么也得排排队吧,分配还是小事,用户是不是等得了那么久this is a really big issue。 我看了下java实现的数据库连接池介绍,那也得有个最小连接数(不管进程是否使用,总是保留这么多连接),和最大连接数,如果进程访问连接池时,发现已经到达最大连接,那进程就得推入一个队列等候空闲的连接。 所以只能是一个php进程至少保持一个mysql连接,但是还得保证有gc机制,就是楼上说的wait_timeout或者interactive_timeout.然后还是不够,假设站点访问高并发,用户停留时间长,那么mysql连接数就很可能超过mysql本身设置的最大连接数,这时候怎么办?将php的mysql连接请求推入队列应该可以避免报错,但是鬼知道还要等多久。 似乎没有个解决方案,那么还是下大力气设计好缓存系统吧,或者引入nosql吧。
PHP提供了一种内置的数据库缓冲机制,即用mysql_pconnect()代替mysql_connect() 来打开数据库而已。PHP会自动回收被废弃的数据库连接,以供重复使用。在实际应用中,这种持久性数据库连接往往会导致数据库连接的伪泄漏现象:在某个时间,并发的数据库连接过多,超过了MySQL的最大连接数,从而导致新的进程无法连接数据库。但是过一段时间,当并发数减少时,PHP会释放掉一些连接,网站又会恢复正常。
mysql_connect()b.php
include("a.pohp")
mysql_query('select ...');
//600秒之内没有交互则自动断掉连接,这点可以通过show processlist来验证
我理解是同一个进程,用户名,密码下调用就会是找同一个已经连接上的。
第二、只要查数据就要对数据库进行操作,不过你也可以写一些缓存文件,这样的的话就可以把一些内容写到本地。
第三、数据库连接和查询是有一个临界点的,不是说查询少量多次的查询内容,或者一次查询大量内容,就可以减少或者增加服务端压力的。而是要取得一个临界值,把握好一个度才是最重要的。
Apache+PHP+Mysql_pconnect的工作方式
每当客户端向服务端发送一个连接请求(包括图片,HTML,PHP等),apache将会用一个线程来接受这个请求(换句话说,每一个用户访问,就占用一个线程),如果是请求的是一个PHP文件,且 PHP文件里使用了PConnect,则当前线程会判断当前线程有没有打开过pconnect(每个用户的线程是相互独立的,那么pconnect也就是针对当前用户占用的进程而言的),如果有打开过,则使用原来的mysql connect,如果没有打开过,则新建一个connect,并且,连接断开后,线程仍在运行,而且保持Mysql connect.按这种方式运行一段时间后,完全有可能所有apache的线程都打开过有Pconnect的Php页面,所以,如果apache的 ThreadsPerChild=500的话,则500个线程都找开了mysql连接,并且没有关闭,则就要求,mysql的连接数必须大于或等于 500,如果小于这个值,将会导致PHP页面提示数据库连接失败.
如果所有的用户连接请求都只占用一个持久链接线程,那打个比方,100万用户访问这一个网站,对数据库进行操作,只占用一个数据库线程??
----------------------------------------------
那搞个访问队列是必须的了,只有一个连接资源,高并发的情况下,怎么分配给100w个用户,怎么也得排排队吧,分配还是小事,用户是不是等得了那么久this is a really big issue。
我看了下java实现的数据库连接池介绍,那也得有个最小连接数(不管进程是否使用,总是保留这么多连接),和最大连接数,如果进程访问连接池时,发现已经到达最大连接,那进程就得推入一个队列等候空闲的连接。
所以只能是一个php进程至少保持一个mysql连接,但是还得保证有gc机制,就是楼上说的wait_timeout或者interactive_timeout.然后还是不够,假设站点访问高并发,用户停留时间长,那么mysql连接数就很可能超过mysql本身设置的最大连接数,这时候怎么办?将php的mysql连接请求推入队列应该可以避免报错,但是鬼知道还要等多久。
似乎没有个解决方案,那么还是下大力气设计好缓存系统吧,或者引入nosql吧。
观点1:优化数据库查询,connect数据库占用资源并不多。
观点2:pconnect并不可取,因其是一对一客户端的。
观点3:php不能够做到,设计好缓存系统,或者引入nosql。
此外,可以试试缓存。用户每一次操作都是在操作缓存,每一次高并发读取都是在读取缓存。缓存的数据每隔20分钟或者10分钟进行一次写入数据库或者更新数据库。
var $version = '';
var $querynum = 0;
var $link = null;
var $charset = "UTF8"; function connect($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0, $halt = TRUE, $dbcharset2 = '') {
$func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';
if(!$this->link = @$func($dbhost, $dbuser, $dbpw, 1)) {
$halt && $this->halt('Can not connect to MySQL server');
} else {
if($this->version() > '4.1') {
$serverset = 'character_set_connection='.$this->charset.', character_set_results='.$this->charset.', character_set_client=binary' ;
$serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';
$serverset && mysql_query("SET $serverset", $this->link);
}
$dbname && @mysql_select_db($dbname, $this->link);
}
}
。class Core extruct Mysql {
public static $db = null;
public $error = '';
public $errorno = ''; /**
* 创建数据库连接
*
* @return Object 数据库对象
*/
public function db(){
if(self::$db == null){
self::$db = new Mysql();
$cfg = config_item('mysql');
self::$db->connect($cfg['host'], $cfg['user'],$cfg['pass'],$cfg['db']);
}
return self::$db;
}
。
class Core extends Mysql {
public static $db = null;
public $error = '';
public $errorno = '';/**
* 创建数据库连接
*
* @return Object 数据库对象
*/
public function db(){
if(self::$db == null){
self::$db = new Mysql();
$cfg = config_item('mysql');
self::$db->connect($cfg['host'], $cfg['user'],$cfg['pass'],$cfg['db']);
}
return self::$db;
}
。