php多進(jìn)程單線(xiàn)程之php-cgi溉贿、php-fpm

php多進(jìn)程單線(xiàn)程之php-cgi枫吧、php-fpm

php從代碼級(jí)別的執(zhí)行上是單線(xiàn)程的, 但是由php-fpm進(jìn)程管理機(jī)制是多進(jìn)程單線(xiàn)程的, 也就是php是多進(jìn)程執(zhí)行的. 有效提高并發(fā)的響應(yīng)效率。

了解關(guān)于cgi宇色、fastCGI九杂、php-cgi、php-fpm的概念更能加深理解宣蠕。
下面是我查閱大量資料后整理的關(guān)系圖供大家參考例隆,也歡迎留言一起討論

image.png

1. CGI

CGI全稱(chēng)是“公共網(wǎng)關(guān)接口”(Common Gateway Interface),HTTP服務(wù)器與你的或其它機(jī)器上的程序進(jìn)行“交談”的一種工具抢蚀,其程序須運(yùn)行在網(wǎng)絡(luò)服務(wù)器上(在fastcig未使用前是運(yùn)行在網(wǎng)絡(luò)服務(wù)器上的镀层,具體請(qǐng)看下文)。CGI可以用任何一種語(yǔ)言編寫(xiě)皿曲,只要這種語(yǔ)言具有標(biāo)準(zhǔn)輸入唱逢、輸出和環(huán)境變量吴侦。如php,perl,tcl等。cgi是一個(gè)web server與cgi程序(這里可以理解為是php解釋器)之間進(jìn)行數(shù)據(jù)傳輸?shù)膮f(xié)議坞古,保證了傳遞的是標(biāo)準(zhǔn)數(shù)據(jù)备韧。

2. FastCGI

FastCGI像是一個(gè)常駐(long-live)型的CGI,它可以一直執(zhí)行著绸贡,只要激活后盯蝴,不會(huì)每次都要花費(fèi)時(shí)間去fork一次(這是CGI最為人詬病的fork-and-execute 模式)毅哗。它還支持分布式的運(yùn)算听怕,即 FastCGI 程序可以在網(wǎng)站服務(wù)器以外的主機(jī)上執(zhí)行并且接受來(lái)自其它網(wǎng)站服務(wù)器來(lái)的請(qǐng)求。

FastCGI是語(yǔ)言無(wú)關(guān)的虑绵、可伸縮架構(gòu)的CGI開(kāi)放擴(kuò)展尿瞭,其主要行為是將CGI解釋器進(jìn)程保持在內(nèi)存中并因此獲得較高的性能。眾所周知翅睛,CGI解釋器的反復(fù)加載是CGI性能低下的主要原因声搁,如果CGI解釋器保持在內(nèi)存中并接受FastCGI進(jìn)程管理器調(diào)度,則可以提供良好的性能捕发、伸縮性疏旨、Fail- Over特性等等

2.1 FastCGI特點(diǎn)

FastCGI具有語(yǔ)言無(wú)關(guān)性.

FastCGI在進(jìn)程中的應(yīng)用程序,獨(dú)立于核心web服務(wù)器運(yùn)行扎酷,提供了一個(gè)比API更安全的環(huán)境檐涝。APIs把應(yīng)用程序的代碼與核心的web服務(wù)器鏈接在一起,這意味著在一個(gè)錯(cuò)誤的API的應(yīng)用程序可能會(huì)損壞其他應(yīng)用程序或核心服務(wù)器法挨。 惡意的API的應(yīng)用程序代碼甚至可以竊取另一個(gè)應(yīng)用程序或核心服務(wù)器的密鑰谁榜。

FastCGI技術(shù)目前支持語(yǔ)言有:C/C++、Java凡纳、Perl窃植、Tcl、Python荐糜、SmallTalk巷怜、Ruby等。相關(guān)模塊在A(yíng)pache, ISS, Lighttpd等流行的服務(wù)器上也是可用的暴氏。

FastCGI的不依賴(lài)于任何Web服務(wù)器的內(nèi)部架構(gòu)丛版,因此即使服務(wù)器技術(shù)的變化, FastCGI依然穩(wěn)定不變。

2.2 FastCGI的工作原理

Web Server啟動(dòng)時(shí)載入FastCGI進(jìn)程管理器(IIS ISAPI或Apache Module)

FastCGI進(jìn)程管理器自身初始化偏序,啟動(dòng)多個(gè)CGI解釋器進(jìn)程(可見(jiàn)多個(gè)php-cgi)并等待來(lái)自Web Server的連接页畦。

當(dāng)客戶(hù)端請(qǐng)求到達(dá)Web Server時(shí),F(xiàn)astCGI進(jìn)程管理器選擇并連接到一個(gè)CGI解釋器研儒。Web server將CGI環(huán)境變量和標(biāo)準(zhǔn)輸入發(fā)送到FastCGI子進(jìn)程php-cgi豫缨。

FastCGI子進(jìn)程完成處理后將標(biāo)準(zhǔn)輸出和錯(cuò)誤信息從同一連接返回Web Server独令。當(dāng)FastCGI子進(jìn)程關(guān)閉連接時(shí),請(qǐng)求便告處理完成好芭。FastCGI子進(jìn)程接著等待并處理來(lái)自FastCGI進(jìn)程管理器(運(yùn)行在Web Server中)的下一個(gè)連接燃箭。 在CGI模式中,php-cgi在此便退出了舍败。

在上述情況中招狸,你可以想象CGI通常有多慢。每一個(gè)Web請(qǐng)求PHP都必須重新解析php.ini邻薯、重新載入全部擴(kuò)展并重初始化全部數(shù)據(jù)結(jié)構(gòu)裙戏。使用FastCGI,所有這些都只在進(jìn)程啟動(dòng)時(shí)發(fā)生一次厕诡。一個(gè)額外的好處是累榜,持續(xù)數(shù)據(jù)庫(kù)連接(Persistent database connection)可以工作。

2.3 FastCGI的不足

因?yàn)槭嵌噙M(jìn)程灵嫌,所以比CGI多線(xiàn)程消耗更多的服務(wù)器內(nèi)存壹罚,PHP-CGI解釋器每進(jìn)程消耗7至25兆內(nèi)存,將這個(gè)數(shù)字乘以50或100就是很大的內(nèi)存數(shù)寿羞。

Nginx 0.8.46+PHP 5.2.14(FastCGI)服務(wù)器在3萬(wàn)并發(fā)連接下猖凛,開(kāi)啟的10個(gè)Nginx進(jìn)程消耗150M內(nèi)存(15M10=150M),開(kāi)啟的64個(gè)php-cgi進(jìn)程消耗1280M內(nèi)存(20M64=1280M)绪穆,加上系統(tǒng)自身消耗的內(nèi)存辨泳,總共消耗不到2GB內(nèi)存。如果服務(wù)器內(nèi)存較小霞幅,完全可以只開(kāi)啟25個(gè)php-cgi進(jìn)程漠吻,這樣php-cgi消耗的總內(nèi)存數(shù)才500M。

上面的數(shù)據(jù)摘自Nginx 0.8.x + PHP 5.2.13(FastCGI)搭建勝過(guò)Apache十倍的Web服務(wù)器(第6版)

3. PHP-CGI

php-cgi 是 php 的解釋器司恳,就是上文提到的cgi程序途乃。

關(guān)于PHP-CGI是PHP自帶的FastCGI管理器的說(shuō)法。
我是這么理解的:第一:CGI解釋器(php-cgi)保持在內(nèi)存中并接受FastCGI進(jìn)程管理器調(diào)度扔傅,則可以提供良好的性能耍共、伸縮性、Fail- Over特性等等猎塞,也就是在fast-cgi層面是管理著多個(gè)CGI程序(php-cgi)的進(jìn)程的.第二:fpm官方的解釋是:FPM(FastCGI 進(jìn)程管理器)用于替換 PHP FastCGI 的大部分附加功能试读,對(duì)于高負(fù)載網(wǎng)站是非常有用的(https://www.php.net/manual/zh/install.fpm.php)。
所以我不認(rèn)同PHP-CGI是PHP自帶的FastCGI管理器的說(shuō)法荠耽。

3.1 PHP-CGI 的不足

php-cgi變更php.ini配置后需重啟php-cgi才能讓新的php-ini生效钩骇,不可以平滑重啟。

直接殺死php-cgi進(jìn)程,php就不能運(yùn)行了倘屹。(PHP-FPM和Spawn-FCGI就沒(méi)有這個(gè)問(wèn)題银亲,守護(hù)進(jìn)程會(huì)平滑從新生成新的子進(jìn)程。)

4. PHP-FPM(php Fastcgi Process Manager)

PHP-FPM是一個(gè)PHP FastCGI管理器纽匙,是只用于PHP的务蝠,可以在 http://php-fpm.org/download下載得到。

PHP-FPM其實(shí)是PHP源代碼的一個(gè)補(bǔ)丁烛缔,旨在將FastCGI進(jìn)程管理整合進(jìn)PHP包中馏段。必須將它patch到你的PHP源代碼中,在編譯安裝PHP后才可以使用践瓷。

現(xiàn)在我們可以在最新的PHP 5.3.2的源碼樹(shù)里下載得到直接整合了PHP-FPM的分支院喜,據(jù)說(shuō)下個(gè)版本會(huì)融合進(jìn)PHP的主分支去。相對(duì)Spawn-FCGI当窗,PHP-FPM在CPU和內(nèi)存方面的控制都更勝一籌够坐,而且前者很容易崩潰寸宵,必須用crontab進(jìn)行監(jiān)控崖面,而PHP-FPM則沒(méi)有這種煩惱。

PHP5.3.3已經(jīng)集成php-fpm了梯影,不再是第三方的包了巫员。PHP-FPM提供了更好的PHP進(jìn)程管理方式,可以有效控制內(nèi)存和進(jìn)程甲棍、可以平滑重載PHP配置简识,比spawn-fcgi具有更多有點(diǎn),所以被PHP官方收錄了感猛。在./configure的時(shí)候帶 –enable-fpm參數(shù)即可開(kāi)啟PHP-FPM七扰。

5 PHP對(duì)并發(fā)訪(fǎng)問(wèn)的處理

5.1 進(jìn)程和線(xiàn)程

PHP從代碼級(jí)別來(lái)講不支持多線(xiàn)程操作,不能像Java陪白、C#等語(yǔ)言一樣可以編寫(xiě)多線(xiàn)程代碼颈走。但多線(xiàn)程和并發(fā)沒(méi)有直接關(guān)系,多線(xiàn)程只是代碼被運(yùn)行時(shí)在同一時(shí)間同時(shí)執(zhí)行多個(gè)線(xiàn)程任務(wù)咱士,來(lái)提高服務(wù)器CPU的利用率立由,提高代碼效率。但php是可以多進(jìn)程執(zhí)行的序厉,上文所述的FPM進(jìn)程管理機(jī)制就是多進(jìn)程單線(xiàn)程的锐膜,有效提高了并發(fā)訪(fǎng)問(wèn)的響應(yīng)效率。

5.2 簡(jiǎn)單的web server + php-fpm 模式

  1. 當(dāng)客戶(hù)端發(fā)送一個(gè)請(qǐng)求時(shí)弛房,web server會(huì)通過(guò)一個(gè)php-fpm進(jìn)程(這里和下文所說(shuō)指的fpm進(jìn)程都是fpm開(kāi)啟的worker進(jìn)程道盏,關(guān)于fpm的工作原理這里不再累述)去執(zhí)行php代碼,php代碼的執(zhí)行是單線(xiàn)程的。
  2. 那么荷逞,當(dāng)有多個(gè)客戶(hù)端同時(shí)發(fā)送請(qǐng)求時(shí)(并發(fā))牺堰,web server會(huì)通過(guò)php-fpm為每個(gè)請(qǐng)求開(kāi)啟一個(gè)單獨(dú)進(jìn)程去執(zhí)行php代碼。
  3. 請(qǐng)求執(zhí)行過(guò)后颅围,空閑的php-fpm進(jìn)程被銷(xiāo)毀伟葫,內(nèi)存得以釋放。
  4. 但并發(fā)的問(wèn)題在于院促,在某一時(shí)間筏养,客戶(hù)端請(qǐng)求讓php-fpm進(jìn)程數(shù)量達(dá)到了最大限制數(shù),這個(gè)時(shí)候常拓,新來(lái)的請(qǐng)求只能等待空閑的php-fpm進(jìn)程來(lái)處理渐溶,這就是多進(jìn)程同步阻塞模式的弊端,當(dāng)然還有進(jìn)程過(guò)多所帶來(lái)的內(nèi)存占用問(wèn)題弄抬。

6茎辐。 高并發(fā)和多線(xiàn)程

“高并發(fā)和多線(xiàn)程”總是被一起提起,給人感覺(jué)兩者好像相等掂恕,實(shí)則 高并發(fā) ≠ 多線(xiàn)程拖陆。多線(xiàn)程是完成任務(wù)的一種方法,高并發(fā)是系統(tǒng)運(yùn)行的一種狀態(tài)懊亡,通過(guò)多線(xiàn)程有助于系統(tǒng)承受高并發(fā)狀態(tài)的實(shí)現(xiàn)依啰。

高并發(fā)是一種系統(tǒng)運(yùn)行過(guò)程中遇到的一種“短時(shí)間內(nèi)遇到大量操作請(qǐng)求”的情況,主要發(fā)生在web系統(tǒng)集中大量訪(fǎng)問(wèn)或者socket端口集中性收到大量請(qǐng)求(例如:12306的搶票情況店枣;天貓雙十一活動(dòng))速警。該情況的發(fā)生會(huì)導(dǎo)致系統(tǒng)在這段時(shí)間內(nèi)執(zhí)行大量操作,例如對(duì)資源的請(qǐng)求鸯两,數(shù)據(jù)庫(kù)的操作等闷旧。如果高并發(fā)處理不好,不僅僅降低了用戶(hù)的體驗(yàn)度(請(qǐng)求響應(yīng)時(shí)間過(guò)長(zhǎng))钧唐,同時(shí)可能導(dǎo)致系統(tǒng)宕機(jī)忙灼,嚴(yán)重的甚至導(dǎo)致OOM異常,系統(tǒng)停止工作等逾柿。

如果要想系統(tǒng)能夠適應(yīng)高并發(fā)狀態(tài)缀棍,則需要從各個(gè)方面進(jìn)行系統(tǒng)優(yōu)化,包括机错,硬件爬范、網(wǎng)絡(luò)、系統(tǒng)架構(gòu)弱匪、開(kāi)發(fā)語(yǔ)言的選取青瀑、數(shù)據(jù)結(jié)構(gòu)的運(yùn)用璧亮、算法優(yōu)化、數(shù)據(jù)庫(kù)優(yōu)化……而多線(xiàn)程只是其中解決方法之一斥难。實(shí)現(xiàn)高并發(fā)需要考慮:

1. 系統(tǒng)的架構(gòu)設(shè)計(jì)枝嘶,如何在架構(gòu)層面減少不必要的處理(網(wǎng)絡(luò)請(qǐng)求,數(shù)據(jù)庫(kù)操作等)
2. 網(wǎng)絡(luò)拓?fù)鋬?yōu)化減少網(wǎng)絡(luò)請(qǐng)求時(shí)間哑诊、如何設(shè)計(jì)拓?fù)浣Y(jié)構(gòu)群扶,分布式如何實(shí)現(xiàn)?
3. 系統(tǒng)代碼級(jí)別的代碼優(yōu)化镀裤,使用什么設(shè)計(jì)模式來(lái)進(jìn)行工作竞阐?哪些類(lèi)需要使用單例,哪些需要盡量減少new操作暑劝?
4. 提高代碼層面的運(yùn)行效率骆莹、如何選取合適的數(shù)據(jù)結(jié)構(gòu)進(jìn)行數(shù)據(jù)存取担猛?如何設(shè)計(jì)合適的算法幕垦?
任務(wù)執(zhí)行方式級(jí)別的同異步操作,在哪里使用同步傅联,哪里使用異步先改?
5. JVM調(diào)優(yōu),是以server模式還是以clien模式運(yùn)行纺且,如何設(shè)置Heap盏道、Stack稍浆、Eden的大小载碌,如何選擇GC策略,控制Full GC的頻率?
6. 數(shù)據(jù)庫(kù)優(yōu)化減少查詢(xún)修改時(shí)間衅枫。數(shù)據(jù)庫(kù)的選燃尥А?數(shù)據(jù)庫(kù)引擎的選认伊谩步咪?數(shù)據(jù)庫(kù)表結(jié)構(gòu)的設(shè)計(jì)?數(shù)據(jù)庫(kù)索引益楼、觸發(fā)器等設(shè)計(jì)猾漫?是否使用讀寫(xiě)分離?還是需要考慮使用數(shù)據(jù)倉(cāng)庫(kù)感凤?
7. 緩存數(shù)據(jù)庫(kù)的使用悯周,如何選擇緩存數(shù)據(jù)庫(kù)?是Redis還是Memcache? 如何設(shè)計(jì)緩存機(jī)制陪竿?
8. 數(shù)據(jù)通信問(wèn)題禽翼,如何選擇通信方式?是使用TCP還是UDP,是使用長(zhǎng)連接還是短連接闰挡?NIO還是BIO锐墙?netty、mina還是原生socket长酗?
9. 操作系統(tǒng)選取溪北,是使用winserver還是Linux?或者Unix夺脾?
10 硬件配置刻盐?是8G內(nèi)存還是32G,網(wǎng)卡10G還是1G?
...

以上的這些問(wèn)題在高并發(fā)中都是必須要深入考慮的劳翰,就像木桶原理一樣敦锌,只要其中的某一方面沒(méi)有考慮到,都會(huì)造成系統(tǒng)瓶頸佳簸,影響整個(gè)系統(tǒng)的運(yùn)行乙墙。而高并發(fā)問(wèn)題不僅僅涉及面之廣,同時(shí)又要求有足夠的深度IL搿!

而多線(xiàn)程在這里只是在同/異步角度上解決高并發(fā)問(wèn)題的其中的一個(gè)方法手段马胧,是在同一時(shí)刻利用計(jì)算機(jī)閑置資源的一種方式汉买。多線(xiàn)程在解決高并發(fā)問(wèn)題中所起到的作用就是使計(jì)算機(jī)的資源在每一時(shí)刻都能達(dá)到最大的利用率,不至于浪費(fèi)計(jì)算機(jī)資源使其閑置佩脊。

參考:

https://www.php.cn/php-weizijiaocheng-377248.html蛙粘、https://www.cnblogs.com/zuochuang/p/7885941.htmlhttps://www.php.net/manual/zh/install.fpm.php威彰、https://www.cnblogs.com/itxiongwei/p/9072075.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末出牧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子歇盼,更是在濱河造成了極大的恐慌舔痕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豹缀,死亡現(xiàn)場(chǎng)離奇詭異伯复,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)邢笙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)啸如,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸣剪,你說(shuō)我怎么就攤上這事组底≌苫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵债鸡,是天一觀(guān)的道長(zhǎng)江滨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)厌均,這世上最難降的妖魔是什么唬滑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮棺弊,結(jié)果婚禮上晶密,老公的妹妹穿的比我還像新娘。我一直安慰自己模她,他們只是感情好稻艰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著侈净,像睡著了一般尊勿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畜侦,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天元扔,我揣著相機(jī)與錄音,去河邊找鬼旋膳。 笑死澎语,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的验懊。 我是一名探鬼主播擅羞,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鲁森!你這毒婦竟也來(lái)了祟滴?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤歌溉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后骑晶,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體痛垛,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年桶蛔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匙头。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仔雷,死狀恐怖蹂析,靈堂內(nèi)的尸體忽然破棺而出舔示,到底是詐尸還是另有隱情,我是刑警寧澤电抚,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布惕稻,位于F島的核電站,受9級(jí)特大地震影響蝙叛,放射性物質(zhì)發(fā)生泄漏俺祠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一借帘、第九天 我趴在偏房一處隱蔽的房頂上張望蜘渣。 院中可真熱鬧,春花似錦肺然、人聲如沸蔫缸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捂龄。三九已至,卻和暖如春加叁,著一層夾襖步出監(jiān)牢的瞬間倦沧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工它匕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留展融,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓豫柬,卻偏偏與公主長(zhǎng)得像告希,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子烧给,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349