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:一個開源的資料庫池串連Proxy 伺服器。支援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) (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核心,這也是為了讓路給新的Regexextension,此外,Fileinfo extension 也將被匯入PHP的核心之中。
APC將被匯入核心:這是一個提高PHP效能的功能,現在它將被放入PHP核心中,並且可以選擇是否啟用APC。
告別ASP風格的起始標籤:原來是為了取悅ASP開發人員轉向使用PHP,現今已經不再需要這種做法了。
PHP6.0除了增加新特性,一些會給系統帶來不穩定因素和安全隱患的特性也將被取消,取消列表:magic_quotes、register_globals、register_long_arrays、safe_mode、magic_quotes。