實戰Nginx與PHP(FastCGI)的安裝、配置與最佳化

玻璃窗起霧了發表於2021-02-01

一、什麼是 FastCGI
FastCGI 是一個可伸縮地、高速地在 HTTP server 和動態指令碼語言間通訊的介面。多數流行的 HTTP server 都支援 FastCGI ,包括 Apache Nginx lighttpd 等,同時, FastCGI 也被許多指令碼語言所支援,其中就有 PHP
FastCGI
是從 CGI 發展改進而來的。傳統 CGI 介面方式的主要缺點是效能很差,因為每次 HTTP 伺服器遇到動態程式時都需要重新啟動指令碼解析器來執行解析,然後結果被返回給 HTTP 伺服器。這在處理高併發訪問時,幾乎是不可用的。另外傳統的 CGI 介面方式安全性也很差,現在已經很少被使用了。
FastCGI
介面方式採用 C/S 結構,可以將 HTTP 伺服器和指令碼解析伺服器分開,同時在指令碼解析伺服器上啟動一個或者多個指令碼解析守護程式。當 HTTP 伺服器每次遇到動態程式時,可以將其直接交付給 FastCGI 程式來執行,然後將得到的結果返回給瀏覽器。這種方式可以讓 HTTP 伺服器專一地處理靜態請求或者將動態指令碼伺服器的結果返回給客戶端,這在很大程度上提高了整個應用系統的效能。

二、 Nginx+FastCGI 執行原理
Nginx 不支援對外部程式的直接呼叫或者解析,所有的外部程式(包括 PHP )必須透過 FastCGI 介面來呼叫。 FastCGI 介面在 Linux 下是 socket ,(這個 socket 可以是檔案 socket ,也可以是 ip socket )。為了呼叫 CGI 程式,還需要一個 FastCGI wrapper wrapper 可以理解為用於啟動另一個程式的程式),這個 wrapper 繫結在某個固定 socket 上,如埠或者檔案 socket 。當 Nginx CGI 請求傳送給這個 socket 的時候,透過 FastCGI 介面, wrapper 接納到請求,然後派生出一個新的執行緒,這個執行緒呼叫直譯器或者外部程式處理指令碼並讀取返回資料;接著, wrapper 再將返回的資料透過 FastCGI 介面,沿著固定的 socket 傳遞給 Nginx ;最後, Nginx 將返回的資料傳送給客戶端,這就是 Nginx+FastCGI 的整個運作過程。

三、 spawn-fcgi PHP-FPM

前面介紹過, FastCGI 介面方式在指令碼解析伺服器上啟動一個或者多個守護程式對動態指令碼進行解析,這些程式就是 FastCGI 程式管理器,或者稱之為 FastCGI 引擎, spawn-fcgi PHP-FPM 就是支援 PHP 的兩個 FastCGI 程式管理器。
下面簡單介紹 spawn-fcgi PHP-FPM 的異同。
 

spawn-fcgi HTTP 伺服器 lighttpd 的一部分,目前已經獨立成為一個專案,一般與 lighttpd 配合使用來支援 PHP ,但是 ligttpd spwan-fcgi 在高併發訪問的時候,會出現記憶體洩漏甚至自動重啟 FastCGI 的問題。
 

Nginx 是個輕量級的 HTTP server ,必須藉助第三方的 FastCGI 處理器才可以對 PHP 進行解析,因此 Nginx+spawn-fcgi 的組合也可以實現對 PHP 的解析,這裡不過多講述。
 

PHP-FPM 也是一個第三方的 FastCGI 程式管理器,它是作為 PHP 的一個補丁來開發的,在安裝的時候也需要和 PHP 原始碼一起編譯,也就是說 PHP-FPM 被編譯到 PHP 核心中,因此在處理效能方面更加優秀;同時它在處理高併發方面也比 spawn-fcgi 引擎好很多,因此,推薦 Nginx+PHP/PHP-FPM 這個組合對 PHP 進行解析。
 

FastCGI 的主要優點是把動態語言和 HTTP Server 分離開來,所以 Nginx PHP/PHP-FPM 經常被部署在不同的伺服器上,以分擔前端 Nginx 伺服器的壓力,使 Nginx 專一處理靜態請求和轉發動態請求,而 PHP/PHP-FPM 伺服器專一解析 PHP 動態請求。

四、 PHP PHP-FPM 的安裝及最佳化

1. 下載安裝包
官方網站下載 PHP 原始碼包,這裡下載的是穩定版 php-5.2.13.tar.gz
下載對應的 PHP-FPM 原始碼包,這裡下載的是 php-5.2.13-fpm-0.5.13.diff.gz
需要注意,在下載軟體包版本時,儘量使 PHP PHP-FPM 版本一致,如果版本之間相差太大,可以會出現相容問題。

2. 配置安裝環境
安裝 PHP 需要下面軟體包的支援,如果沒有安裝,請自行安裝。

1.     gcc gcc-c++ libxml2 libxml2-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel  zlib zlib-devel glibc glibc-devel glib2 glib2-devel   

由於各個 Linux 系統版本的不確定性,讀者也可以在安裝 PHP 過程中,根據錯誤提示資訊,安裝對應的軟體庫。

3. 開始編譯安裝 PHP PHP-FPM
編譯安裝 PHP PHP-FPM 很簡單,下面是安裝過程:

1.     [root@localhost local]#tar zxvf php-5.2.13.tar.gz  

2.    [root@localhost local]#gzip -cd php-5.2.13-fpm-0.5.13.diff.gz | patch -d php-5.2.13 -p1

3.     [root@localhost local]#cd php-5.2.13  

4.    [root@localhost php-5.2.13]#./configure  --prefix=/usr/local/php --enable-fastcgi --enable-fpm

5.     [root@localhost php-5.2.13]#make  

6.    [root@localhost php-5.2.13]#make install

7.     [root@localhost php-5.2.13]cp php.ini-dist /usr/local/php/lib/php.ini  

其中,第二步將 PHP-FPM 作為補丁加入 PHP 原始碼中。
“./configure” 編譯選項中,指定將 PHP 安裝到 /usr/local 下, “--enable-fastcgi” 是啟用對 PHP FastCGI 支援, “--enable-fpm” 是啟用對 FastCGI 模式的 fpm 支援。
在編譯 PHP 時可以加入很多編譯選項,但是這裡為了介紹 PHP FastCGI 功能沒有加入更多的編譯選項。

4. 配置與最佳化 PHP-FPM
PHP
的全域性配置檔案是 php.ini ,在上面的步驟中,已經將此檔案複製到了 /usr/local/php/lib/php.ini 下。可以根據每個應用需求的不同,對 php.ini 進行相應的配置。
下面重點介紹 PHP-FPM 引擎的配置檔案。
 

根據上面指定的安裝路徑, PHP-FPM 的預設配置檔案為 /usr/local/php/etc/php-fpm.conf
php-fpm.conf
是一個 XML 格式的純文字檔案,其內容很容易看明白。這裡重點介紹幾個重要的配置標籤:
 

標籤 listen_address 是配置 fastcgi 程式監聽的 IP 地址以及埠,預設是 127.0.0.1:9000
<value name="listen_address">127.0.0.1:9000</value>
 

標籤 display_errors 用來設定是否顯示 PHP 錯誤資訊,預設是 0 ,不顯示錯誤資訊,設定為 1 可以顯示 PHP 錯誤資訊。
<value name="display_errors">0</value>
 

標籤 user group 用於設定執行 FastCGI 程式的使用者和使用者組。需要注意的是,這裡指定的使用者和使用者組要和 Nginx 配置檔案中指定的使用者和使用者組一致。
<value name="user">nobody</value>
<value name="group">nobody</value>
 

標籤 max_children 用於設定 FastCGI 的程式數。根據官方建議,小於 2GB 記憶體的伺服器,可以只開啟 64 個程式, 4GB 以上記憶體的伺服器可以開啟 200 個程式。
<value name="max_children">5</value>
 

標籤 request_terminate_timeout 用於設定 FastCGI 執行指令碼的時間。預設是 0s ,也就是無限執行下去,可以根據情況對其進行修改。
<value name="request_terminate_timeout">0s</value>
 

標籤 rlimit_files 用於設定 PHP-FPM 對開啟檔案描述符的限制,預設值為 1024 。這個標籤的值必須和 Linux 核心開啟檔案數關聯起來,例如要將此值設定為 65535 ,就必須在 Linux 命令列執行 'ulimit -HSn 65536'
<value name="rlimit_files">1024</value>
 

標籤 max_requests 指明瞭每個 children 最多處理多少個請求後便會被關閉,預設的設定是 500
<value name="max_requests">500</value>
 

標籤 allowed_clients 用於設定允許訪問 FastCGI 程式解析器的 IP 地址。如果不在這裡指定 IP 地址, Nginx 轉發過來的 PHP 解析請求將無法被接受。
<value name="allowed_clients">127.0.0.1</value>

5. 管理 FastCGI 程式
在配置完 php-fpm 後,就可以啟動 FastCGI 程式了。啟動 fastcgi 程式有兩種方式:

1.     /usr/local/php/bin/php-cgi --fpm   

2.    或者

3.     /usr/local/php/sbin/php-fpm  start  

建議採用第二種方式啟動 FastCGI 程式。
 /usr/local/php/sbin/php-fpm
還有其他引數,具體為 start|stop|quit|restart|reload|logrotate
每個啟動引數的含義如下:

1.     q  start,啟動 PHPFastCGI程式。  

2.    q stop,強制終止PHP的FastCGI程式。

3.     q  quit,平滑終止 PHPFastCGI程式。  

4.    q restart, 重啟PHP的FastCGI程式。

5.     q  reload 重新載入 PHPphp.ini  

6.    q logrotate, 重新啟用log檔案。

reload 是個很重要的引數,它可以在 PHP FastCGI 程式不中斷的情況下重新載入改動過的 php.ini ,因此透過 php-fpm 可以平滑變更 FastCGI 模式下的 PHP 設定。


FastCGI 程式啟動後,其監聽的 IP 地址和埠也隨即啟動,可以透過 ps netstat 檢視相關資訊。

1.      [root@localhost php]# netstat -antl|grep 9000  

2.    tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN

3.     [root@localhost php]# ps -ef|grep php-cgi  

4.    root      3567     1     0  17:06 ?       00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf

5.     nobody    3568  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf  

6.    nobody    3569  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf

7.     nobody    3570  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf  

8.    nobody    3571  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf

9.     nobody    3572  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf  

10. root      3583  3524  0 17:09 pts/1    00:00:00 grep php-cgi

五、配置 Nginx 來支援 PHP
Nginx 的安裝特別簡單,前面已經對此進行了詳細介紹,這裡不再進行講述。下面重點介紹 Nginx 如何透過 php-fpm FastCGI 程式對 PHP 進行解析處理。
由於N ginx 本身不會對 PHP 進行解析,因此要實現 Nginx PHP 的支援,其實是將對 PHP 頁面的請求交給 fastCGI 程式監聽的 IP 地址及埠。如果把 php-fpm 當做動態應用伺服器,那麼 Nginx 其實就是一個反向代理伺服器。 Nginx 透過反向代理功能實現對 PHP 的解析,這就是 Nginx 實現 PHP 動態解析的原理。
這裡假定 Nginx 的安裝目錄為 /usr/local ,則 Nginx 配置檔案的路徑為 /usr/local/nginx/conf/nginx.conf 。下面是在 Nginx 下支援 PHP 解析的一個虛擬主機配置例項。

1.             server {  

2.     include port.conf;

3.      server_name   

4.

5.       location / {  

6.     index index.html index.php;

7.      root /web/www/  

8.     }

9.      

10.  location ~ \.php$ {

11.             root           html;  

12.             fastcgi_pass   127.0.0.1:9000;

13.             fastcgi_index  index.php;  

14.             fastcgi_param  SCRIPT_FILENAME  html$fastcgi_script_name;

15.             include        fastcgi_params;  

16.         }

17. }  

18.

透過 location 指令,將所有以 php 為字尾的檔案都交給 127.0.0.1:9000 來處理,而這裡的 IP 地址和埠就是 FastCGI 程式監聽的 IP 地址和埠。
fastcgi_param
指令指定放置 PHP 動態程式的主目錄,也就是 $fastcgi_script_name 前面指定的路徑,這裡是 /usr/local/nginx/html 目錄,建議將這個目錄與 Nginx 虛擬主機指定的根目錄保持一致,當然也可以不一致。
fastcgi_params
檔案是 FastCGI 程的一個 站長部落格 引數配置檔案 ,在安裝 Nginx 後,會預設生成一個這樣的檔案,這裡透過 include 指令將 FastCGI 引數配置檔案包含了進來。
接下來,啟動 nginx 服務。
/usr/local/nginx/sbin/nginx
到此為止, Nginx+PHP 已經配置完成。

六、測試 Nginx PHP 的解析功能
這裡在 /usr/local/nginx/html 目錄下建立一個 phpinfo.php 檔案,內容如下:
<?php phpinfo(); ?>
然後透過瀏覽器訪問 ,預設會在瀏覽器顯示 “Welcome to Nginx!” 表示 Nginx 正常執行。
接著在瀏覽器中訪問 ,如果 PHP 能夠正常解析,會出現 PHP 安裝配置以及功能列表統計資訊。

七、例項講解 Nginx FastCGI 引數的最佳化
在配置完成 Nginx+FastCGI 之後,為了保證 Nginx PHP 環境的高速穩定執行,需要新增一些 FastCGI 最佳化指令。下面給出一個最佳化例項,將下面程式碼新增到 Nginx 主配置檔案中的 HTTP 層級。

1.     fastcgi_cache_path /usr/local/nginx/fastcgi_cache  levels = 1 :2  keys_zone = TEST :10m  inactive = 5m ;    

2.    fastcgi_connect_timeout 300;

3.     fastcgi_send_timeout 300;    

4.    fastcgi_read_timeout 300;

5.     fastcgi_buffer_size 64k;    

6.    fastcgi_buffers 4 64k;

7.     fastcgi_busy_buffers_size 128k;    

8.    fastcgi_temp_file_write_size 128k;

9.     fastcgi_cache TEST;    

10. fastcgi_cache_valid 200 302 1h;

11. fastcgi_cache_valid 301 1d;    

12. fastcgi_cache_valid any 1m;

下面是對上述程式碼的含義進行介紹。
第一行程式碼是為 FastCGI 快取指定一個檔案路徑、目錄結構等級、關鍵字區域儲存時間和非活動刪除時間。
fastcgi_connect_timeout
指定連線到後端 FastCGI 的超時時間。
fastcgi_send_timeout
指定向 FastCGI 傳送請求的超時時間,這個值是已經完成兩次握手後向 FastCGI 傳送請求的超時時間。
fastcgi_read_timeout
指定接收 FastCGI 應答的超時時間,這個值是已經完成兩次握手後接收 FastCGI 應答的超時時間。

fastcgi_buffer_size 用於指定讀取 FastCGI 應答第一部分需要用多大的緩衝區,這個值表示將使用 1 64KB 的緩衝區讀取應答的第一部分(應答頭),可以設定為 fastcgi_buffers 選項指定的緩衝區大小。

fastcgi_buffers 指定本地需要用多少和多大的緩衝區來緩衝 FastCGI 的應答請求。如果一個 PHP 指令碼所產生的頁面大小為 256KB ,那麼會為其分配 4 64KB 的緩衝區來快取;如果頁面大小大於 256KB ,那麼大於 256KB 的部分會快取到 fastcgi_temp 指定的路徑中,但是這並不是好方法,因為記憶體中的資料處理速度要快於硬碟。一般這個值應該為站點中 PHP 指令碼所產生的頁面大小的中間值,如果站點大部分指令碼所產生的頁面大小為 256KB ,那麼可以把這個值設定為 “16 16k” “4 64k” 等。

fastcgi_busy_buffers_size 的預設值是 fastcgi_buffers 的兩倍。

fastcgi_temp_file_write_size 表示在寫入快取檔案時使用多大的資料塊,預設值是 fastcgi_buffers 的兩倍。

fastcgi_cache 表示開啟 FastCGI 快取併為其指定一個名稱。開啟快取非常有用,可以有效降低 CPU 的負載,並且防止 502 錯誤的發生,但是開啟快取也會引起很多問題,要視具體情況而定。
fastcgi_cache_valid
fastcgi 用來指定應答程式碼的快取時間,例項中的值表示將 200 302 應答快取一個小時,將 301 應答快取 1 天,其他應答均快取 1 分鐘。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69992957/viewspace-2755235/,如需轉載,請註明出處,否則將追究法律責任。

相關文章