php對象池、連接池的意義是什么

這篇文章主要講解了“php對象池、連接池的意義是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“php對象池、連接池的意義是什么”吧!

我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站設(shè)計、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、東港ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的東港網(wǎng)站制作公司

nginx與php-fpm的進程模型

nginx采用多進程模型,啟動之后的進程將包含一個master多個worker進程。

master是worker的父進程,主要職責(zé)是用來管理worker進程的。

  • 向worker進程發(fā)送信號,如通知退出

  • 監(jiān)控worker狀態(tài),當(dāng)worker退出后(無論正常異常),可以重新啟動新的worker。

可以實現(xiàn)從容重啟:master進程在接收到信號后,會先重新加載配置,然后再啟動新進程開始接收新請求,并向所有老進程發(fā)送信號告知不再接收新請求并在處理完所有未處理完的請求后自動退出。

worker進程負(fù)責(zé)處理請求,如果是靜態(tài)文件則可以直接處理完,如果是php程序還需要調(diào)用php來處理,當(dāng)php處理完成時獲取php的返回,并返回給客戶端。

采用的是異步非堵塞,當(dāng)調(diào)用php的時候不會堵塞等待,會抽空處理下一個請求,當(dāng)php處理完成時恢復(fù)之前的請求并返回給客戶端。

php-fpm是php-cgi的管理器,在php >= 5.3.3就已經(jīng)集成在php中了。

它的出現(xiàn)提供了更好的php管理方式

  • 可以平滑停止/啟動php進程(重載配置生效)

  • 可以配置監(jiān)控多個端口和使用不同的配置

php腳本的解釋器是php-cgi

php-fpm是一個管理器,管理對象是php-cgi

php-fpm實現(xiàn)了fastcgi協(xié)議,當(dāng)php-fpm啟動時,會啟動多個cgi解釋器進程。

web服務(wù)器可以發(fā)送數(shù)據(jù)給php-fpm,php-fpm再把數(shù)據(jù)發(fā)給php-cgi處理。(跟nginx發(fā)送數(shù)據(jù)給php-fpm類似)

常駐內(nèi)存下程序的對象回收

常駐內(nèi)存程序是指把自己裝入內(nèi)存后將控制返回給操作系統(tǒng),直到運行結(jié)束、異常、用戶手動退出才會中斷運行的程序。

當(dāng)程序運行時,對象和變量將會一直存在。除非在程序中釋放銷毀。

高并發(fā)下頻繁new對象的資源占用

當(dāng)我們new一個對象的時候,需要先經(jīng)過這幾個步驟:類加載檢查、分配內(nèi)存空間、設(shè)置類的基本信息、調(diào)用初始化構(gòu)造函數(shù)。

首先我們看看構(gòu)造函數(shù)這一塊,這是在代碼中按我們的需求和意愿編寫的。
在這一塊中我們經(jīng)常會做一些配置檢測、數(shù)據(jù)初始化、數(shù)據(jù)庫連接(網(wǎng)絡(luò)io)等。

接下來是分配內(nèi)存空間

OS的內(nèi)存分配器一般是預(yù)先向OS申請一大段內(nèi)存。然后每次分配時,再將里面的一小段標(biāo)記為已分配,釋放的時候再標(biāo)記成未分配。

由于是有很多程序在運行,所以分配和釋放會交替存在,得到的結(jié)果可能是 分配1段-未分配1段-分配2段-未分配2段

一個一個的未分配就是內(nèi)存碎片,會占用額外的內(nèi)存,碎片不一定可以馬上被重復(fù)使用(當(dāng)分配不出連續(xù)內(nèi)存時,需要向OS申請更多的內(nèi)存)

同時,創(chuàng)建和銷毀對象時,OS都需要做一些處理工作,也會產(chǎn)生資源占用。

new太多對象,然后導(dǎo)致cpu負(fù)載上線讓全站死機的概念

若程序未產(chǎn)生IO(網(wǎng)絡(luò)請求、讀寫文件等),執(zhí)行時間等于cpu的占用時間。

頻繁地創(chuàng)建銷毀對象將會占用更多cpu資源,高并發(fā)時容易導(dǎo)致cpu長期處于高負(fù)載運行狀態(tài)。

什么是對象池

對象池就是一個在程序啟動的時候先創(chuàng)建好若干個可以重復(fù)使用的對象。

當(dāng)程序其他地方需要使用該類型對象時,不再是向系統(tǒng)申請創(chuàng)建,而是向池發(fā)出請求。

池將會從池內(nèi)發(fā)配出一個對象提供使用,當(dāng)程序使用完畢后,需要將對象歸還給對象池做管理。

對象池服務(wù)可以減少從頭創(chuàng)建每個對象的系統(tǒng)開銷。

大并發(fā)下多個MySQL連接導(dǎo)致mysql繁忙全站崩潰

<?phpfunction db(){return mysqli_connect("localhost","root","root"); }for ($i=0; $i < 10000; $i++) { $name  = "db{$i}";$$name = db();}

這一個demo將會產(chǎn)生報錯:Warning: mysqli_connect(): (08004/1040): Too many connections

我們習(xí)慣性地在PHP腳本中不會主動關(guān)閉mysql連接,而是等到腳本運行完畢之后再由gc自動回收。在這個期間將會繼續(xù)占用連接資源,而連接資源的數(shù)量又是有限制的,所以會更快出現(xiàn)連接不夠用的情況。

處理會影響程序的運行,同時還將可能導(dǎo)致全站崩潰。

  • mysql是一個連接創(chuàng)建一個線程處理。

  • 創(chuàng)建銷毀mysql線程需要的內(nèi)存等性能消耗、線程緩存命中率下降

  • mysql底層幾乎在同時需要處理幾百個線程提交的查詢請求,而cpu一次只能處理一條指令,并且數(shù)據(jù)庫查詢需要產(chǎn)生IO,在IO期間cpu將會切換上下文處理其他的請求,當(dāng)cpu頻繁切換上下文,性能抖動,發(fā)生性能下降甚至宕機的情況。

連接池 保護mysql不崩潰

連接池是將已經(jīng)創(chuàng)建好的連接保存在池中,當(dāng)有請求來時,直接使用已經(jīng)創(chuàng)建好的連接對數(shù)據(jù)庫進行訪問。

<?phpclass Pool{private $pool = [];private $min = 5;private $max = 100;private $now;public function __construct(){// 在池創(chuàng)建的時候就先創(chuàng)建好一些連接for ($i = 0 ; $i < $this->min; $i++){$this->pool[] = mysqli_connect("localhost","root","root");$this->now++;}}public function get(){// 這里要判斷當(dāng)前池還有沒有空閑的// 若沒有,則判斷當(dāng)前已經(jīng)提供的服務(wù)數(shù)量大不大于最大數(shù)量   如果還沒有達到最大數(shù)量  可以向系統(tǒng)再申請一個資源到池中// 如果已經(jīng)達到最大數(shù)量,并且池內(nèi)沒有服務(wù)了,則進行短暫等等看看有沒有// 需要銷毀避免同一個連接多處使用,會沖突$connect = array_shift($this->pool);return $connect;//偽代碼}public function recovery($connect){$this->pool[] = $connect;}}

因為連接池需要長期保持在線,在傳統(tǒng)的php腳本中不支持,在swoole中可以常駐內(nèi)存運行,即可使用連接池

這樣省略了創(chuàng)建連接和銷毀連接的過程。這樣性能上得到了提高。

然而除了性能上的提高外,還有一個意義也很重要:保護服務(wù)穩(wěn)定運行,不發(fā)生全站崩潰。

在上面一點我們已經(jīng)提到,更多的鏈接將會導(dǎo)致cpu頻繁切換上下文,性能抖動,嚴(yán)重情況時將會全站崩潰。

假設(shè)本來我們的服務(wù)器配置是可以保證1000個連接同時穩(wěn)定運行,突然某一時刻有3000個人并發(fā),導(dǎo)致連接不夠用,那么是保證原有1000人都正常運行好,還是讓這3000人爭搶資源最終導(dǎo)致機器響應(yīng)不了全站崩潰好呢?

連接池的意義此時才得以體現(xiàn),我們設(shè)置連接池的最大數(shù)量為機器能承受并且穩(wěn)定運行的最大數(shù)量。

當(dāng)已經(jīng)有這么多的數(shù)量在服務(wù)的時候,后面的請求申請連接資源時需要進行短暫的等待,若時間到了還是沒有空余連接提供,則需要熔斷服務(wù),返回給客戶端失敗。

這樣子可以保證機器長期穩(wěn)定服務(wù)。若是越來越多的客戶端申請不到資源,則需要提高機器配置。(因為我們的連接池最大數(shù)量已經(jīng)是機器的瓶頸,只能通過硬件配置來提升能服務(wù)的數(shù)量)

nginx – php fpm在大并發(fā)下504

在最開始的時候已經(jīng)介紹過nginx和php的運行進程模型,php-fpm就是一個池管理器,內(nèi)部裝了若干個php-cgi程序,當(dāng)nginx申請解析php腳本時,php-fpm則分配一個php-cgi出去處理,處理完則收回管理。

在高并發(fā)下,nginx會產(chǎn)生504錯誤,這就是我們上面介紹到的,客戶端進行了短暫的 等待 后,仍然申請不到資源,則只能告訴客戶端失敗。

(在京東、淘寶的大活動期間很有機會碰到504錯誤哦! 這種情況下我們一般只需要刷新頁面即可。 因為再刷新時大幾率已經(jīng)有連接資源空閑了?。?/p>

  • Nginx 504 Gateway Time-out的含義是沒有請求到可以執(zhí)行的PHP-CGI。

總結(jié)

連接池、對象池的意義不僅僅是可以減少頻繁創(chuàng)建銷毀對象連接的性能開銷

更大的意義是可以保證應(yīng)有服務(wù)客戶端的穩(wěn)定運行。

感謝各位的閱讀,以上就是“php對象池、連接池的意義是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對php對象池、連接池的意義是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

當(dāng)前題目:php對象池、連接池的意義是什么
文章鏈接:http://bm7419.com/article8/iihdip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號、網(wǎng)站制作面包屑導(dǎo)航、全網(wǎng)營銷推廣、品牌網(wǎng)站設(shè)計搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化