為什么要推薦使用現(xiàn)代化PHP框架?
概述
PHP語言從1995年發(fā)布,至今已經(jīng)有29多年的歷史,在期間涌現(xiàn)了成千上萬的MVC框架,大致可以將其分為以下三大類:
公司內(nèi)部自研
有大量的公司會自研MVC框架,會根據(jù)自身業(yè)務(wù)的特性打造適合自身的PHP框架。
PHP開源框架
現(xiàn)PHP開源社區(qū)流行的PHP MVC框架有Yii、Laravel、CodeIgniter、ZendFrameWork、Symfony等;
C擴展
純C擴展的PHP MVC框架由于研發(fā)難度大,不易修改,學(xué)習(xí)成本相對較高,故直到近幾年才出現(xiàn),比如Yaf、Phalcon等。
上述三類的PHP MVC運行的環(huán)境為LA(N)MP,而且其中的A(N)是不可或缺的,也就是說他們都需要依賴Web Server來承接用戶的請求,將請求轉(zhuǎn)發(fā)給PHP進程,解析并執(zhí)行PHP代碼,而這樣的工作模式是所有PHPer根深蒂固的認(rèn)知,甚至筆者在前幾年聽到有人說我們可以拋棄php-fpm,nginx,心想簡直是無稽之談。
隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,大量公司的后端技術(shù)架構(gòu)都在往微服務(wù)架構(gòu)變遷,微服務(wù)架構(gòu)要求我們盡可能的將我們的業(yè)務(wù)拆分到獨立的部署單元,當(dāng)然微服務(wù)框架的好處是很“誘人”的,但是它會帶來大量的成本開銷和性能開銷,如何在微服務(wù)架構(gòu)實踐中節(jié)約成本和提升性能是我們不可邁過的溝壑。
那在PHP生態(tài)中傳統(tǒng)的LA(N)MP能滿足微服務(wù)框架的需求嗎?
答案顯然是不能的。就目前PHP的fastcgi進程管理器php-fpm和nginx的配合已經(jīng)運行得足夠好,但是由于php-fpm本身是同步阻塞進程模型,在請求結(jié)束后釋放所有的資源(包括框架初始化創(chuàng)建的一系列對象),導(dǎo)致PHP進程空轉(zhuǎn)(創(chuàng)建銷毀創(chuàng)建) 消耗大量的CPU資源,從而導(dǎo)致單機的吞吐能力有限。
我們是不是應(yīng)該切換開發(fā)語言?
先簡單的來看換開發(fā)語言,一個公司或者團隊切換開發(fā)語言的成本是巨大的,它直接面臨著放棄已有的技術(shù)沉淀,學(xué)習(xí)新的語言生態(tài)和習(xí)慣做法,并將現(xiàn)有業(yè)務(wù)的全面重構(gòu),同時整個運維技術(shù)棧也要同步更新,需要踩過無數(shù)個“坑”,所以我們這里暫不展開去講切換開發(fā)語言來解決我們的核心問題。
那我們還有什么解決方案?
我們分析我們的業(yè)務(wù)不難發(fā)現(xiàn),90%以上的業(yè)務(wù)都是IO密集性業(yè)務(wù),我們只需要提高IO復(fù)用的能力就可以提升單機吞吐能力,另外需要將php-fpm同步阻塞模式替換為異步非阻塞模式,當(dāng)然不一定使用php-fpm,就可以解決我們的核心問題——性能。不幸的是目前PHP生態(tài)中還沒有一個工程級別的MVC框架能夠滿足我們的需求。
綜上所述,我們需要使用全新的現(xiàn)代化的PHP框架Webman,為微服務(wù)架構(gòu)打下堅實的基礎(chǔ)。
PHP-FPM工作模式的問題
圖片
- Nginx基于epoll事件模型,一個worker同時可處理多個請求
 - fpm-worker在同一時刻可處理一個請求
 - master進程只負(fù)責(zé)處理worker進程的監(jiān)控、日志等
 - 用戶端請求由elb解析,再經(jīng)過nginx解析
 - fpm-worker每次處理請求前需要重新初始化mvc框架,然后再釋放資源
 - 高并發(fā)請求時,fpm-worker不夠用,nginx直接響應(yīng)502
 - fpm-worker進程間切換消耗大(如某線上業(yè)務(wù)在4核8G內(nèi)存服務(wù)器實質(zhì)可利用16個進程)
 
壓測數(shù)據(jù)對比
目標(biāo)
- 對比在相同硬件條件下,PHP Yii2框架在PHP-5.6及PHP7下echo hello world的QPS,并觀察平均響應(yīng)時間及CPU。
 - 對比現(xiàn)有某服務(wù)在PHP-5.6及PHP7下的QPS
 
工具
ApacheBench即ab。ab -n xx -c xx -k http://www.tinywan.com/
硬件
aws c4.xlarge(4核8G)
Hello World
PHP-5.6/Yii2
開啟opcache,64個php-fpm進程,輸出hello world
n  | c  | qps  | 平均響應(yīng)時間(ms)  | CPU  | 
10000  | 1  | 662.73  | 1.509  | 6%  | 
50000  | 10  | 1435.35  | 6.967  | 76%  | 
500000  | 20  | 1577.16  | 13.375  | 83%  | 
500000  | 50  | 1626.09  | 145.953  | 89%  | 
PHP-7/Yii2
開啟opcache,64個php-fpm進程,輸出hello world
n  | c  | qps  | 平均響應(yīng)時間(ms)  | CPU  | 
10000  | 1  | 854.81  | 1.170  | 18%  | 
50000  | 10  | 2008.32  | 4.979  | 62%  | 
500000  | 20  | 2186.90  | 9.145  | 65%  | 
500000  | 50  | 2304.98  | 21.692  | 69%  | 
500000  | 200  | 2331.93  | 85.766  | 69%  | 
某服務(wù)
- 1次Redis Get
 - 1次 MongoDB Query
 - 2個廣告接口
 - 2個業(yè)務(wù)接口
 
PHP-5.6/Yii2
n  | c  | qps  | 平均響應(yīng)時間(ms)  | CPU  | 
100  | 1  | 4.16  | 240.168  | 9%  | 
5000  | 5  | 15.36  | 325.502  | 46%  | 
5000  | 10  | 18.72  | 534.141  | 83%  | 
5000  | 50  | 19.03  | 2627.159  | 99%  | 
PHP-7/Yii2
n  | c  | qps  | 平均響應(yīng)時間(ms)  | CPU  | 
100  | 1  | 3.51  | 284.876  | 5%  | 
5000  | 5  | 17.23  | 290.129  | 21%  | 
5000  | 10  | 32.36  | 309.057  | 40%  | 
5000  | 20  | 52.94  | 377.784  | 82%  | 
5000  | 40  | 55.52  | 720.433  | 91%  | 
結(jié)論
- PHP-5.6升級PHP-7.0,Yii2框架的性能提升43%
 - PHP-5.6升級PHP-7.0,某服務(wù)性能提升170%
 - 單純將業(yè)務(wù)升級PHP-7.0,能夠提升很大的性能
 















 
 
 










 
 
 
 