[TOC]
## 查看當前php 運行模式
關于運行模式我也是查了很多資料,各種博客詞條都看了,有的寫的很簡略,有的寫的很詳細但不是每一個模式都寫的那么詳細,這里我結合我自己看過的書以及經驗和理解,稍加整理放在下面。
>注意,如果只是使用swoole的話,好好看一下FastCGI即可。
php\_sapi\_name();
## 運行模式
關于PHP目前比較常見的五大運行模式:
1)CGI(通用網關接口/?Common?Gateway?Interface)
2)FastCGI(常駐型CGI?/?Long-Live?CGI)
3)CLI(命令行運行?/?Command?Line?Interface)
4)Web模塊模式(Apache等Web服務器運行的模式)?
5)ISAPI(Internet?Server?Application?Program?Interface)
> 備注:在PHP5.3以后,PHP不再有ISAPI模式,安裝后也不再有php5isapi.dll這個文件。要在IIS6上使用高版本PHP,必須安裝FastCGI?擴展,然后使IIS6支持FastCGI。
## 1. CGI 協議模式
CGI即通用網關接口(Common?Gateway?Interface),它是一段程序,通俗的講CGI就象是一座橋,把網頁和Web服務器中的執行程序連接起來,它把HTML接收的指令傳遞給服務器的執行程序,再把服務器執行程序的結果返還給HTML頁。CGI?的跨平臺性能極佳,幾乎可以在任何操作系統上實現。CGI已經是比較老的模式了,這幾年都很少用了。?
?? 每有一個用戶請求,都會先要創建CGI的子進程,然后處理請求,處理完后結束這個子進程,這就是Fork-And-Execute模式。?當用戶請求數量非常多時,會大量擠占系統的資源如內存,CPU時間等,造成效能低下。所以用CGI方式的服務器有多少連接請求就會有多少CGI子進程,子進程反復加載是CGI性能低下的主要原因。?
?? 如果不想把?PHP?嵌入到服務器端軟件(如?Apache)作為一個模塊安裝的話,可以選擇以?CGI?的模式安裝。或者把?PHP?用于不同的?CGI?封裝以便為代碼創建安全的?chroot?和?setuid?環境。這樣每個客戶機請求一個PHP文件,Web服務器就調用php.exe(win下是php.exe,linux是php)去解釋這個文件,然后再把解釋的結果以網頁的形式返回給客戶機。?這種安裝方式通常會把?PHP?的可執行文件安裝到?web?服務器的?cgi-bin?目錄。CERT?建議書?CA-96.11?建議不要把任何的解釋器放到?cgi-bin?目錄。???這種方式的好處是把Web?Server和具體的程序處理獨立開來,結構清晰,可控性強,同時缺點就是如果在高訪問需求的情況下,CGI的進程Fork就會成為很大的服務器負擔,想?象一下數百個并發請求導致服務器Fork出數百個進程就明白了。這也是為什么CGI一直背負性能低下,高資源消耗的惡名的原因。
## 2.FastCGI模式
這個模式就比較重要了,需要仔細的看看,因為我們經常使用的的**PHP-FPM**就是**PHP的FastCGI進程管理器**(PHP-FastCGI?Process?Manager)?
FastCGI是CGI的升級版本,FastCGI像是一個常駐?(long-live)型的?CGI,它可以一直執行著,只要激活后,不會每次都要花費時間去?Fork?一次?(這是?CGI?最為人詬病的?fork-and-execute?模式)。?
FastCGI是一個可伸縮地、高速地在HTTP?server和動態腳本語言間通信的接口。多數流行的HTTP?server都支持FastCGI,包括Apache、Nginx和lighttpd等,同時,FastCGI也被許多腳本語言所支持,其中就有PHP。?
FastCGI接口方式采用C/S結構,可以將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啟動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然后將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。
【原理】
1)Web?Server啟動時載入FastCGI進程管理器(IIS?ISAPI或Apache?Module);?
2)FastCGI進程管理器自身初始化,啟動多個CGI解釋器進程?(可見多個php-cgi.exe或php-cig)并等待來自Web?Server的連接;?
3)當客戶端請求到達Web?Server時,FastCGI進程管理器選擇并連接到一個CGI解釋器。Web?server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi;?
4)FastCGI子進程完成處理后將標準輸出和錯誤信息從同一連接返回Web?Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接著等待并處理來自FastCGI進程管理器(運行在?WebServer中)的下一個連接。在正常的CGI模式中,php-cgi.exe在此便退出了。?
? ? 在CGI模式中,你可以想象?CGI通常有多慢。每一個Web請求PHP都必須重新解析php.ini、重新載入全部dll擴展并重初始化全部數據結構。使用FastCGI,所有這些都只在進程啟動時發生一次。一個額外的好處是,持續數據庫連接(Persistent?database?connection)可以工作。?
備注:PHP的FastCGI進程管理器是PHP-FPM(PHP-FastCGI?Process?Manager)? ?
【優點】?
1)從穩定性上看,FastCGI是以獨立的進程池來運行CGI,單獨一個進程死掉,系統可以很輕易的丟棄,然后重新分配新的進程來運行邏輯;?
2)從安全性上看,FastCGI支持分布式運算。FastCGI和宿主的Server完全獨立,FastCGI怎么down也不會把Server搞垮;?
3)從性能上看,FastCGI把動態邏輯的處理從Server中分離出來,大負荷的IO處理還是留給宿主Server,這樣宿主Server可以一心一意作IO,對于一個普通的動態網頁來說,?邏輯處理可能只有一小部分,大量的是圖片等靜態。? ?
【缺點】?
有網友說使用Zend?Studio調試程序時,由于?FastCGI會認為?PHP進程超時,從而在頁面返回?500錯誤,因為我沒遇到過這個問題,所以這里我就不做任何說明了。
> 注意,fast-cgi和cgi都是一種協議,開啟的進程是單獨實現該協議的進程
> cgi:
> 用戶請求->Web服務器接收請求->fork子進程 調用程序/執行程序->程序返回內容/程序調用結束->web服務器接收內容->返回給用戶。
> fast-cgi
> web服務器fast-cgi進程管理器初始化->預先fork n個進程
用戶請求->web服務器接收請求->交給fast-cgi進程管理器->fast-cgi進程管理區接收,給其中一個空閑fast-cgi進程處理->處理完成,fast-cgi進程變為空閑狀態,等待下次請求->web服務器接收內容->返回給用戶
## 3.CLI模式?
?? PHP-CLI是PHP?Command?Line?Interface的簡稱,如同它名字的意思,就是PHP在命令行運行的接口,區別于在Web服務器上運行的PHP環境(PHP-CGI,ISAPI等)。?也就是說,PHP不單可以寫前臺網頁,它還可以用來寫后臺的程序。?PHP的CLI?Shell腳本適用于所有的PHP優勢,使創建要么支持腳本或系統甚至與GUI應用程序的服務端,在Windows和Linux下都是支持PHP-CLI模式的。???
【優點】?
1)使用多進程,子進程結束以后,內核會負責回收資源;?
2)使用多進程,子進程異常退出不會導致整個進程Thread退出,父進程還有機會重建流程;?
3)一個常駐主進程,只負責任務分發,邏輯更清楚。?
詳細信息可以在 http://php.net/manual/zh/features.commandline.php查看。
?? 我們在Linux下經常使用"php?–m"查找PHP安裝了那些擴展就是PHP命令行運行模式;有興趣的同學可以輸入"php?–h"去深入研究該運行模式。
## 4.模塊模式?
?? 模塊模式是以mod\_php5模塊的形式集成,此時mod\_php5模塊的作用是接收Apache傳遞過來的PHP文件請求,并處理這些請求,然后將處理后的結果返回給Apache。如果我們在Apache啟動前在其配置文件中配置好了PHP模塊
(mod\_php5),?PHP模塊通過注冊apache2的ap\_hook\_post\_config掛鉤,在Apache啟動的時候啟動此模塊以接受PHP文件的請求。?
?? 除了這種啟動時的加載方式,Apache的模塊可以在運行的時候動態裝載,這意味著對服務器可以進行功能擴展而不需要重新對源代碼進行編譯,甚至根本不需要停止服務器。我們所需要做的僅僅是給服務器發送信號HUP或者AP\_SIG\_GRACEFUL通知服務器重新載入模塊。但是在動態加載之前,我們需要將模塊編譯成為動態鏈接庫。此時的動態加載就是加載動態鏈接庫。?Apache中對動態鏈接庫的處理是通過模塊mod\_so來完成的,因此mod\_so模塊不能被動態加載,它只能被靜態編譯進Apache的核心。這意味著它是隨著Apache一起啟動的。?
?? Apache是如何加載模塊的呢?我們以前面提到的mod\_php5模塊為例。首先我們需要在Apache的配置文件httpd.conf中添加一行:
LoadModule?php5\_module?modules/mod\_php5.so?
?? 這里我們使用了LoadModule命令,該命令的第一個參數是模塊的名稱,名稱可以在模塊實現的源碼中找到。第二個選項是該模塊所處的路徑。如果需要在服務器運行時加載模塊,可以通過發送信號HUP或者AP\_SIG\_GRACEFUL給服務器,一旦接受到該信號,Apache將重新裝載模塊,而不需要重新啟動服務器。?
?? 該運行模式是我們以前在windows環境下使用apache服務器經常使用的,而在模塊化(DLL)中,PHP是與Web服務器一起啟動并運行的。(它是apache在CGI的基礎上進行的一種擴展,加快PHP的運行效率)。
## 5.ISAPI模式?
?? ISAPI(Internet?Server?Application?Program?Interface)是微軟提供的一套面向Internet服務的API接口,一個ISAPI的DLL,可以在被用戶請求激活后長駐內存,等待用戶的另一個請求,還可以在一個DLL里設置多個用戶請求處理函數,此外,ISAPI的DLL應用程序和WWW服務器處于同一個進程中,效率要顯著高于CGI。(由于微軟的排他性,只能運行于windows環境)?
?? PHP作為Apache模塊,Apache服務器在系統啟動后,預先生成多個進程副本駐留在內存中,一旦有請求出現,就立即使用這些空余的子進程進行處理,這樣就不存在生成子進程造成的延遲了。這些服務器副本在處理完一次HTTP請求之后并不立即退出,而是停留在計算機中等待下次請求。對于客戶瀏覽器的請求反應更快,性能較高。
- 微服務
- 服務器相關
- 操作系統
- 極客時間操作系統實戰筆記
- 01 程序的運行過程:從代碼到機器運行
- 02 幾行匯編幾行C:實現一個最簡單的內核
- 03 黑盒之中有什么:內核結構與設計
- Rust
- 入門:Rust開發一個簡單的web服務器
- Rust的引用和租借
- 函數與函數指針
- Rust中如何面向對象編程
- 構建單線程web服務器
- 在服務器中增加線程池提高吞吐
- Java
- 并發編程
- 并發基礎
- 1.創建并啟動線程
- 2.java線程生命周期以及start源碼剖析
- 3.采用多線程模擬銀行排隊叫號
- 4.Runnable接口存在的必要性
- 5.策略模式在Thread和Runnable中的應用分析
- 6.Daemon線程的創建以及使用場景分析
- 7.線程ID,優先級
- 8.Thread的join方法
- 9.Thread中斷Interrupt方法學習&采用優雅的方式結束線程生命周期
- 10.編寫ThreadService實現暴力結束線程
- 11.線程同步問題以及synchronized的引入
- 12.同步代碼塊以及同步方法之間的區別和關系
- 13.通過實驗分析This鎖和Class鎖的存在
- 14.多線程死鎖分析以及案例介紹
- 15.線程間通信快速入門,使用wait和notify進行線程間的數據通信
- 16.多Product多Consumer之間的通訊導致出現程序假死的原因分析
- 17.使用notifyAll完善多線程下的生產者消費者模型
- 18.wait和sleep的本質區別
- 19.完善數據采集程序
- 20.如何實現一個自己的顯式鎖Lock
- 21.addShutdownHook給你的程序注入鉤子
- 22.如何捕獲線程運行期間的異常
- 23.ThreadGroup API介紹
- 24.線程池原理與自定義線程池一
- 25.給線程池增加拒絕策略以及停止方法
- 26.給線程池增加自動擴充,閑時自動回收線程的功能
- JVM
- C&C++
- GDB調試工具筆記
- C&C++基礎
- 一個例子理解C語言數據類型的本質
- 字節順序-大小端模式
- Php
- Php源碼閱讀筆記
- Swoole相關
- Swoole基礎
- php的五種運行模式
- FPM模式的生命周期
- OSI網絡七層圖片速查
- IP/TCP/UPD/HTTP
- swoole源代碼編譯安裝
- 安全相關
- MySql
- Mysql基礎
- 1.事務與鎖
- 2.事務隔離級別與IO的關系
- 3.mysql鎖機制與結構
- 4.mysql結構與sql執行
- 5.mysql物理文件
- 6.mysql性能問題
- Docker&K8s
- Docker安裝java8
- Redis
- 分布式部署相關
- Redis的主從復制
- Redis的哨兵
- redis-Cluster分區方案&應用場景
- redis-Cluster哈希虛擬槽&簡單搭建
- redis-Cluster redis-trib.rb 搭建&原理
- redis-Cluster集群的伸縮調優
- 源碼閱讀筆記
- Mq
- ELK
- ElasticSearch
- Logstash
- Kibana
- 一些好玩的東西
- 一次折騰了幾天的大華攝像頭調試經歷
- 搬磚實用代碼
- python讀取excel拼接sql
- mysql大批量插入數據四種方法
- composer好用的鏡像源
- ab
- 環境搭建與配置
- face_recognition本地調試筆記
- 虛擬機配置靜態ip
- Centos7 Init Shell
- 發布自己的Composer包
- git推送一直失敗怎么辦
- Beyond Compare過期解決辦法
- 我的Navicat for Mysql
- 小錯誤解決辦法
- CLoin報錯CreateProcess error=216
- mysql error You must reset your password using ALTER USER statement before executing this statement.
- VM無法連接到虛擬機
- Jetbrains相關
- IntelliJ IDEA 筆記
- CLoin的配置與使用
- PhpStormDocker環境下配置Xdebug
- PhpStorm advanced metadata
- PhpStorm PHP_CodeSniffer