您好,欢迎访问一九零五行业门户网

PHP连接池详解

php 脚本本身的确是不能做连接池的,因为php脚本在解释执行完毕后会释放所有内存资源,当然其中用到的数据库连接也会被释放,但一些中间件也是可以做为连接 池的,只要提供php的相关驱动,所以可以自己做php的连接池,但是绝对作不了100% pure php的连接池。mysql_pconnect是php内建的一个模拟连接池,但这套机制不是用php脚本实现的。  但是一次请求可以复用链接,减少new带来的消耗。
<?php class connectodb { private static $instance=array(); //防止外部创建新的数据库连接类 private function _constuct(){} static public function connect() { //连接类不够100,创建新类 if(count(self::$instance)<100) { $newdb=new self(); self::$instance[]=$newdb; return $newdb::condb(); } else { //随机数保证数据库连接均衡 $i=rand(0,99); $new_obj=self::$instance[$i]; return $new_obj::condb(); } } static private function condb() { try { $connec=mysql_connect("127.0.0.1","数据库账户","数据库密码"); mysql_select_db("数据库名");//选择数据库 } catch(exception $e) { $errors[]=$e->getmessage(); } }
连接池的作用主要是节省打开数据库的时间。连接池机制预先打开n个数据库连接,把它们缓存起来,当需要使用数据库的时候就直接使用这些已经打开的连接,从而节省了时间。连接池的存在基本上消除了数据库连接断开的时间与cpu开销。
连接池解决方案:
1、pconnect(持久连接):pconnect的原理,和连接池差不多的,都是程序关闭连接,但php并不真正关闭,再次打开时,直接使用可用的连接。
如果因为访问量太大出现mysql应该配置 mysql 数据库服务的my.cnf 里的 max_connection 的值,如max_connections = 2000。
2、mysql proxy。
3、memcache:针对mysql的一个数据库缓存实现。
4、sql relay:一个开源的数据库池连接代理服务器。支持oracle、mysql、msql、postgresql、sybase、ms sql server、ibm db2、sybase、sqlite、lago、 odbc、ms access等。
安装与配置[sql server](http://blog.sina.com.cn/s/blog_4dd475390100hbck.html),安装sql relay需要先安装rudiments:
1、安装rudiments:
# tar vxzf rudiments-0.28.2.tar.gz
# cd rudiments-0.28.2
# ./configure --prefix=/usr/local/rudiments
# make
# make install
2、安装sql relay:
# tar vxzf sqlrelay-0.36.4.tar.gz
# cd sqlrelay-0.36.4
# ./configure --prefix=/usr/local/sqlrelay --with-rudiments-prefix=/usr/local/rudiments --with-mysql-prefix=mysql安装路径 --with-freetds-prefix=freetds安装路径 --with-oracle-home=oracle安装路径 --with-php-prefix=php安装路径
# make
# make install
3、 设置php:修改 php.ini中extension_dir = "./",把以上内容修改为:extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20050922"。
根据php安装的路径来修改,并不是每个版本的php都是这个路径,在php.ini中添加如下内容extension=sql_relay.so。
4、修改sql relay的配置文件
# cd /usr/local/sqlrelay/etc
# cp sqlrelay.conf.example sqlrelay.conf
把sqlrelay.conf的内容改为:
<?xml version="1.0"?> <!doctype instances system "sqlrelay.dtd"> <instances> <instance id="msdetest" port="9000" socket="/tmp/msdetest.socket" dbase="freetds" connections="5" maxconnections="10" maxqueuelength="0" growby="1" ttl="60" endofsession="commit" sessiontimeout="5" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass"> <users> <user user="sa" password="sa"/> </users> <connections> <connection connectionid="msdetest" string="server=msde;db=pubs;user=sa;password=sa;" metric="1"/> </connections> </instance> </instances>
启动sql relay,并测试;
1、启动 sql relay
# export path=$path:/usr/local/sqlrelay/bin
# sqlr-start -id msdetest
2、使用sql工具:
# sqlrsh -id msdetest
可以直接输入sql语句停止sql relay:# sqlr-stop msdetest
3、测试php,写一个php文 件,内容如下:
<? $con=sqlrcon_alloc("msdetest",9000,"/tmp/msdetest.socket","sa","sa",0,1); $cur=sqlrcur_alloc($con); sqlrcur_sendquery($cur,"select * from t_gifts"); for ($row=0; $row<sqlrcur_rowcount($cur); $row++) { for ($col=0; $col<sqlrcur_colcount($cur); $col++) { echo sqlrcur_getfield($cur,$row,$col); echo ","; } echo "<br>\n"; } sqlrcur_free($cur); sqlrcon_free($con); ?>
php+sqlrelay+mysql实现连接池及读写负载均衡:
为了有效的解决并发访问的瓶颈,利用多台数据库master-slave的模式来增加web的并发访问量。master-slave模式是为了数据同步的问题。
sqlrelay 解决连接池问题以及实现读写分离的均衡负载。sqlrelay配置3个instance a/b/c,a负责从master和slave读取数据,b负责写数据,且只写master,c为router负责调度应用。php通过a还是通过b连接 数据库。在实际配置中,由于master承担了读写操作,那么在instance a的配置中,可以把从master的连接稍微降小,把从slave连接读取数据的连接数稍稍增大以此进行平衡。
配置与应用(http://blog.163.com/lgh_2002/blog/static/4401752620107393057989/):
一、mysql master/slave配置
################
#mster/slave配置
################
master:192.168.1.51
slave:192.168.1.50
1、master配置
/etc/my.cnf 中加入
binlog-do-db=book book为数据库名确保
server-id=1
log-bin=mysql-bin
授权给rep用户进行复制操作
grant replication slave on book.* to rep@192.168.1.50 identified by '123456';
重启master服务
2、配置slave
vi /etc/my.cnf
设置下面4行
server-id = 2
master-host = 192.168.1.51
master-user = rep
master-password = 123456
重启slave
3、把master的原始数据导入slave。
二、sqlrelay配置
当前行业中比较流行的连接池解决方案几乎都不支持php,经过多番努力终于在找到了一个开源的连接池技术--------sqlrelay。
sqlreplay支持的语言:c c++ perl python php ruby java tcl zope。
sqlreplay支持的数据库:oracle mysql msql postgresql sybase ms sql server ibm db2 interbase sybase sqlite odbc ms access
基本思路:
1、配置2个实例用以最终处理业务
clubs-read
clubi-write
其中读取的 instance分别配置两个连接,且两个连接启动对等的连接数。
2、配置一个instance来调度读写操作,即clubr
通过router来区分读写连接不同的mysql数据库。
<?xml version="1.0"?> <!doctype instances system "sqlrelay.dtd"> <instances> <!-- club instance --> <instance id="clubs" port="9002" socket="/tmp/clubs.socket" dbase="mysql" connections="10" maxconnections="20" maxqueuelength="5" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none" maxquerysize="65536" maxstringbindvaluelength="4000" maxlobbindvaluelength="71680" idleclienttimeout="-1" maxlisteners="-1" listenertimeout="0"> <users> <user user="club" password="edb:club"/> </users> <connections> <connection connectionid="master51" string="host=192.168.1.51;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/> <connection connectionid="slave50" string="host=192.168.1.50;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/> </connections> </instance> <instance id="clubi" port="9003" socket="/tmp/clubi.socket" dbase="mysql" connections="10" maxconnections="40" maxqueuelength="5" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none" maxquerysize="65536" maxstringbindvaluelength="4000" maxlobbindvaluelength="71680" idleclienttimeout="-1" maxlisteners="-1" listenertimeout="0"> <users> <user user="club" password="edb:club"/> </users> <connections> <connection connectionid="master51" string="host=192.168.1.51;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/> </connections> </instance>
php.ini文件在系统中的优先级:phpinidir、注册表键值、环境变量%phprc%、php5的根目录(for cli),或者www的根目录(for sapi moudles)、windows目录(c:\windows)。
php5特征:加入了面向对象机制、对于xml的复杂处理、异常处理机制。
php6特征:
支持unicode:虽然unicode占用较多的空间,但unicode带来的便利性,远超过占用空间的缺点。php也可以在.ini文件中设定是否开启支持unicode。
命名空间:命名空间是一种避免因函数或者类之间的命名冲突,而使你的函数和类以及方法无法读取,而不使用前缀命名惯例的一种方法。
php6.0令人激动的web 2.0特性。
soap: 简单对象访问协议 (soap:simple object access protocol)soap 可以和现存的许多因特网协议和格式结合使用,包括:http、smtp、mime、rpc。
xml: 从php 5.1版本开始,xmlreader和xmlwriter就已经包含在php内核,它可以让它可以让xml编程更加轻松。
register globals 将被移除:它虽满方便的,但是却忽略会带来程序上安全性的隐患,php4.3.x版开始时,此项默认设置值即是关闭状态,php6后php3将完全无法使用。
magic quotes 将消失:magic quotes主要是自动转义需要转义的字符,此项功能移除叶符合大多数php开发者的心声。
safe mode 取消。
’var’ 别名为 ‘public’:在类中的var声明变成public的别名,相信是为了兼容php5而作的决定,php6现在也可以称作为oo语言了。
通过引用返回将出错:现在透过引用返回编译器将会报错 例如$a =& new b()、function &c(),oo语言默认就是引用,所以不需要再使用&了。 
zend.ze1 compatbility mode 将被移去 zend.ze1相容模式将被移去php5是为兼容旧有php4,所以在.ini中可选择是否开启相容模式。
freetype 1 and gd 1 support 将不见这两个是很久的libs,所以不再支持,gd1早已被现在的gd2取代了。
dl() 被移到 sapi 中dl()主要是让设计师加载extension libs,现在被移到 sapi 中。
register long array 去除从php5起默认是关闭,再php6中正式移除。
extension的变更:如xmlreader、xmlwriter将不再是以extension的方式出现,他们将被移入到php的核心之中默认是开启。
ereg extension将被放入pecl,代表着它将被移出php核心,这也是为了让路给新的正则表达式extension,此外,fileinfo extension 也将被导入php的核心之中。
apc将被导入核心:这是一个提高php性能的功能,现在它将被放入php核心中,并且可以选择是否启用apc。
告别asp风格的起始标签:原来是为了取悦asp开发者转向使用php,现今已经不再需要这种做法了。
php6.0除了增加新特性,一些会给系统带来不稳定因素和安全隐患的特性也将被取消,取消列表:magic_quotes、register_globals、register_long_arrays、safe_mode、magic_quotes。
以上就是php连接池详解的详细内容。
其它类似信息

推荐信息