12.21 php-fpm的pool

12.22 php-fpm慢执行日志

12.23 open_basedir

12.24 php-fpm进程管理



12.21 php-fpm的pool

大纲

和LAMP不同的是,在LNMP架构中,php-fpm座位独立的一个服务存在。既然是独立服务,那么它必然有自己的配置文件。

php-fpm的配置文件为/usr/local/php-fpm/etc/php-fpm.conf,它同样也支持include语句,类似于nginx.conf里面的include。

Nginx可以配置多个虚拟主机,php-fpm同样也支持配置多个pool,每一个pool可以监听一个端口(ip:port),也可以监听一个socket。

为什么要隔离pool?

因为如果pool有某一个站点发生问题,例如其中一个站点占用了庞大的资源,导致其他站点运行卡顿,或者奔溃,所以这样会牵连pool里面其他站点的运行。


定义pool

1 进入php-fpm/etc/配置目录

 [root@AliKvn ~]#  cd /usr/local/php-fpm/etc/
[root@AliKvn etc]# ls
pear.conf  php-fpm.conf  php-fpm.conf.default  php.ini

2 添加pool,名为aming.com,参数如下。

[root@AliKvn etc]# vim php-fpm.conf
[aming.com]
listen = /tmp/aming.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

3 添加完成后-t检查语法并重启或者reload。

[root@AliKvn etc]# /usr/local/php-fpm/sbin/php-fpm -t
[02-May-2018 11:32:20] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[root@AliKvn etc]# /etc/init.d/php-fpm reload 
Reload service php-fpm  done

4 查看进程,看看进程右侧有没有多了刚刚配置的pool(aming.com)

5 修改aaa.com监听aming的socket,添加如下参数

location ~ \.php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/php-fcgi.sock;
#        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/default$fastcgi_script_name;
    }
}

6 加入 include语法,拆分pool的配置文件conf

include = etc/php-fpm.d/*.conf

[root@AliKvn php-fpm.d]# !vim


vim /usr/local/php-fpm/etc/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

6.1 复制参数

创建php-fpm.d目录

[root@AliKvn etc]# mkdir php-fpm.d
[root@AliKvn etc]# cd php-fpm.d/
[root@AliKvn php-fpm.d]# cat /usr/local/php-fpm/etc/php-fpm.conf

[root@AliKvn php-fpm.d]# vim www.conf 

6.2 复制www参数到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


6.3 复制aming.com参数到aming.conf

[root@AliKvn php-fpm.d]# vim aming.conf 
[aming.com]
listen = /tmp/aming.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


[root@AliKvn php-fpm.d]# ls
aming.conf  www.conf

7 复制完成后,删除php-fpm.conf两个pool的参数,加入include语法,再删除后可以看到参数是多么的干净利落。

[root@AliKvn php-fpm.d]# cat !$

cat /usr/local/php-fpm/etc/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


8 检查语法并重新加载。

[root@AliKvn php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t

[02-May-2018 12:07:00] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm restart

Gracefully shutting down php-fpm . done

Starting php-fpm  done

9 重启后检查进程

总结

定义多个pool的原因:

假如现在test.com的请求量很大,导致最终把php-fpm进程耗尽了。

最多可以启动50个子进程,但是启动完50个进程后,所有都在忙,又有新的请求来的时候,

此时会报502状态码,因为没有多余的php-fpm进程给请求监听服务。

而另外一个pool(aming.com)请求则不会受影响,因为它是另外一个pool。


12.22 php-fpm慢执行日志

做PHP网站,建议使用LNMP架构,其中一个原因在于我们可以分析PHP的慢执行日志。

例如,

用户反馈网站访问速度很慢(平时1-2s,现在要10s+),那此时应该怎么追踪问题点所在呢?

PHP慢执行日志就可以追踪到问题所在点在哪。

针对www.conf做实验,实操如下:

1 vim www.conf加入如下内容

#vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log

参数解释:

request_slowlog_timeout = 1 

超过一秒钟,则要记录日志

日志记录文件在

slowlog = /usr/local/php-fpm/var/log/www-slow.log

2 检查语法并重新加载reload

[root@AliKvn php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[02-May-2018 15:24:09] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm reload 
Reload service php-fpm  done

3 检查日志是否被生成

[root@AliKvn php-fpm.d]# ls /usr/local/php-fpm/var/log/
php-fpm.log  www-slow.log

确认有日志文件,

进行模拟测试php执行过程

因为www.conf是test.com的配置文件,所以在test.com目录下创建一个php文件。

4 vim sleep.php

vim /data/wwwroot/test.com/sleep.php

5 curl sleep.php没有任何反应,此时可以考虑配置是否有问题。

curl -I 发现错误状态码500。

[root@AliKvn php-fpm]# curl -x127.0.0.1:80 test.com/sleep.php
[root@AliKvn php-fpm]# curl -x127.0.0.1:80 test.com/sleep.php -I
HTTP/1.1 500 Internal Server Error
Server: nginx/1.8.0
Date: Wed, 02 May 2018 07:45:58 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

5.1 如果想curl的时候显示错误信息,可以修改php.ini的display_errors设置,把Off改成On。

(注意,此处应该是off的,因为正常网页在线上是不允许被看到内部信息的,错误信息也算内部信息)

5.2 reload重新加载php-fpm

[root@AliKvn php-fpm]# /etc/init.d/php-fpm reload 
Reload service php-fpm  done

5.3 再次curl

[root@AliKvn php-fpm]# curl -x127.0.0.1:80 test.com/sleep.php 

Parse error:  syntax error, unexpected 'slow' (T_STRING), expecting ',' or ';' in /data/wwwroot/test.com/sleep.php on line 2

有错误参数显示,此处的报错应该是php参数标点符号错误,

5.4 再次修改php配置参数,把标点符号都重新修改,利用英文键盘符号。

[root@AliKvn php-fpm]# vim /data/wwwroot/test.com/sleep.php

5.5 再次执行curl,

[root@AliKvn php-fpm]# curl -x127.0.0.1:80 test.com/sleep.php 
test slow logdone[root@AliKvn php-fpm]#

执行过程中间会停顿一会,证明效果见效了,因为sleep是有停顿动作。

6 此时查看慢执行日志的记录情况


[root@AliKvn php-fpm]# cat /usr/local/php-fpm/var/log/www-slow.log 
[02-May-2018 15:59:06]  [pool www] pid 1912
script_filename = /data/wwwroot/test.com/sleep.php
[0x00007f93dbc51270] sleep() /data/wwwroot/test.com/sleep.php:3

日志记录解释:

script_filename = /data/wwwroot/test.com/sleep.php
[0x00007f93dbc51270] sleep() /data/wwwroot/test.com/sleep.php:3

sleep.php这个脚本的第三行配置参数导致慢。

6.1 查看sleep.php的第三行参数


[root@AliKvn php-fpm]# cat /data/wwwroot/test.com/sleep.php 

第三行是 sleep(2),sleep(2)是执行了2秒钟,超过了1秒,因为当初配置慢执行文件设置了超过1秒(request_slowlog_timeout = 1)就会被记录日志里。所以被记录在慢执行日志里。


总结

很多php执行时间介于1-2秒之间,也就是说输入网址之后,启动网页的响应时间介于1-2秒之间。



12.23 open_basedir

open_basedir的目的就是安全,限制php活动。httpd可以针对每个虚拟主机设置一个open_basedir,

php-fpm同样也可以针对不同的pool设置不同的open_basedir。

例如针对www的pool来配置

配置如下:

[root@AliKvn php-fpm.d]# cd /usr/local/php-fpm/etc/php-fpm.d


1 编辑www的配置文件,www.conf

[root@AliKvn php-fpm.d]#vim /usr/local/php-fpm/etc/php-fpm.d/www.conf

在最后入如下内容

php_admin_value[open_basedir]=/data/wwwroot/aming.com:/tmp/

参数解释:

配置方法跟httpd有点相似

php_admin_value[open_basedir] open_basedir参数

/data/wwwroot/aming.com:/tmp/ 路径,此处的路径是针对站点路径的,

此处是为了做实验,所以路径故意写错。

2 重启服务

#/etc/init.d/php-fpm restart 

3 curl访问,curl的站点是test.com,而test.com的pool定义open_basedir不是test.com的目录,不是正确的路径,所以会出错。

导致404错误,访问失败。

如果将open_basedir的路径定义回test.com的目录,正常的话能成功访问。


[root@AliKvn php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php 
No input file specified.
[root@AliKvn php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.8.0
Date: Wed, 02 May 2018 10:03:51 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

4 修改www.conf


php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

4.1 重启服务

[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm restart 
Gracefully shutting down php-fpm . done
Starting php-fpm  done

4.2 再次curl测试,状态码200通过访问。

[root@AliKvn php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php  -I
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Wed, 02 May 2018 09:49:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

5 配置错误日志,

# vim php.ini

搜索/error_log 

5.1 配置reportting级别

重启服务 

[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm restart 

Gracefully shutting down php-fpm . done

Starting php-fpm  done

日志生成后,给予777权限,防止日志没法写入错误。

[root@AliKvn php-fpm.d]# chmod 777 /usr/local/php-fpm/var/log/php_errors.log 

6 故意把www.conf的open_basedir路径写错,再curl访问,测试日志文件有没有记录错误。


php_admin_value[open_basedir]=/data/wwwroot/1test.com:/tmp/

重启服务

[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm restart 
Gracefully shutting down php-fpm . done

7 curl 访问,404错误。

[root@AliKvn php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php 
No input file specified.
[root@AliKvn php-fpm.d]# curl -x127.0.0.1:80 test.com/3.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.8.0
Date: Wed, 02 May 2018 10:03:51 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30

7.1 查看日志

[root@AliKvn php-fpm.d]# tail -4 !$

tail -4 /usr/local/php-fpm/var/log/php_errors.log

[02-May-2018 10:03:40 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/test.com/3.php) is not within the allowed path(s): (/data/wwwroot/1test.com:/tmp/) in Unknown on line 0
[02-May-2018 10:03:40 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0
[02-May-2018 10:03:51 UTC] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/test.com/3.php) is not within the allowed path(s): (/data/wwwroot/1test.com:/tmp/) in Unknown on line 0
[02-May-2018 10:03:51 UTC] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0

日志信息解释:

大致意思就是访问站点路径跟限定路径(open_basedir)不同。找不到网页,所以会产生404报错。

7.2 更正www.conf的open_basedir路径,并重启服务

php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/
[root@AliKvn php-fpm.d]# /etc/init.d/php-fpm restart 
Gracefully shutting down php-fpm . done
Starting php-fpm  done

7.3 再次curl,状态码200,通过访问


[root@AliKvn php-fpm.d]# !curl 
curl -x127.0.0.1:80 test.com/3.php -I 
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Wed, 02 May 2018 10:11:58 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.30


总结

open_basedir的目的就是安全,限制php网页活动。





12.24 php-fpm进程管理


可以看到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
request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

 参数解释:

  •  pm = dynamic  //动态进程管理,也可以是static

  •  pm.max_children = 50 //最大子进程数,ps aux可以查看

  •  pm.start_servers = 20 //启动服务时会启动的进程数

  •  pm.min_spare_servers = 5 //定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程。

  •  pm.max_spare_servers = 35 //定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程。

  •  pm.max_requests = 500  //定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出。