1. 程式人生 > >LNMP架構php-fpm相關配置

LNMP架構php-fpm相關配置

11月30日任務

12.21 php-fpm的pool

12.22 php-fpm慢執行日誌

12.23 open_basedir

12.24 php-fpm程序管理

 

php-fpm的pool

php-fpm.conf可以設定多個pool,在其中一個pool資源耗盡,會導致其他站點無法訪問資源,報502錯誤。有必要把站點進行分離,分別使用單獨的pool。

  • 修改php-fpm配置檔案程式碼
# 檔案地址:/usr/local/php-fpm/etc/php-fpm.conf
[[email protected] etc]# vim php-fpm.conf
...
# 新增一個pool程式碼設定
[test]
listen = /tmp/test.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
  • 修改虛擬主機配置檔案
# 這裡設定另外一個虛擬主機
# 實現不同虛擬主機訪問資源pool的隔離,互不影響
[[email protected] etc]# cat /usr/local/nginx/conf/vhost/aaa.com.conf 
server
{
	listen 80 default_server;
	index index.html index.htm index.php
	root /data/www/default;
        location ~ \.php$
        {
            include fastcgi_params;
            # 這裡寫對應php-fpm.conf內設定的sock
            fastcgi_pass unix:/tmp/test.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /data/www/default$fastcgi_script_name;
        }
}
  • 重啟php-fpm服務
[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -t
[... 19:37:17] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[[email protected] etc]# /etc/init.d/php-fpm reload
Reload service php-fpm  done
  • 檢視配置是否生效
# 已經可以看到建立的pool --- test
[
[email protected]
etc]# ps aux | grep php-fpm root 2895 1.7 0.3 227208 5008 ? Ss 19:37 0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf) ... php-fpm 2915 0.0 0.3 227148 4712 ? S 19:37 0:00 php-fpm: pool www php-fpm 2916 1.4 0.3 227148 4708 ? S 19:37 0:00 php-fpm: pool test ... root 2937 0.0 0.0 112680 976 pts/0 S+ 19:37 0:00 grep --color=auto php-fpm

實現程式碼分離

在php-fpm.conf內新增如下程式碼就可以實現類似虛擬主機配置檔案分離的效果。

[[email protected] etc]# cat php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
include = etc/php-fpm.d/*.conf

# 將原檔案內的www、test pool模組分別寫在不同的conf檔案內
[[email protected] etc]# vim php-fpm.d/www.conf
[www]
#listen = /tmp/php-fcgi.sock
listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

[[email protected] etc]# vim php-fpm.d/test.conf
[test]
listen = /tmp/test.sock
#listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
  • 重啟php-fpm服務
[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -t
[... 20:19:10] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[[email protected] etc]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
  • 檢視pool是否配置成功
# 這裡test池在前,www池在後
[[email protected] etc]# ps aux | grep php-fpm
root       3068  0.2  0.3 227236  4980 ?        Ss   20:20   0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf)
php-fpm    3069  0.0  0.3 227176  4712 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3070  0.0  0.3 227176  4712 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3071  0.0  0.3 227176  4712 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3075  0.0  0.3 227176  4716 ?        S    20:20   0:00 
...
php-fpm    3079  0.0  0.3 227176  4716 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3080  0.0  0.3 227176  4716 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3081  0.0  0.3 227176  4716 ?        S    20:20   0:00 php-fpm: pool test
php-fpm    3089  0.0  0.3 227176  4716 ?        S    20:20   0:00 php-fpm: pool www
...
php-fpm    3107  0.0  0.3 227176  4724 ?        S    20:20   0:00 php-fpm: pool www
php-fpm    3108  0.0  0.3 227176  4724 ?        S    20:20   0:00 php-fpm: pool www
root       3110  0.0  0.0 112680   976 pts/0    S+   20:20   0:00 grep --color=auto php-fpm

php-fpm慢執行日誌

通過分析php的慢執行日誌,可以得知php網站訪問緩慢原因。

  • 修改php配置檔案www.conf
[[email protected] etc]# vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
[www]
# 這裡監聽的sock修改為www.sock
listen = /tmp/www.sock
;listen = 127.0.0.1:9000
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
# 這裡新增下面兩行程式碼

# 設定slowlog間隔為1s,間隔超過1s會記錄到慢執行日誌內
# 實際工作中,可以設定為2s,1s太過短暫
request_slowlog_timeout = 1

# 指定slowlog檔案存放路徑
slowlog = /usr/local/php-fpm/var/log/www-slow.log
  • 重啟php服務
[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -t
[... 20:43:24] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[[email protected] etc]# /etc/init.d/php-fpm  reload
  • 修改虛擬主機配置檔案
[[email protected] etc]# vim /usr/local/nginx/conf/vhost/test.com.conf
# 修改sock檔案
fastcgi_pass unix:/tmp/www.sock;
...
  • 重啟nginx服務
[[email protected] etc]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] etc]# /usr/local/nginx/sbin/nginx -s reload
  • 設定測試php檔案
[[email protected] etc]# vim /data/www/test.com/sleep.php 
<?php
echo "test slow log";
sleep(2);
echo "done";
?>

要檢視具體的錯誤資訊,可以開啟php.ini內的display_error引數

  • 檢視慢執行日誌
[[email protected] etc]# cat /usr/local/php-fpm/var/log/www-slow.log 

[... 21:13:15]  [pool www] pid 3430
script_filename = /data/www/test.com/sleep.php
[0x00007f616ec772d8] sleep() /data/www/test.com/sleep.php:3

open_basedir引數設定

  • 相關配置程式碼
[[email protected] etc]# vim /usr/local/php-fpm/etc/php-fpm.d/test.conf 
# 新增如下程式碼
php_admin_value[open_basedir]=/data/www/test.com:/tmp/

效果測試

  • 先測試錯誤配置時php指令碼的效果
[[email protected] etc]# vim /usr/local/php-fpm/etc/php-fpm.d/test.conf 
# 將新增的程式碼內站點錯誤書寫為aaa.com
php_admin_value[open_basedir]=/data/www/aaa.com:/tmp/

重啟php-fpm服務

[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -t
[... 18:35:50] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[[email protected] etc]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done

使用curl測試網頁訪問

# 由於已經設定了open_basedir,網頁無法訪問
[[email protected] etc]# curl -x 127.0.0.1:80 test.com/test.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.12.2
Date: Tue, ... 10:38:45 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30
  • 修改正確後驗證
[[email protected] etc]# vim /usr/local/php-fpm/etc/php-fpm.d/test.conf 
# 將新增的程式碼錯誤書寫為
php_admin_value[open_basedir]=/data/www/test.com:/tmp/

重啟服務並驗證

[[email protected] etc]# /usr/local/php-fpm/sbin/php-fpm -t
[... 18:39:10] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[[email protected] etc]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done

# 成功訪問
[[email protected] etc]# curl -x 127.0.0.1:80 test.com/test.php -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, ... 10:39:20 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

php錯誤日誌設定

修復php.ini配置檔案,關閉display_errors引數

# 不在瀏覽器上顯示錯誤資訊
display_errors = Off

# 開啟錯誤日誌記錄
log_errors = On
# 設定存放路徑
error_log = /usr/local/php-fpm/var/log/php_errors.log
# 設定錯誤記錄級別
error_reporting = E_ALL

為了防止錯誤日誌無法建立並修改,最好先行建立並給予許可權。

[[email protected] etc]# touch /usr/local/php-fpm/var/log/php_errors.log
[[email protected] etc]# chmod 777 /usr/local/php-fpm/var/log/php_errors.log 

為了產生錯誤資訊,先故意寫錯php程式碼

[[email protected] etc]# touch /usr/local/php-fpm/var/log/php_errors.log
[[email protected] etc]# chmod 777 /usr/local/php-fpm/var/log/php_errors.log 
php_admin_value[open_basedir]=/data/www/aaa.com:/tmp/

訪問網頁,其錯誤資訊如下

[[email protected] etc]# curl -x 127.0.0.1:80 test.com/test.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.12.2
Date: Tue, ... 10:52:01 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

# 這裡明確指出所要訪問的網頁不在aaa.com站點
[[email protected] etc]# cat /usr/local/php-fpm/var/log/php_errors.log 
[... 10:52:01 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/www/test.com/test.php) is not within the allowed path(s): (/data/www/aaa.com:/tmp/) in Unknown on line 0
[... 10:52:01 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0

修改正確後再檢視日誌(php檔案已被解析)

[[email protected] etc]# cat /usr/local/php-fpm/var/log/php_errors.log 
...
[... 10:53:18 UTC] PHP Warning:  phpinfo(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /data/www/test.com/test.php on line 2

php-fpm程序管理

  • 程序管理
# 動態程序管理
pm = dynamic

# 靜態程序管理
# 設定了靜態程序管理的配置項只有緊跟該行的那項配置生效
pm = static
  • 最大子程序數
# 可以使用ps aux進行檢視
pm.max_children = 50
  • 設定啟動時開啟的PHP程序數
# 值可以根據需要進行修改
pm.start_servers = 20
  • 在空閒時段,子程序數的最小值
# 如果達到這個數值,php-fpm服務會自動派生新的子程序
pm.min_spare_servers = 5
  • 定義在空閒時段,子程序數的最大值
# 如果高於這個數值,就開始清理空閒的子程序
pm.max_spare_servers = 35
  • 定義一個子程序最多處理的請求數
# 對於該項而言,超出該值的話程序會因此而退出
pm.max_requests = 500

我們需要根據實際應用時的需要對上述引數的值進行配置,配置後重啟php-fpm服務使其生效即可。