PHP-FPM使用指南

在LNMP的单机架构中,Nginx作为Web服务器,负责将PHP请求转发给PHP-FPM处理:

1
2
3
4
5
location ~  \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}

Nginx服务器通过FastCGI协议,发送环境变量和 HTTP 数据给PHP-FPM,Nginx和PHP-FPM之间可以通过 Unix domain socket 和 TCP connection 通信。PHP-FPM 处理请求后,通过相同的连接返回数据给 Nginx。

php-fpm

PHP-FPM是PHP实现的FastCGI Process Manager(FastCGI进程管理器), 负责管理创建和管理PHP FastCGI进程,支持的功能如下:

  • 平滑停止/启动的高级进程管理功能
  • 慢日志记录脚本
  • 动态/静态子进程产生
  • 基于php.ini的配置文件

PHP-FPM在5.4之后已经整合进入PHP源代码中,提供更好的PHP进程管理方式,可以有效控制内存和进程,平滑重载PHP配置。如果需要使用,在./configure的时候带上-enable-fpm参数即可,使用PHP-FPM来控制FastCGI进程。

./configure –prefix=/usr/local/php7 –with-config-file-path=/usr/local/php7/etc –enable-fpm …

PHP-FPM工作原理

php-fpm

  1. FastCGI进程管理器自身初始化,包括masterworker进程两部分,master进程监听端口,接收来自Web Server请求,worker进程一般具有多个,每个worker进程都有一个cgi进程解释器,用来执行php代码, 等待来自Web Server的连接。
  2. 当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web Server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi
  3. FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告知处理完成。FastCGI子进程接着等待并处理来自FastCGI继承管理器的下一个连接。

PHP-FPM配置

FPM配置文件为php-fpm.conf和进程池配置文件,其语法类似 php.ini 。其php手册上也有详细的讲解:http://php.net/manual/zh/install.fpm.configuration.php

php-fpm

重要配置参数:

全局配置

  • pidmaster进程pid存放路径,默认: pid = #INSTALL_PREFIX#/run/php-fpm.pid
  • error_log: 错误日志文件路径,默认:error_log = #INSTALL_PREFIX#/log/php-fpm.log, 设置为 “syslog”,日志将不会写入本地文件,而是发送到 syslogd
  • log_level:日志级别, alert, error, warning, notice, debug, 默认值: notice
  • syslog.facility:设置何种程序记录消息,默认值:daemon。
  • syslog.ident:为每条信息添加前缀。 如果在同一台服务器上运行了多个 FPM 实例,可以修改此默认值来满足需求。默认值:php-fpm
  • daemonize:设置FPM是否在后台运行,默认值:yes
  • process.max:Fork 的最大 FPM 进程数。使用动态管理进程数时,此设计可以控制在一个进程池内的全局进程数量。 使用需谨慎。默认值:0。
  • rlimit_files:设置 master 进程的打开文件描述符 rlimit 数,默认取系统值

进程池配置

php-fpm可以配置多个pool,每个pool都是以一个独立的配置文件来运作,默认都会定义在主配置文件的include包含文件目录中。php默认会提供一个www的pool,大概配置如下:

  • user:FPM 进程运行的Unix用户,默认为nobody,一般设置为www-data
  • group: FPM 进程运行的 Unix 用户组, 默认为nobody, 一般设置为www-data
  • listen: 设置接受 FastCGI 请求的地址,默认为127.0.0.1:9000
  • pm:设置进程管理器如何管理子进程,可用值:staticondemanddynamic
    - static*: 子进程的数量是固定的(*pm.max_children*)*
    - *ondemand*:进程在有需求时才产生(当请求时才启动。与 dynamic 相反,在服务启动时 *pm.start_servers* 就启动了
    - *dynamic*:子进程的数量在下面配置的基础上动态设置:*pm.max_children*,*pm.start_servers*,*pm.min_spare_servers*,*pm.max_spare_servers*
    
  • pm.max_childrenpm 设置为 static 时表示创建的子进程的数量,pm 设置为 dynamic 时表示最大可创建的子进程的数量
  • pm.start_servers:设置启动时创建的子进程数目,仅在 pm 设置为 dynamic 时使用
  • pm.min_spare_servers:设置空闲服务进程的最低数目,仅在 pm 设置为 dynamic 时使用
  • pm.max_spare_servers:设置空闲服务进程的最大数目,仅在 pm 设置为 dynamic 时使用
  • pm.process_idle_timeout:秒数,多久之后结束空闲进程,仅当设置 pmondemand。 可用单位:s(秒),m(分),h(小时)或者 d(天)。默认单位:10s
  • pm.max_requests:设置每个子进程重生之前服务的请求数
  • pm.status_path:FPM 状态页面的网址, 可以借助于这个数据调整PHP-FPM配置
  • ping.path:FPM 监控页面的 ping 网址。如果没有设置,则无法访问 ping 页面。该页面用于外部检测 FPM 是否存活并且可以响应请求,请注意必须以斜线开头(/)
  • ping.response:用于定义 ping 请求的返回响应。返回为 HTTP 200 的 text/plain 格式文本,默认值:pong
  • access.log:Access log 文件路径,默认未设置
  • access.format:Access log 格式,默认值: “%R - %u %t \”%m %r\” %s”
  • slowlog:慢请求的记录日志,默认值:#INSTALL_PREFIX#/log/php-fpm.log.slow
  • request_slowlog_timeout:当一个请求该设置的超时时间后,就会将对应的 PHP 调用堆栈信息完整写入到慢日志中,默认值:0(关闭)
  • request_terminate_timeout:设置单个请求的超时中止时间,该选项可能会对 php.ini 设置中的 ‘max_execution_time’ 因为某些特殊原因没有中止运行的脚本有用,设置为 ‘0’ 表示 ‘Off’
  • rlimit_files:设置文件打开描述符的 rlimit 限制,默认值:系统定义值

配置优化

进程配置

PHP-FPM是多进程模式,master进程管理worker进程,进程的数量,都可以通过php-fpm.conf做具体配置,而PHP-FPM的进程,亦可以分为动态模式及静态模式。

  • 静态(static):直接开启指定数量的php-fpm进程,不再增加或者减少;启动固定数量的进程,占用内存高。但在用户请求波动大的时候,对Linux操作系统进程的处理上耗费的系统资源低。
  • 动态(dynamic):开始的时候开启一定数量的php-fpm进程,当请求量变大的时候,动态的增加php-fpm进程数到上限,当空闲的时候自动释放空闲的进程数到一个下限。动态模式,会根据max、min、idle children 配置,动态的调整进程数量。在用户请求较为波动,或者瞬间请求增高的时候,进行大量进程的创建、销毁等操作,而造成Linux负载波动升高,简单