what's FastCGi for php

preface

  公司全部的大多數業務都泡在LNMP平臺上,因此對PHP+Nginx有點了解,那麼就作個小小的總結吧。php

what's FastCGi

  FastCGI是一個可伸縮,高速的在HTTP server和動態腳本語言間通訊的接口。FastCGI支持多種腳本語言和HTTP server。
  FCGI是由CGI發展改進而來的。傳統的CGI接口方式的性能不好。每次HTTP服務器遇到動態程序時都須要從新啓動腳本解釋器來執行解析,而後將結果返回給HTTP服務器,這在處理高併發訪問時幾乎是不可用的。另外傳統的CGI接口方式安全性也不好,如今不多使用了。
  FCGI接口方式採用C/S結構,能夠將HTTP服務器和腳本解釋器分開,同時在腳本解釋器上啓動一個或者多個腳本解釋器守護進程。當HTTP服務器遇到動態程序時,能夠將其直接交付給FCGI進程來執行,而後將獲得的結果返回給瀏覽器。這種方式可讓HTTP服務器專注的處理靜態請求或者動態腳本的結果返回給客戶端,這就很大程度上提升了響應速度。html

Nginx + FCGI運行原理

  Nginx 不支持對外部程序的直接調用或者解析,全部的外部程序(包括PHP)必須經過FCGI接口來調用。FCGI接口在linux是socket(這個socket是文件socket,也能夠是ip socket)。爲了調用CGI程序,還須要一個FCGI的wrapper(wrapper能夠理解爲啓動另外一個程序的程序)。這個wrapper綁定在某個固定的socket上,如端口或者文件的socket,當Nginx將cgi請求發送給這個socket的時候,經過FCGI接口,wrapper接收到請求,而後派生出一個新的線程,這個線程調用解釋器或者外部程序處理腳本並讀取數據,接着,wrapper將返回的數據經過FCGi接口,沿着固定的socket傳給Nginx,最終,NGinx將返回的數據發送給客戶端,這就是Nginx+FCGi的運行流程。如圖所示:
前端

spawn-fcgi 和 php-fpm

  FCGI接口方式在腳本解析服務器上啓動一個或者多個守護進程對動態腳本進行解析,這些進程就是FastCGI進程管理器,或者稱爲fastCgi引擎,spawn-fcgi 和 PHP-FPM就是支持php的兩個Fcgi進程管理器。
  span-fcgi是HTTP服務器lighttpd的一部分,目前是獨立的一個項目,通常與lighttpd配合使用來支持PHP,可是lighttpd的spwan-fcgi在高併發訪問的時候,會出現內存泄漏甚至自動重啓FastCGI的問題
  Nginx是個輕量級的HTTPserver,必須藉助第三方的FCGI處理器才能夠對PHP進行解析。
  PHP-FPM是一個第三方的FCGI進程管理器,它是PHP的一個補丁來開發的,在安裝的時候也須要和PHP源碼一塊兒編譯,也就是說PHP-FPM被編譯到PHP內核中,所以處理性能方面更加優秀,同事PHP-FPM在處理高併發方面也比spawn-fcgi引擎好不少,因此推薦NGINX+PHP-FPM組合。linux

  FCGI的主要優勢是把動態語言和HTTP server分離開來,因此Nginx 與 php、php-fpm常常被部署在不一樣的服務器上,以分擔前端Nginx的服務器壓力,讓nginx 專注處理靜態請求和轉發動態請求。而PHP、PHP-fpm服務器專注解析PHP動態請求。nginx

那麼就部署它們吧

  php下載地址: http://php.net
  php-fpm下載地址:http://php-fpm.org/downloads/
  我這裏下載的php是php-5.5.38
  安裝以前,把依賴包都安裝好,採用yum安裝 :c++

yum -y install gcc gcc++ libxml2 libxml2-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel zlib zlib-devel glibc-devel glib2 glib2-devel

安裝好依賴包後,安裝phpweb

./configure --prefix=/usr  /local/php --enable-fpm --enable-fastcgi(可能會提示沒有這個選項)
    make && make install

  編譯沒有問題後,咱們開始配置和優化php-fpm,php全局配置文件是php.ini,編譯後是在/etc/php.ini這下面。redis

重點介紹php-fpm引擎的配置文件
php-fpm配置文件也在/etc/php-fpm.conf下面,默認狀況下會把/etc/php-fpm.d/www.conf 的配置文件include進去。vim

咱們在www.conf裏面看看如下幾項:
    listen = 127.0.0.1:9000 #監聽了本地9k端口
    user = nginx     #運行用戶
    group = nginx
    pm.max_children = 50        # 設置fcgi的進程數,官方建議小於2G內存開啓64個,4G能夠開200個
    request_terminate_timeout = 0   # 用於設置FCGI執行腳本的時間,默認是0秒,也就是五險的執行下去,能夠更加狀況改
    rlimit_files = 1024 #設置PHP-FPM 打開文件描述符的限制,這個值要和linux內核打開文件數關聯起來,例如,要將此值設置爲65535,就必須在linux命令上執行ulimit -HSN 65536
    pm.max_requests = 500  設置處理多少個請求後便會關閉,默認是500,
    listen.allowed_clients = 127.0.0.1    # 設置容許訪問FCGI進程解析器的IP地址,若是不在IP地址,將沒法接受Nginx轉發過來的php解析請求。

瞭解完上訴配置後,就能夠啓動FastCGI了,啓動命令以下:後端

[root@salt ~]# php-fpm        啓動php-fpm

若是有像這樣的報錯:

[root@salt php]# php-cgi 
    PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/redis.so' - /usr/lib64/php/modules/redis.so: undefined symbol: igbinary_unserialize in Unknown on line 0

那麼在/etc/php.ini把這行註釋掉啓動就能夠了:

;  extension=/usr/lib64/php/modules/redis.so

Notice

若是是php7.0版本以上的,可使用如下命令安裝redis

[root@salt ~]# pecl install redis
pecl/redis requires PHP (version >= 7.0.0, version <= 7.1.0, excluded versions: 6.0.0),              installed version is 5.5.32
No valid packages found
install failed

配置nginx來支持php
咱們切換到nginx配置文件目錄下,發現有個default.conf的模版文件,咱們copy一份來修改後便可用,命令以下:

[root@salt ~]# cd /etc/nginx/conf.d/
[root@salt conf.d]# ls
default.conf
[root@salt conf.d]# cp default.conf web1.conf
[root@salt conf.d]# mv default.conf default.cf    # 避免默認配置影響nginx運行
[root@salt conf.d]# vim web1.conf 
# 寫入如下內容:
server {
    listen       80;
    server_name  web1.test.com;
    charset utf8;
    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    location ~ \.php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;;
        include        fastcgi_params;
    }
}

參數解釋

  • location 正則匹配到以php結尾的到這裏解析,
  • root 指明瞭網站目錄
  • fastcgi_pass 指明瞭用哪裏的php-fpm來解析
  • fastcgi_index 指明首頁
  • fastcgi_param 指明的是php動態程序的主目錄,/scripts也就是$fastcgi_script_name前面指定的路徑,咱們通常在這裏寫網站根目錄的路徑,好比咱們的路徑是 /var/www/html。

測試php+nginx是否正常工做

在網站根目錄下面建立Index.php文件,寫入一些內容,命令以下:

/var/www/html/index.html的內容:
<h1>
    <span> hello, this is test page </span>
</h1>
/var/www/html/phpinfo.php內容:
<?php phpinfo(); ?>

咱們訪問http://ip/若是出現自定義頁面,那麼就成功了。
訪問http://ip/phpinfo.php 出現php安裝信息,那麼也算成功了。

優化Nginx和FastCgi參數

咱們在nginx配置文件裏面的http段內添加一下內容,好比咱們如今使用的web1.conf文件,那麼我就在web1.conf裏面添加如下內容:

fastcgi_connect_timeout 300;    
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;

參數解釋

  • fastcgi_connect_timeout 300;` 值鏈接到後端FastCGI的超時時間
  • fastcgi_send_timeout 300; 指向Fastcgi 傳送請求的超時時間,這個值是已經完成了2次握手後向FastCGI應答的超時時間
  • fastcgi_read_timeout 300; 指向接收FastCGI應答的超時時間,這個是已經完成2次握手後接收FastCGI應答的超時時間
  • fastcgi_buffer_size 64k; 用於指定讀取FastCGI。 應答第一部分須要多大的緩衝區,這個值表示將使用1個64KB的緩衝區讀取應答的第一部分(應答頭),能夠設置Fastcgi_buffers選項指定的緩衝區大小。
  • fastcgi_buffers 4 64k; 指定本地須要多少和多大的緩衝區緩衝FastCGI的應答請求。若是一個PHP腳本所產生的頁面大小爲256KB,那麼就會爲其分配4個64KB的緩衝區來緩存,若是頁面大小大於256KB,那麼大於256KB的部分會緩存到Fastcgi_temp指定的路徑中。可是這個不是好辦法。由於內存中的數據處理速度大於硬盤,通常這個值應該爲站點中的php腳本所產生的頁面大小的中間值,若是站點大部分腳本所產生的頁面大小爲256KB,那麼能夠把這個值設置爲16 16K,或者4 64KB。。
  • fastcgi_busy_buffers_size 128k; 默認值是fastcgi_buffers的兩 倍
  • fastcgi_temp_file_write_size 128k; 表示寫入緩存文件時使用多大的數據塊,默認是fastcgi_buffers的兩倍。
  • 開啓緩存後:
    fastcgi_cache_valid 200 302 1h;將http狀態碼是200的和302的緩存一小時,301的緩存一天,其餘的緩存一分鐘

  • fastcgi_cache_valid 301 1d;
  • fastcgi_cache_valid any 1m;

寫完以上參數後,保存退出重啓服務。

相關文章
相關標籤/搜索