使用Phalcon+PHP-FPM構建PHP基於多進程的資料庫連接池

Posted by

之前看到網上有一篇文章說Phalcon和PHP沒有資料庫連接池,而swoole本身提供了很好的資料庫連接池。實際上這是一種誤解,PHP自身早就實現了持久化的資料庫連接。而Phalcon基於zephir寫的資料庫連接適配器,必然也是支持PHP自身實現的這種資料庫連接池。Phalcon基於C語言寫的ORM,配合PHP-FPM提供的多進程的PHP資料庫連接池,將提供性能極為強悍並且健壯的多進程資料庫連接池。苦逼的是我大Phalcon文檔太爛,根本就沒提到這方面的先天優勢。根本不需要swoole,nginx與php-fpm的黃金搭檔以及phalcon提供的高性能ORM,就能提供目前最好的PHP資料庫連接池解決方案。本文將詳述,有關PHP資料庫連接池的相關技術。

第一:PHP官方文檔有關持久化資料庫連接的有關闡述

下圖就是PHP官方網站,對於PHP持久化資料庫連接問題的一些闡述。

PHP官方文檔里有關資料庫連接池的描述
PHP官方文檔里有關持久化資料庫連接的描述

這裡需要特別注意的一個問題是,由於腳本語言的特殊性,PHP官方並不建議在鎖表或者事務操作的時候,使用PHP的持久化資料庫連接。如圖一所示,害怕資料庫鎖死

第二:PHP-FPM提供的進程復用機制給PHP提供了健壯的PHP資料庫連接池

下圖中所示的,就是PHP-FPM的配置文件。關於配置文件,PHPer都看得懂,我就不多說了。主要說說PHP-FPM帶來的PHP資料庫連接池的特色:

PHP官方文檔里有關phpfpm的配置文檔
PHP官方文檔里有關phpfpm的配置文檔

1,PHP-FPM一個進程對應一個持久化的資料庫連接;

2,所有PHP-FPM進程所創造的持久化資料庫連接,不能超過mysql的最大資料庫連接數的,默認max_connections為150個連接。所以,不管是動態還是靜態管理PHP-FPM進程,都需要注意PHP-FPM的進程數和mysql的最大連接數。

3,如果一個PHP請求,請求了多個不同資料庫的數據,創建了多個持久化的資料庫連接。那麼對應的PHP-FPM就會在一個進程內創建多個持久化的資料庫連接。這裡是一個比較坑的地方,所有PHPer都應該注意。

假設伺服器有100個PHP-FPM的進程,單個請求向5個不同的資料庫請求持久化連接的數據,那麼伺服器將會創建500個持久化的資料庫連接。

第三:PHP實現資料庫連接池的條件

php官方文檔里有關pdo持久化連接的示例和說明
php官方文檔里有關pdo持久化連接的示例和說明

如上圖中所示,只有在new Pdo()時使用了Pdo::PERSISTENT=ture屬性構造資料庫連接時,這個連接才會成為持久化的資料庫連接。但是問題來了,new Pdo()時,綁定了資料庫的地址、庫名和用戶名。也就是說,同一資料庫的同一用戶產生的資料庫連接,才會復用這個資料庫持久連接。

這是PHP資料庫連接池的另外一個問題。

第四:Phalcon框架支持PHP內置的資料庫連接池

雖然Phalcon官方文檔並沒有提及PDO的資料庫連接池,但是翻看Phalcon的PDO類的源代碼,就會發現Phalcon實際上是支持PDO的資料庫連接池。如下圖所示:

Phalcon框架源碼里有關Pdo的持久化連接的檢查
Phalcon框架源碼里有關Pdo的持久化連接的檢查

不僅僅支持PHP的資料庫連接池,而且他用C語言寫的ORM,性能要比所有的PHP語言寫的ORM要強很多。也就是說Phalcon的ORM及與PHP-FPM實現的資料庫連接池,就是目前PHP所有框架中資料庫連接池性能最強的。

yaf框架雖然路由性能比phalcon略好,但是由於沒有ORM,在拉取PHP所寫的ORM後,其ORM性能要比Phalcon內置的C語言所寫的PHQL要差。

第五:Phalcon項目內資料庫連接池的實現方式

Phalcon實現持久連接的方式很簡單,如下圖所示,配置文件里在註冊服務時添加一個PDO的參數即可。所有通過這個請求的資料庫連接,都將成為持久化的連接。

Phalcon框架里資料庫持久化連接的配置極其簡單
Phalcon框架里資料庫持久化連接的配置極其簡單

但是由於,PHP資料庫連接池的特殊性。最好通過註冊不同的資料庫連接服務,來區分不同的資料庫連接。甚至針對高查詢量的請求,創建帶有專用資料庫連接池的微服務,來實現與其他不需要資料庫連接池業務的區分。

在如今微服務大行其道的情況下,PHP這種需要區別對待的資料庫連接池,反而更容易使用了。

第六:關於需要鎖表操作和事務操作的資料庫連接池

PHP官方建議不要在鎖表和事務操作的時候,使用資料庫連接池。個人的看法是,一個項目中需要鎖表和事務操作的地方,往往並不多,兩者完全可以不走資料庫連接池。程序員可以通過其他辦法,盡量少寫鎖表操作。而對於並發較少的事務操作,用完連接就扔了,不走資料庫連接池也沒什麼不可。

畢竟鎖表和事務操作,真正需要用的並不是太多。實在不行的話,也可以用其他語言來寫吧。諸如:Java,Go,C#,.NET Core等,通過他們搭建少量的微服務專門服務於鎖表和事務操作作為補充,也未嘗不可。

文武雙全的總結

如本文所示,通過nginx+php-fpm+phalcon就能通過性能極好的ORM搭建基於多進程的資料庫連接池。根本不需要swoole擴展,就能實現php的資料庫連接池。而且這種基於多進程的資料庫連接池,比基於多線程的資料庫連接池更加健壯和安全。

PHP的Phalcon框架,跟隨PHP-FPM常駐內存,本身處理HTTP請求的性能極強。而且自帶C語言所寫的ORM,通過PHP-FPM實現基於多進程的資料庫連接池,再搭配Nginx強大的HTTP處理能力,這真是完美的Web組合啊。

公司同事用最新版的Go在本地測試,跑了7000每秒的並發請求。鳥哥之前做的測試,Phalcon可是能跑到14000的RQS。哈哈,我大Phalcon真是吊的飛起呢。以後加上JIT和數據類型,PHP未來會更加強大。

13 comments

  1. 按照您的這個觀點 任意php mvc框架 只要在創建連接時,設置了持久連接
    一樣能實現這個功能嘍?

Leave a Reply

電子郵件地址不會被公開。 必填項已用*標註

此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據