nginx中配置php-FPM教程詳解

來源:互聯網
上載者:User

nginx中配置php-FPM教程

nginx 可以直接調用FPM來驅動php,從此就可以放棄apache了。什麼原因不多說了。
先下載php5.4的安裝包。

照別人的說法

 代碼如下 複製代碼
./configure --enable-fastcgi --prefix=/data1/server/php-cgi --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-sockets --with-curl --with-ttf --with-libxml-dir --with-config-file-path=/data1/server/php-cgi/etc --with-zlib --enable-exif --enable-ftp --with-xmlrpc --enable-zip --with-iconv-dir --with-libxml-dir --with-mcrypt --with-tidy --with-tidy --enable-fpm --enable-force-cgi-redirect

提示無法安裝enable-force-cgi-redirect 等等一堆玩意兒

好的,去掉一些東西來安裝

 代碼如下 複製代碼
./configure --prefix=/data1/server/php-cgi --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --enable-sockets --with-curl --with-libxml-dir --with-config-file-path=/data1/server/php-cgi/etc --with-zlib --enable-exif --enable-ftp --with-xmlrpc --enable-zip --with-iconv-dir --with-libxml-dir --with-mcrypt --with-tidy --with-tidy --enable-fpm

出現錯誤
configure: error: xml2-config not found. Please check your libxml2 installation.

 代碼如下 複製代碼

1.安裝他
#apt-get install libxml2-dev

錯誤
configure: error: Please reinstall the libcurl distribution -
easy.h should be in <curl-dir>/include/curl/

2.安裝他
apt-get install libcurl4-gnutls-dev

錯誤
configure: error: jpeglib.h not found.
3.安裝他
apt-get install libjpeg-dev

錯誤
If configure fails try –with-vpx-dir=<DIR>
configure: error: png.h not found.
4.安裝他
apt-get install libpng12-dev

錯誤
If configure fails try –with-xpm-dir=<DIR>
configure: error: freetype.h not found.
5.安裝他
apt-get install libfreetype6-dev

錯誤
configure: error: mcrypt.h not found. Please reinstall libmcrypt.
6.安裝他
apt-get install libmcrypt-dev

錯誤
configure: error: Cannot find libtidy
7.安裝他
apt-get install libtidy-dev

我一個一個測試的。大家安裝的時候,可以先安裝這些錯誤需要安裝的東西,然後再執行./configure……

make
make test
make install


啟動php-fpm

/data1/server/php-cgi/sbin/php-fpm

錯誤
[28-Mar-2012 11:15:01] ERROR: failed to open configuration file ‘/data1/server/php-cgi/etc/php-fpm.conf’: No such file or directory (2)
[28-Mar-2012 11:15:01] ERROR: failed to load configuration file ‘/data1/server/php-cgi/etc/php-fpm.conf’
[28-Mar-2012 11:15:01] ERROR: FPM initialization failed
cd /data1/server/php-cgi/etc

再次啟動
/data1/server/php-cgi/sbin/php-fpm

ERROR: [pool www] cannot get gid for group ‘nobody’
好吧,我們加一個組叫nobody

#groupadd nobody

再次啟動
/data1/server/php-cgi/sbin/php-fpm
成功了。

關閉php-fpm
killall php-fpm

目前還不知道有沒有直接的命令來關閉它。

cannot get gid for group ‘nobody’ 其他解決方案。
————————————————————————————
or can change it in your php-fpm.conf

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user’s group
; will be used.
user = www-data
group = nobody
————————————————————————————-

整合nginx

最後的配置

 代碼如下 複製代碼

# cd /etc/nginx/conf.d
#vi default.conf

location ~ \.php$ {

root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;

# vi /etc/nginx/fastcgi.conf

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

/etc/init.d/nginx stop
/etc/init.d/nginx start

成功啦。

給php一個設定檔,從安裝目錄拷貝一個
cp php.ini-development /data1/server/php-cgi/etc/php.ini

補充:php-fpm 輸出php錯誤記錄檔

nginx是一個web伺服器,因此nginx的access日誌只有對訪問頁面的記錄,不會有php 的 error log資訊。

nginx把對php的請求發給php-fpm fastcgi進程來處理,預設的php-fpm只會輸出php-fpm的錯誤資訊,在php-fpm的errors log裡也看不到php的errorlog

原因是php-fpm的設定檔php-fpm.conf中預設是關閉worker進程的錯誤輸出,直接把他們重新導向到/dev/null,所以我們在nginx的error log 和php-fpm的errorlog都看不到php的錯誤記錄檔。

調試起來就很痛苦了。解決nginx下php-fpm不記錄php錯誤記錄檔的辦法:

1.修改php-fpm.conf中配置 沒有則增加
catch_workers_output = yes
error_log = log/error_log

2.修改php.ini中配置,沒有則增加
log_errors = On
error_log = "/usr/local/lnmp/php/var/log/error_log"
error_reporting=E_ALL&~E_NOTICE

3.重啟php-fpm,
當PHP執行錯誤時就能看到錯誤記錄檔在"/usr/local/lnmp/php/var/log/error_log"中了

請注意:

1. php-fpm.conf 中的php_admin_value[error_log] 參數 會覆蓋php.ini中的 error_log 參數
所以確保你在phpinfo()中看到的最終error_log檔案具有可寫入權限並且沒有設定php_admin_value[error_log] 參數,否則錯誤記錄檔會輸出到php-fpm的錯誤記錄檔裡。


2.找不到php.ini位置,使用php的phpinfo()結果查看


3.如何修改PHP錯誤記錄檔不輸出到頁面或螢幕上
修改php.ini
display_errors = off //不顯示錯誤資訊(不輸出到頁面或螢幕上)
log_errors = on //記錄錯誤資訊(儲存到記錄檔中)
error_reporting = E_ALL //捕獲所有錯誤資訊
error_log = //設定記錄檔名

程式中修改以上配置
ini_set("display_errors",0)
ini_set("error_reporting",E_ALL); //這個值好像是個PHP的常量
ini_set("error_log","<記錄檔名>")
ini_set("log_errors",1);

4.如何將php的錯誤記錄檔輸出到nginx的錯誤記錄檔裡
在PHP 5.3.8及之前的版本中,通過FastCGI啟動並執行PHP,在使用者訪問時出現錯誤,會首先寫入到PHP的errorlog中
如果PHP的errorlog無法寫入,則會將錯誤內容返回給FastCGI介面,然後nginx在收到FastCGI的錯誤返回後記錄到了nginx的errorlog中
在PHP 5.3.9及之後的版本中,出現錯誤後PHP只嘗試寫入PHP的errorlog中,如果失敗則不會再返回到FastCGI了,錯誤記錄檔會輸出到php-fpm的錯誤記錄檔裡。
所以如果想把php錯誤記錄檔輸出到nginx錯誤記錄檔,需要使用php5.3.8之前的版本,並且設定檔中php的error_log對於php worker進程不可寫


php-fpm記憶體配置問題


nginx php-fpm配置過程中最大問題是內泄漏出問題:伺服器的負載不大,但是記憶體佔用迅速增加,很快吃掉記憶體接著開始吃交換分區,系統很快掛掉!
google了一天,終於發現些有用的東西,其實根據官方的介紹,php-cgi不存在記憶體流失,每個請求完成後php-cgi會回收記憶體,但是不會釋放給作業系統,這樣就會導致大量記憶體被php-cgi佔用。
官方的解決辦法是降低PHP_FCGI_MAX_REQUESTS的值,我用的是php-fpm,對應的php-fpm.conf中的就是max_requests,該值的意思是發送多少個請求後會重啟該線程,我們需要適當降低這個值,用以讓php-fpm自動的釋放記憶體,不是大部分網上說的51200等等,實際上還有另一個跟它有關聯的值max_children,這個是每次php-fpm會建立多少個進程,這樣實際上的記憶體消耗是max_children*max_requests*每個請求使用記憶體,根據這個我們可以預估一下記憶體的使用方式,就不用再寫指令碼去kill了。
下面其實是重啟指令碼的過程,並不是什麼很嚴重的事情,但是我們要小心,不是說一直重啟就是好的,因為重啟會導致cpu的使用率飆升,系統負載巨大,所以還是平衡上面的資料比較重要。
Mar 08 16:13:33.113138 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Mar 08 16:13:33.113202 [WARNING] fpm_children_bury(), line 215: child 23051 (pool default) exited on signal 11 SIGSEGV after 747.428492 seconds from start
Mar 08 16:13:33.113622 [NOTICE] fpm_children_make(), line 352: child 24511 (pool default) started


配置指南通訊指南

TCP配置方式

TCP通訊配置起來很簡單,三步即可搞定

第一步,編輯 /etc/nginx/conf.d/你的網站設定檔(如果使用的預設設定檔,修改/etc/nginx/sites-available/default)

將fastcgi_pass參數修改為127.0.0.1:9000,像這樣:

 代碼如下 複製代碼
location ~ \.php$ {
      index index.php index.html index.htm;
      include /etc/nginx/fastcgi_params;
      fastcgi_pass 127.0.0.1:9000;
      fastcgi_index index.php;
      include fastcgi_params;
 }

 第二步,編輯php-fpm設定檔 /etc/php5/fpm/pool.d/www.conf

將listen參數修改為127.0.0.1:9000,像這樣:

listen = 127.0.0.1:9000

 第三步,重啟php-fpm,重啟nginx

 unix socket配置方式

unix socket其實嚴格意義上應該叫unix domain socket,它是*nix系統處理序間通訊(IPC)的一種被廣泛採用方式,以檔案(一般是.sock)作為socket的唯一標識(描述符),需要通訊的兩個進程引用同一個socket描述符檔案就可以建立通道進行通訊了。

配置需要五步

第一步,決定你的socket描述符檔案的儲存位置。

可以放在系統的任意位置,如果想要更快的通訊速度,可以放在/dev/shm下面,這個目錄是所謂的tmpfs,是RAM可以直接使用的地區,所以,讀寫速度都會很快。

決定了檔案位置,就要修改檔案的許可權了,要讓nginx和php-fpm對它都有讀寫的許可權,可以這樣:

 代碼如下 複製代碼
sudo touch /dev/shm/fpm-cgi.sock
sudo chown www-data:www-data /dev/shm/fpm-cgi.sock
sudo chmod 666 /dev/shm/fpm-cgi.sock

 第二步,修改php-fpm設定檔/etc/php5/fpm/pool.d/www.conf

將listen參數修改為/dev/shm/fpm-cgi.sock,像這樣:


listen = /dev/shm/fpm-cgi.sock
 將listen.backlog參數改為-1,記憶體壓無限大,預設是128,並發高了之後就會報錯

 ; Set listen(2) backlog. A value of '-1' means unlimited.
 ; Default Value: 128 (-1 on FreeBSD and OpenBSD)
 listen.backlog = -1

 第三步,修改nginx網站設定檔

將fastcgi_pass參數修改為unix:/dev/shm/fpm-cgi.sock,像這樣:

 代碼如下 複製代碼
location ~ \.php$ {
      index index.php index.html index.htm;
      include /etc/nginx/fastcgi_params;
      fastcgi_pass unix:/dev/shm/fpm-cgi.sock;
      fastcgi_index index.php;
      include fastcgi_params;
}

第四步,修改/etc/sysctl.conf 檔案,提高核心層級的並發串連數(這個系統級的設定檔我也不是特別熟悉,參考的是這篇部落格:《Php-fpm TcpSocket vs UnixSocket》)

sudo echo 'net.core.somaxconn = 2048' >> /etc/sysctl.conf
sudo sysctl -p
第五步, 重啟nginx和php-fpm服務(最好先重啟php-fpm再重啟nginx)

 兩種通訊方式的分析和總結

從原理上來說,unix socket方式肯定要比tcp的方式快而且消耗資源少,因為socket之間在nginx和php-fpm的進程之間通訊,而tcp需要經過本地迴環驅動,還要申請臨時連接埠和tcp相關資源。

當然還是從原理上來說,unix socket會顯得不是那麼穩定,當並發串連數爆發時,會產生大量的長時緩衝,在沒有連線導向協議支撐的情況下,大資料包很有可能就直接出錯並不會返回異常。而TCP這樣的連線導向的協議,多少可以保證通訊的正確性和完整性。

當然以上主要是半懂不懂的理論分析加主觀臆測,具體的差別還是要通過測試資料來說話,以後有空,會進行這方面的測試。從網上別人部落格的測試資料,我的理論分析差不多是對的。至於你選擇哪種方式,我只能說“魚和熊掌不可兼得也”,通過高超的營運和配置技巧,在效能和穩定性上做一個平衡吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.