您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)PHP如何使用數(shù)據(jù)庫(kù)永久連接方式操作MySQL的是與非,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
PHP程序員應(yīng)該都知道連接MySQL數(shù)據(jù)庫(kù)可以使用mysql_pconnect(永久連接)函數(shù),使用數(shù)據(jù)庫(kù)永久連接可以提高效率,但是實(shí)際應(yīng)用中數(shù)據(jù)庫(kù)永久連接往往會(huì)導(dǎo)致出現(xiàn)一些問(wèn)題,通常的表現(xiàn)就是在大訪問(wèn)量的網(wǎng)站上時(shí)常發(fā)生斷斷續(xù)續(xù)的無(wú)法連接數(shù)據(jù)庫(kù)的情況,出現(xiàn)類(lèi)似"Too many connections in ..."的錯(cuò)誤提示信息,重新啟動(dòng)服務(wù)器又正常了,但過(guò)不了一會(huì)兒又出現(xiàn)同樣的故障。對(duì)于這些問(wèn)題的成因,恐怕就不是每個(gè)人都能說(shuō)清楚的了,雖然PHP文檔里有一些相關(guān)資料,但是解釋的并不淺顯易懂,這里我厚著臉皮試圖做一個(gè)簡(jiǎn)單的討論,所述觀點(diǎn)不見(jiàn)得全都正確。
首先看看數(shù)據(jù)庫(kù)永久連接的定義:
永久的數(shù)據(jù)庫(kù)連接是指在腳本結(jié)束運(yùn)行時(shí)不關(guān)閉的連接。當(dāng)收到一個(gè)永久連接的請(qǐng)求時(shí)。PHP 將檢查是否已經(jīng)存在一個(gè)(前面已經(jīng)開(kāi)啟的)相同的永久連接。如果存在,將直接使用這個(gè)連接;如果不存在,則建立一個(gè)新的連接。所謂“相同”的連接是指用相同的用戶名和密碼到相同主機(jī)的連接。
PHP使用永久連接方式操作MySQL是有前提的:就是PHP必須安裝為多線程或多進(jìn)程Web服務(wù)器的插件或模塊。最常見(jiàn)的形式是把PHP用作多進(jìn)程Apache服務(wù)器的一個(gè)模塊。對(duì)于一個(gè)多進(jìn)程的服務(wù)器,其典型特征是有一個(gè)父進(jìn)程和一組子進(jìn)程協(xié)調(diào)運(yùn)行,其中實(shí)際生成Web頁(yè)面的是子進(jìn)程。每當(dāng)客戶端向父進(jìn)程提出請(qǐng)求時(shí),該請(qǐng)求會(huì)被傳遞給還沒(méi)有被其它的客戶端請(qǐng)求占用的子進(jìn)程。這也就是說(shuō)當(dāng)相同的客戶端第二次向服務(wù)端提出請(qǐng)求時(shí),它將有可能被一個(gè)不同的子進(jìn)程來(lái)處理。在開(kāi)啟了一個(gè)永久連接后,所有不同子進(jìn)程請(qǐng)求SQL服務(wù)的后繼頁(yè)面都能夠重新使用這個(gè)已經(jīng)建立的 SQL服務(wù)器連接。它使得每個(gè)子進(jìn)程在其生命周期中只做一次連接操作,而非每次在處理一個(gè)頁(yè)面時(shí)都要向 SQL 服務(wù)器提出連接請(qǐng)求。每個(gè)子進(jìn)程將對(duì)服務(wù)器建立各自獨(dú)立的永久連接。PHP本身并沒(méi)有數(shù)據(jù)庫(kù)連接池的概念,但是Apache有進(jìn)程池的概念, 一個(gè)Apache子進(jìn)程結(jié)束后會(huì)被放回進(jìn)程池, 這也就使得用mysql_pconnect打開(kāi)的的那個(gè)mysql連接資源可以不被釋放,而是依附在相應(yīng)的Apache子進(jìn)程上保存到了進(jìn)程池中。于是在下一個(gè)連接請(qǐng)求時(shí)它就可以被復(fù)用。一切看起來(lái)似乎都很正常,但是在Apache并發(fā)訪問(wèn)量大的時(shí)候,如果使用mysql_pconnect,會(huì)由于之前的 Apache子進(jìn)程占用的MySQL連接沒(méi)有close, 很快使MySQL達(dá)到最大連接數(shù),使得之后的請(qǐng)求可能得不到響應(yīng)。
上面的部分文字是摘抄自PHP文檔,看起來(lái)可能還是有些文縐縐的不好理解,那么我就用大白話再舉一個(gè)例子來(lái)說(shuō)明問(wèn)題:
假設(shè)Apache配置最大連接數(shù)為1000,MySQL配置最大連接數(shù)為100,當(dāng)Apache服務(wù)器接到200個(gè)并發(fā)訪問(wèn)的時(shí)候,其中100個(gè)涉及到數(shù)據(jù)庫(kù)訪問(wèn),剩下的100個(gè)不涉及數(shù)據(jù)庫(kù)訪問(wèn),因?yàn)檫@個(gè)時(shí)候還不存在可用的數(shù)據(jù)庫(kù)連接,所以這里面涉及到數(shù)據(jù)庫(kù)訪問(wèn)的100個(gè)并發(fā)會(huì)同時(shí)產(chǎn)生100個(gè)數(shù)據(jù)庫(kù)永久連接,達(dá)到了數(shù)據(jù)庫(kù)最大連接數(shù),當(dāng)這些操作沒(méi)有結(jié)束的時(shí)候,任何其他的連接都無(wú)法再獲得數(shù)據(jù)庫(kù)連接,當(dāng)這些操作結(jié)束了,相應(yīng)的連接會(huì)被放入進(jìn)程池,此時(shí)Apache的進(jìn)程池里就有了200個(gè)空閑的子進(jìn)程,其中100個(gè)是帶有數(shù)據(jù)庫(kù)連接的,由于Apache會(huì)為訪問(wèn)請(qǐng)求隨機(jī)的挑選空閑子進(jìn)程,所以你得到的子進(jìn)程很可能是不包含數(shù)據(jù)庫(kù)連接的那100個(gè)中的一個(gè),而數(shù)據(jù)庫(kù)連接已經(jīng)達(dá)到了最大值,你也不可能成功的建立新的數(shù)據(jù)庫(kù)連接,唉,你便只好不停的刷新頁(yè)面,哪個(gè)時(shí)候運(yùn)氣好,碰巧分配到了帶有數(shù)據(jù)庫(kù)連接的子進(jìn)程,才能正常瀏覽頁(yè)面。如果是大訪問(wèn)量的網(wǎng)站來(lái)說(shuō),任何時(shí)候都可能存在大量的并發(fā),所以瀏覽者可能就會(huì)不停的發(fā)現(xiàn)無(wú)法連接數(shù)據(jù)庫(kù)的現(xiàn)象了。
或許你會(huì)說(shuō),我們把Apache和MySQL的最大連接數(shù)調(diào)成一樣大不就可以了么?是的,合理的調(diào)整這個(gè)最大連接數(shù)某種程度上會(huì)避免這個(gè)問(wèn)題的發(fā)生,但是Apache和MySQL的負(fù)載能力是不同的,如果按照Apache的負(fù)載能力來(lái)設(shè)置,對(duì)于MySQL來(lái)說(shuō),這個(gè)最大連接數(shù)就偏大,會(huì)產(chǎn)生大量的 MySQL數(shù)據(jù)庫(kù)永久連接,打個(gè)比方,就好像和平時(shí)代還要養(yǎng)活一個(gè)幾百萬(wàn)的軍隊(duì)一樣,其開(kāi)銷(xiāo)得不償失;而如果按照Mysql的負(fù)載能力設(shè)置,對(duì)于 Apache來(lái)說(shuō),這個(gè)最大連接數(shù)就偏小,有點(diǎn)殺雞牛刀的感覺(jué),無(wú)法發(fā)揮Apache的最大效率。
所以按照PHP手冊(cè)上的介紹,只適合在并發(fā)訪問(wèn)不大的網(wǎng)站上使用數(shù)據(jù)庫(kù)永久連接,但對(duì)于一個(gè)并發(fā)訪問(wèn)不大的網(wǎng)站來(lái)說(shuō),使用數(shù)據(jù)庫(kù)永久連接帶來(lái)的效率提高似乎沒(méi)有太大的意義,從這個(gè)角度上來(lái)看,我覺(jué)得PHP中的數(shù)據(jù)庫(kù)永久連接基本上是一個(gè)雞肋的角色,如果你一定要使用數(shù)據(jù)庫(kù)連接池的概念,可以嘗試一下sqlrelay或者Apache本身提供的mod_dbd,說(shuō)不定會(huì)有驚喜。
關(guān)于“PHP如何使用數(shù)據(jù)庫(kù)永久連接方式操作MySQL的是與非”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。