溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2021-07-02 17:01:29 來源:億速云 閱讀:241 作者:chen 欄目:編程語言

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

nginx與php-fpm的進程模型

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

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

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

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

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

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

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

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é)議,當php-fpm啟動時,會啟動多個cgi解釋器進程。

web服務器可以發(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),直到運行結束、異常、用戶手動退出才會中斷運行的程序。

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

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

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

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

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

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

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

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

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

new太多對象,然后導致cpu負載上線讓全站死機的概念

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

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

什么是對象池

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

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

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

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

大并發(fā)下多個mysql連接導致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

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

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

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

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

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

連接池 保護mysql不崩潰

連接池是將已經(jīng)創(chuà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(){// 這里要判斷當前池還有沒有空閑的// 若沒有,則判斷當前已經(jīng)提供的服務數(shù)量大不大于最大數(shù)量   如果還沒有達到最大數(shù)量  可以向系統(tǒng)再申請一個資源到池中// 如果已經(jīng)達到最大數(shù)量,并且池內(nèi)沒有服務了,則進行短暫等等看看有沒有// 需要銷毀避免同一個連接多處使用,會沖突$connect = array_shift($this->pool);return $connect;//偽代碼}public function recovery($connect){$this->pool[] = $connect;}}

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

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

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

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

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

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

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

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

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

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

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

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

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

總結

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

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

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

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

php
AI