在說明fastcgi方式之前,先對php_module方式做一個簡要說明
php_module方式的簡要說明
常見的執行php腳本的方式是php_module 方式:
以apache2.4 及php7.2.4爲例進行說明,在php_module方式執行時,php腳本的執行並不是在單獨的進程中進行,而是由apache服器加載一個dll,這個dll負責php腳本的解釋執行。
比如在apache的配置文件中下面的語句:
LoadModule php7_module D:/php7.2.4/php7apache2_4.dll
AddType application/x-httpd-php .php
PHPIniDir "D:/php7.2.4"
從以上配置可見,php7apache2_4.dll 負責解釋執行php腳本,php7apache2_4.dll 並不是獨立的進程,而是加載到apache的進程空間中執行。
fastcgi方式的簡要說明
cgi或fastcgi方式執行時,解釋執行php腳本的程序運行在獨立的進程空間中,web服務器與解釋執行php腳本的程序之間根據cgi協議進行通信。
以fastcgi方式運行腳本要搞清楚的問題:是什麼程序在執行php腳本?
答案是 php-cgi.exe
php的發行版中都提供了這個php-cgi.exe。它是一個可以獨立運行的可執行程序
在apahce的配置文件中有如下的語句:
FcgidWrapper "D:/php7.2.4/php-cgi.exe" .php
以上這句配置就指明瞭真正執行php腳本的程序是 php-cgi.exe
apache 配置fastcgi
僅僅有上 一節所說的一句配置還不夠,我們還得指明apache如何與php-cgi.exe打交道。因此下面是一個比較完整一點的配置
LoadModule fcgid_module modules/mod_fcgid.so
AddType application/x-httpd-php .php
<IfModule mod_fcgid.c>
AddHandler fcgid-script .php
#php.ini的存放目錄
FcgidInitialEnv PHPRC "D:/php7.2.4"
# 設置PHP_FCGI_MAX_REQUESTS大於或等於FcgidMaxRequestsPerProcess,防止php-cgi進程在處理完所有請求前退出
FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 500
#php-cgi每個進程的最大請求數
FcgidMaxRequestsPerProcess 500
#php-cgi最大的進程數
FcgidMaxProcesses 20
#最大執行時間
FcgidIOTimeout 120
FcgidIdleTimeout 120
#php-cgi的路徑
FcgidWrapper "D:/php7.2.4/php-cgi.exe" .php
</IfModule>
從以上的配置可以看出來,爲了讓apache與php-cgi.exe交互,加載了模塊 mod_fcgid.so
並且配置了一些相關的參數。
另外在配置中還要注意兩點:
1,<IfModule mod_fcgid.c> 不要寫成 <IfModule mod_fcgid> ,
雖然只是多了一個“.c",但會導致是否加載配置的問題。
否則 *.php文件都被當成了普通文件,而沒有被php引擎解析執行
2,要在 “<Directory”指令節中 加上 “ Options ExecCGI”,
指明要執行CGI,當然option還可以帶上其它的選項,但 "ExecCGI"不能省。
nginx 配置fastcgi
nginx與apache不一樣,nginx是通過反向代理的方式與php-cgi.exe打交道。配置方式與apache不一樣。
php-cgi.exe 與nginx是做爲兩個獨立的進程分別啓動
第一步,啓動php-cgi.exe ,讓它監聽某個端口,這裏以端口9000爲例,在cmd窗口中執行如下命令
D:/php7.2.4/php-cgi.exe -b 127.0.0.1:9000
第二步,修改nginx配置,讓它反向代理,指向端口9000,然後啓動nginx
nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 9090;
server_name localhost;
location / {
root html;
index index.html index.htm index.php;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
以上配置中的關鍵一句是
fastcgi_pass 127.0.0.1:9000;
從以上配置可以看出,nginx實際上只負責把對*.php的請求轉發到9000端口,至於是不是php-cgi.exe在監聽9000端口,nginx並不關心。
在以上的配置中有一個問題,就是windows環境下,php-cgi.exe的運行非常不穩定,運行一段時間後就會崩
潰退出。在linux中有fpm管理,在windows環境下現在比較好用的FastCGI進程管理器是xxfpm.exe
改進的思路就是讓xxfpm.exe管理php-cgi.exe,同進打開幾個php-cgi.exe進程,當某個php-cgi.exe進程退出時,開啓新的php-cgi.exe進程補上,使得php-cgi.exe的進程數目始終維持穩定。
前面已經說過,nginx並不關心是誰在監聽9000端口,所以nginx的配置不用做改動。
只要下載xxfpm.exe到本地,並執行如下的命令開始監聽9000端口即可:
xxfpm.exe "D:/php7.2.4/php-cgi.exe -c D:/php7.2.4/php.ini" -n 5 -i 127.0.0.1 -p 9000
以上命令中 ,參數 -n 5 表示同時開啓5個php.exe進程, -i 與 -p 分別指定ip與端口