Nginx實現FastCGI

CGI的由來

  最早的Web服務器只能簡單地響應瀏覽器發來的HTTP請求,並將存儲在服務器上的HTML文件返回給瀏覽器,也就是靜態html文件,但是後期隨着網站功能增多網站開發也越來越複雜,以至於出現動態技術,比如像php(1995年)、java(1995)、python(1991)語言開發的網站,但是nginx/apache服務器並不能直接運行 php、java這樣的文件,apache實現的方式是打補丁,但是nginx缺通過與第三方基於協議實現,即通過某種特定協議將客戶端請求轉發給第三方服務處理,第三方服務器會新建新的進程處理用戶的請求,處理完成後返回數據給Nginx並回收進程,最後nginx在返回給客戶端,那這個約定就是通用網關接口(common gateway interface,簡稱CGI),CGI(協議)是web服務器和外部應用程序之間的接口標準,是cgi程序和web服務器之間傳遞信息的標準化接口。

FastCGI

  CGI協議雖然解決了語言解析器和web server之間通訊的問題,但是它的效率很低,因爲web server每收到一個請求都會創建一個CGI進程,PHP解析器都會解析php.ini文件,初始化環境,請求結束的時候再關閉進程,對於每一個創建的CGI進程都會執行這些操作,所以效率很低,而FastCGI是用來提高CGI性能的,FastCGI每次處理完請求之後不會關閉掉進程,而是保留這個進程,使這個進程可以處理多個請求。這樣的話每個請求都不用再重新創建一個進程了,大大提升了處理效率。

什麼是PHP-FPM

  PHP-FPM(FastCGI Process Manager:FastCGI進程管理器)是一個實現了Fastcgi的程序,並且提供進程管理的功能。進程包括master進程和worker進程。master進程只有一個,負責監聽端口,接受來自webserver的請求。worker進程一般會有多個,每個進程中會嵌入一個PHP解析器,進行PHP代碼的處理。

FastCHI配置指令

  Nginx基於模塊ngx_http_fastcgi_module實現通過fastcgi協議將指定的客戶端請求轉發至php-fpm處理,其配置指令如下:

fastcgi_pass address;
# 轉發請求到後端服務器,address爲後端的fastcgi server的地址,可用位置:location, if in location

fastcgi_index name;
# fastcgi默認的主頁資源,示例:fastcgi_index index.php;

fastcgi_param parameter value [if_not_empty];
# 設置傳遞給FastCGI服務器的參數值,可以是文本,變量或組合,可用於將Nginx的內置變量賦值給自定義key
fastcgi_param REMOTE_ADDR $remote_addr; #客戶端源IP
fastcgi_param REMOTE_PORT $remote_port; #客戶端源端口
fastcgi_param SERVER_ADDR $server_addr; #請求的服務器IP地址
fastcgi_param SERVER_PORT $server_port; #請求的服務器端口
fastcgi_param SERVER_NAME $server_name; #請求的server name

Nginx默認配置示例:
    location ~ \.php$ {
        root html;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默認腳本路徑
        include fastcgi_params;
    }

緩存定義指令

fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time]
[purger_threshold=time];
定義fastcgi的緩存;
    path # 緩存位置爲磁盤上的文件系統路徑
    max_size=size # 磁盤path路徑中用於緩存數據的緩存空間上限
    levels=levels:緩存目錄的層級數量,以及每一級的目錄數量,levels=ONE:TWO:THREE,示例:leves=1:2:2
    keys_zone=name:size # 設置緩存名稱及k/v映射的內存空間的名稱及大小
    inactive=time # 緩存有效時間,默認10分鐘,需要在指定時間滿足fastcgi_cache_min_uses 次數被視爲活動緩存。

緩存調用指令

fastcgi_cache zone | off;
# 調用指定的緩存空間來緩存數據,可用位置:http, server, location

fastcgi_cache_key string;
# 定義用作緩存項的key的字符串,示例:fastcgi_cache_key $request_uri;

fastcgi_cache_methods GET | HEAD | POST ...;
# 爲哪些請求方法使用緩存

fastcgi_cache_min_uses number;
# 緩存空間中的緩存項在inactive定義的非活動時間內至少要被訪問到此處所指定的次數方可被認作活動項

fastcgi_keep_conn on | off;
# 收到後端服務器響應後,fastcgi服務器是否關閉連接,建議啓用長連接

fastcgi_cache_valid [code ...] time;
# 不同的響應碼各自的緩存時長

fastcgi_hide_header field; # 隱藏響應頭指定信息
fastcgi_pass_header field; # 返回響應頭指定信息,默認不會將Status、X-Accel-...返回

FastCGI示例--Nginx與php-fpm在同一服務器上

php環境準備

# yum安裝默認版本php
[root@CentOS7 ~]#yum install -y php-fpm php-mysql -y
# 啓動php-fpm程序
[root@CentOS7 ~]#systemctl start php-fpm && systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
# 查看php-fpm進程
[root@CentOS7 ~]#ps -ef | grep php-fpm
root       7457      1  1 10:44 ?        00:00:00 php-fpm: master process (/etc/php-fpm.conf)
apache     7459   7457  0 10:44 ?        00:00:00 php-fpm: pool www
apache     7460   7457  0 10:44 ?        00:00:00 php-fpm: pool www
apache     7461   7457  0 10:44 ?        00:00:00 php-fpm: pool www
apache     7462   7457  0 10:44 ?        00:00:00 php-fpm: pool www
apache     7463   7457  0 10:44 ?        00:00:00 php-fpm: pool www
root       7492   7278  0 10:44 pts/0    00:00:00 grep --color=auto php-fpm

php配置優化

[root@CentOS7 ~]#grep "^[a-Z]" /etc/php-fpm.conf
include=/etc/php-fpm.d/*.conf
pid = /run/php-fpm/php-fpm.pid
error_log = /var/log/php-fpm/error.log
daemonize = yes  #是否是後臺啓動

[root@CentOS7 ~]#vim /etc/php-fpm.d/www.conf
[root@CentOS7 ~]#grep -v "^;" /etc/php-fpm.d/www.conf | grep -v '^[ ]*$'
[www]
listen = 127.0.0.1:9000    # 監聽地址及IP
listen.allowed_clients = 127.0.0.1   # 允許客戶端從哪個源IP地址訪問,要允許所有行首加 ;註釋即可
user = nginx   # php-fpm啓動的用戶和組,會涉及到後期文件的權限問題
group = nginx
pm = dynamic    # 動態模式進程管理
pm.max_children = 500    # 靜態方式下開啓的php-fpm進程數量,在動態方式下他限定php-fpm的最大進程數
pm.start_servers = 100    # 動態模式下初始進程數,必須大於等於pm.min_spare_servers和小於等於pm.max_children的值。
pm.min_spare_servers = 100    # 最小空閒進程數
pm.max_spare_servers = 200    # 最大空閒進程數
pm.max_requests = 500000    # 進程累計請求回收值,會重啓
pm.status_path = /pm_status    # 狀態訪問URL
ping.path = /ping    # ping訪問地址
ping.response = ping-pong    # ping返回值
slowlog = /var/log/php-fpm/www-slow.log    # 慢日誌路徑
php_admin_value[error_log] = /var/log/php-fpm/www-error.log    # 錯誤日誌
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files    # phpsession保存方式及路徑
php_value[session.save_path] = /var/lib/php/session    # 當時使用file保存session的文件路徑

# 重新啓動php-fpm以加載配置文件
[root@CentOS7 ~]#systemctl restart php-fpm

準備php測試頁面

[root@CentOS7 ~]#mkdir /data/nginx/php
[root@CentOS7 ~]#vim /data/nginx/php/index.php
[root@CentOS7 ~]#cat /data/nginx/php/index.php
<?php
phpinfo();
?>

Nginx實現FastCGI

Nginx配置轉發

Nginx安裝完成之後默認生成了與fastcgi的相關配置文件,一般保存在nginx的安裝路徑的conf目錄當中,比如/apps/nginx/conf/fastcgi.conf、/apps/nginx/conf/fastcgi_params。

[root@CentOS7 ~]#vim /apps/nginx/conf.d/pc.conf
[root@CentOS7 ~]#cat /apps/nginx/conf.d/pc.conf   # 在指定文件配置fastcgi
server {
  listen 80;
  server_name www.darius.com;
  charset utf-8;
  error_log /apps/nginx/logs/www_darius_com_error.log;
  access_log /apps/nginx/logs/www_darius_com_access.log access_json;
  location ~ \.php$ {
    root /data/nginx/php;    # $document_root調用root目錄
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    #fastcgi_param SCRIPT_FILENAME /data/nginx/php$fastcgi_script_name;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;    # 如果SCRIPT_FILENAME是絕對路徑則可以省略root /data/nginx/php;
    include fastcgi_params;
  }
}

[root@CentOS7 ~]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 ~]#nginx -s reload

訪問驗證php測試頁面

訪問配置文件裏面指定的路徑,會返回php-fpm的當前運行狀態。

Nginx配置

  location ~ ^/(pm_status|ping)$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
    include fastcgi_params;
  }

重啓Nginx並測試

[root@CentOS7 ~]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@CentOS7 ~]#nginx -s reload

[root@CentOS7 ~]#curl http://www.darius.com/pm_status
pool:                 www
process manager:      dynamic
start time:           02/Jun/2019:11:20:03 +0800
start since:          7
accepted conn:        1
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       99
active processes:     1
total processes:      100
max active processes: 1
max children reached: 0
slow requests:        0

[root@CentOS7 ~]#curl http://www.darius.com/ping
ping-pong
full格式狀態頁

Nginx實現FastCGI

html格式狀態頁

Nginx實現FastCGI

json格式狀態頁

Nginx實現FastCGI

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章