安装php-fpm

半兽人 发表于: 2020-03-02   最后更新时间: 2020-03-02 22:35:09  
{{totalSubscript}} 订阅, 1,614 游览

安装php-fpm

1. 安装php运行环境

下载

wget http://cn2.php.net/get/php-7.1.26.tar.gz/from/this/mirror

2. 因为php安装需要编译,所以服务器应该保证gcc和g++环境的安装

yum -y install libxml2
yum -y install libxml2-devel
yum -y install openssl
yum -y install openssl-devel
yum -y install curl
yum -y install curl-devel
yum -y install libjpeg
yum -y install libjpeg-devel
yum -y install libpng
yum -y install libpng-devel
yum -y install freetype
yum -y install freetype-devel
yum -y install pcre
yum -y install pcre-devel
yum -y install libxslt
yum -y install libxslt-devel
yum -y install bzip2
yum -y install bzip2-devel
yum -y install gcc gcc-c++

3. php7中,对lib-zip和cmake版本要求较高,编译时可能会由于版本过低导致编译错误,需要手动编译源码包解决,这里下载libzip-1.5.1.tar.gz和cmake-3.13.4.tar.gz

wget  https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4.tar.gz
tar xvf cmake-3.13.4.tar.gz && cd cmake-3.13.4/
./bootstrap
gmake
gmake install
wget  https://libzip.org/download/libzip-1.5.1.tar.gz
tar -xvzf libzip-1.5.1.tar.gz 
cd  libzip-1.5.1
mkdir build && cd build/
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/libzip ..
make
make install

4.配置参数,添加--enable-fpm参数(nginx编译时应添加ngx_http_fastcgi_module模块)

./configure --prefix=/usr/local/php \
--with-curl \
--with-freetype-dir \
--with-gd \
--with-gettext \
--with-iconv-dir \
--with-kerberos \
--with-libdir=lib64 \
--with-libxml-dir \
--with-mysqli \
--with-openssl \
--with-pcre-regex \
--with-pdo-mysql \
--with-pdo-sqlite \
--with-pear \
--with-png-dir \
--with-jpeg-dir \
--with-xmlrpc \
--with-xsl \
--with-zlib \
--with-bz2 \
--with-mhash \
--enable-fpm \
--enable-bcmath \
--enable-libxml \
--enable-inline-optimization \
--enable-mbregex \
--enable-mbstring \
--enable-opcache \
--enable-pcntl \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-sysvsem \
--enable-sysvshm \
--enable-xml \
--enable-zip \
--with-libzip=/usr/local/libzip

5.执行编译

make && make install

6.配置文件

cp php.ini-development /usr/local/php/lib/php.ini
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
cp sapi/fpm/php-fpm /usr/local/sbin

注:

  • php-fpm.conf是PHP-FPM特有的配置文件
  • php.ini是所以php模式中必须的配置文件,对php的整体环境配置起作用
  • 两者的区别是,php-fpm.conf是PHP-FPM进程管理器的配置文件,php.ini是PHP解析的配置文件

7.PHP-FPM 主配置文件 /usr/local/php/etc/php-fpm.conf

[global]
pid = /var/run/php-fpm.pid
error_log = /var/log/php-fpm.log
process_control_timeout = 0
;动态方式下开启的php-fpm进程的最大数量
process.max = 10   (此值会影响到poll的最大进程数,以这里的数值为准,或者注释掉在pool里配置)
;设置 fpm 在后台运行
daemonize = yes
; 设置进程可以打开的文件描述符数量
rlimit_files = 65535
; 设置FPM 的事件处理机制
events.mechanism = epoll
;emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启
emergency_restart_threshold = 10(个)
emergency_restart_interval = 5(s)
;  加载pool 配置
include = /usr/local/php/etc/php-fpm.d/*.conf
注:
  1. SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。
  2. SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。

8.创建用户和组

useradd aaa groupadd aaa

9.配置子配置文件(pool池)

vim /usr/local/php/etc/php-fpm.d/aaa.conf
[aaa.com]
user = aaa
group = aaa
listen = 127.0.0.1:9000
;允许访问FastCGI进程的IP,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接
listen.allowed_clients = 127.0.0.1
; 如何控制子进程,选项有static、dynamic和ondemand。如果选择static,则由pm.max_children指定固定的子进程数。ondemand: 按需分配,当收到用户请求时fork worker进程。 如果选择ondemand,按需分配,当收到用户请求时fork worker进程。如果选择dynamic,则由以下参数决定:
pm = dynamic
pm.max_children = 10
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
; 设置每个进程可处理的请求数,当进程达到这个请求数量后会自动释放在重新生成新的进程。避免内存泄漏等情况
pm.max_requests = 15 
; FPM 的监控设置
pm.status_path = /status
; 终止请求超时时间。一个请求若处理大于20s ,则会自动kill 掉。避免进程堆积
request_terminate_timeout = 20
catch_workers_output = no
; 限制 FPM 允许解析的脚本扩展名. 这里不限制,FPM可以解析任何扩展名的文件
security.limit_extensions = ""
注:

pm.max_requests = 15 ,这段配置的意思是,当一个 PHP-CGI 进程处理的请求数累积到 15个后,自动重启该进程。如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.

为什么要重启呢?

一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库经常存在内存泄漏问题,如果不定期重启 PHP-CGI 进程,势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器,提供了这么一项监控功能,对请求达到指定次数的 PHP-CGI 进程进行重启,保证内存使用量不增长。

10.配置nginx
server {
  listen       80;
  server_name  aaa.com;
  location / {
    root   html;
    index  index.html index.htm;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   html;
  }

  location ~ /status {
    include fastcgi.conf;
    fastcgi_pass 127.0.0.1: 9000;
  }

  location ~ /ping {
    include fastcgi.conf;
    fastcgi_pass 127.0.0.1: 9000;
  }
  location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1: 9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

11. 启动php-fpm,默认端口为9000

/usr/local/php/sbin/php-fpm

开启php-fpm监控功能

# cat /usr/local/php/etc/php-fpm.d/aaa.conf | grep status
pm.status_path = /status

注:这里斜杠后的status是可以自定义的,在nginx上location上配置匹配的选项即可。

location ~ /status {
    include fastcgi.conf;
    fastcgi_pass 127.0.0.1: 9000;
  }

验证动态模式下开启的进程数

# ps -ef|grep php-fpm

root         252       1  0 22:11 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nobody       253     252  0 22:11 ?        00:00:00 php-fpm: pool aaa.com
nobody       254     252  0 22:11 ?        00:00:00 php-fpm: pool aaa.com
nobody       255     252  0 22:11 ?        00:00:00 php-fpm: pool aaa.com
nobody       256     252  0 22:11 ?        00:00:00 php-fpm: pool aaa.com
nobody       257     252  0 22:11 ?        00:00:00 php-fpm: pool aaa.com
root         279     167  0 22:12 pts/4    00:00:00 grep --color=auto php-fpm

查看php-fpm状态参数

# curl aaa.com/status

pool:                 aaa.com
process manager:      dynamic
start time:           02/Mar/2020:22:11:37 +0800
start since:          511
accepted conn:        1
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       4
active processes:     1
total processes:      5
max active processes: 1
max children reached: 0
slow requests:        0

相应参数解释

# PHP-FPM 的POOL名字
pool:                 aaa.com
# 这个POOL中进程管理方式,这里是动态管理方式。相反还有静态管理方式。
process manager:      dynamic
# POOL从什么时间开始启动
start time:          09/Mar/2019:21:02:43 +0800
# POOL 从启动到现在已经存活了多久
start since:         779   (单位秒)
# 当前POOL接受的请求数
accepted conn:        1
# 请求等待队列当前长度,如果这个值不为0,那么说明你的请求处理已经开始有挤压了,应该注意系统状态。
listen queue:         0
# 从启动到现在,请求等待队列历史最大长度
max listen queue:     0
# 请求队列长度大小
listen queue len:     128
# 目前空闲进程数
idle processes:       4
# 目前工作进程数
active processes:     1
# 目前总进程数
total processes:      5
# 从启动到现在,最大的活跃进程数量
max active processes: 1
# 达到进程最大数量限制的次数,如果这个数量不为0,那说明设置的最大进程数量(pm.max_children)太小了,或者进程积压了。
max children reached: 0
# 慢请求的数量
slow requests:        0

总结

nginx与php-fpm的完整流程是这样的

screenshot

如图,简单版的cgi工作方式

screenshot

默认虚拟主机

默认虚拟主机就是配置文件里的第一个虚拟主机。关于默认虚拟主机有个特点,凡是解析到这台机器的域名,不管是什么域名,只要在配置文件中没有配置,那么都会访问到这个虚拟主机上来。也就是说默认虚拟主机是一个兜底的虚拟主机。

php-fpm的三种运行模式

php-fpm支持三种运行模式,分别为staticondemanddynamic,默认为dynamic 。

  • static: 静态模式,启动时分配固定的worker进程。

  • ondemand: ondemand: 按需分配,当收到用户请求时fork worker进程,也就是说最初系统不会启动php-fpm进程,当有连接进来时按需启动。

  • dynamic: 动态模式,启动时分配固定的进程。伴随着请求数增加,在设定的浮动范围调整worker进程

验证

1.static模式

/usr/local/php/etc/php-fpm.d/aaa.conf里配置运行模式为static,并配置最大开启的进程数为10。

# cat /usr/local/php/etc/php-fpm.d/aaa.conf
pm = static
pm.max_children = 10
...

重启php-fpm,查看php-fpm进程数量

# ps -ef |grep php-fpm|grep pool|wc -l
10

可以看到,当配置文件里设置php-fpm的运行方式为static模式时,启动的php-fpm进程数只受pm.max_children 这个参数值的影响,与其他的参数值无关。

2.ondemand模式

修改配置文件aaa.conf,配置为ondemand模式,与其相关的两个参数是pm.max_children 和 pm.process_idle_timeout , pm.process_idle_timeout 表示系统检测到php-fpm进程的空闲时间(秒)达到规定值时就会将其会kill。如下:

pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 15

修改完成后启动php-fpm,查看进程数如下:

# ps -ef|grep php-fpm
root         320       1  0 22:32 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
root         322     167  0 22:32 pts/4    00:00:00 grep --color=auto php-fpm

可以看到php-fpm的master启动时,并没有fork出子进程。

通过curl去测试访问

curl 127.0.0.1/test.php

再次查看进程数,可以看到已经有一个php-fpm进程启动。

ps -ef|grep php-fpm  
root         320       1  0 22:32 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
nobody       328     320  0 22:34 ?        00:00:00 php-fpm: pool aaa.com
root         330     167  0 22:34 pts/4    00:00:00 grep --color=auto php-fpm

在配置文件里写到php-fpm进程空闲15s后将会被masterkill掉,这里可以等待15s左右再去查看进程数,如下,可以看到该进程已经被kill掉。

# ps -ef|grep php-fpm
root         320       1  0 22:32 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
root         332     167  0 22:34 pts/4    00:00:00 grep --color=auto php-fpm
更新于 2020-03-02

查看php-fpm更多相关的文章或提一个关于php-fpm的问题,也可以与我们一起分享文章