第一部分:FPM 配置
参数 | 说明
-p | 命令行中动态修改--prefix
;include=etc/fpm.d/*.conf | 用于包含一个或多个文件,如果glob(3)存在(glob()函数返回匹配指定模式的文件名或目录)
第二部分:全局配置
由标志[global]开始:
;pid = run/php-fpm.pid 设置pid文件的位置,默认目录路径 /usr/local/php/var
;error_log = log/php-fpm.log 记录错误日志的文件,默认目录路径 /usr/local/php/var
;syslog.facility = daemon 用于指定什么类型的程序日志消息。
;syslog.ident = php-fpm 用于FPM多实例甄别
;log_level = notice 记录日志的等级,默认notice,可取值alert, error, warning, notice, debug
;emergency_restart_threshold = 0 如果子进程在这个时间段内带有IGSEGV或SIGBUS退出,则重启fpm,默认0表示关闭这个功能
;emergency_restart_interval = 0 设置时间间隔来决定服务的初始化时间(默认单位:s秒),可选s秒,m分,h时,d天
;process_control_timeout = 0 子进程等待master进程对信号的回应(默认单位:s秒),可选s秒,m分,h时,d天
; process.max = 128 控制最大进程数,使用时需谨慎
; process.priority = -19 处理nice(2)的进程优先级别-19(最高)到20(最低)
;rlimit_files = 1024 设置主进程文件描述符rlimit的数量
;rlimit_core = 0 设置主进程rlimit最大核数
;events.mechanism = epoll 使用处理event事件的机制
; - select (any POSIX os)
; - poll (any POSIX os)
; - epoll (linux >= 2.5.44)
; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
; - /dev/poll (Solaris >= 7)
; - port (Solaris >= 10)
;daemonize = yes 将fpm转至后台运行,如果设置为“no”,那么fpm会运行在前台
;systemd_interval = 10
第三部分:进程池的定义
通过监听不同的端口和不用管理选择可以定义多个不同的子进程池,进程池被用与记录和统计,对于fpm能够处理进程池数目的多少并没有限制
其中$pool变量可以在任何指令中使用,他将会替代相应的进程池名字。例如:这里的[www]
[root@test ~]# ps -ef | grep php-fpm root 3028 1 0 20:33 ? 00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf) nobody 3029 3028 0 20:33 ? 00:00:00 php-fpm: pool www nobody 3030 3028 0 20:33 ? 00:00:00 php-fpm: pool www
[www]
; It only applies on the following directives: ; - 'access.log' ; - 'slowlog' ; - 'listen' (unixsocket) ; - 'chroot' ; - 'chdir' ; - 'php_values' ; - 'php_admin_values' ;prefix = /path/to/pools/$pool 如果没有制定,将使用全局prefix替代
user = nobody 进程的发起用户和用户组,用户user是必须设置,group不是
group = nobody
listen = 127.0.0.1:9000 监听ip和端口
;listen.backlog = 65535 设置listen(2)函数backlog
;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
;listen.acl_users =
;listen.acl_groups =
;listen.allowed_clients = 127.0.0.1 允许FastCGI客户端连接的IPv4地址,多个地址用','分隔,为空则允许任何地址发来链接请求
; process.priority = -19
pm = dynamic 选择进程池管理器如何控制子进程的数量
static: 对于子进程的开启数路给定一个锁定的值(pm.max_children)
dynamic: 子进程的数目为动态的,它的数目基于下面的指令的值(以下为dynamic适用参数)
pm.max_children: 同一时刻能够存货的最大子进程的数量
pm.start_servers: 在启动时启动的子进程数量
pm.min_spare_servers: 处于空闲"idle"状态的最小子进程,如果空闲进程数量小于这个值,那么相应的子进程会被创建
pm.max_spare_servers: 最大空闲子进程数量,空闲子进程数量超过这个值,那么相应的子进程会被杀掉。
ondemand: 在启动时不会创建,只有当发起请求链接时才会创建(pm.max_children, pm.process_idle_timeout)
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
;pm.process_idle_timeout = 10s; 空闲进程超时时间
;pm.max_requests = 500 在派生新的子进程前,每一个子进程应该处理的请求数目,在第三方库中解决内存溢出很有用,设置为0则不会限制
;pm.status_path = /status 配置一个URI,以便查看fpm状态页
状态页描述:
accepted conn: 该进程池接受的请求数量
pool: 进程池的名字
process manager: 进程管理,就是配置中pm指令,可以选择值static,dynamic,ondemand
idle processes: 空闲进程数量
active processes: 当前活跃的进程数量
total processes: 总的进程数量=idle+active
max children reached: 达到最大子进程的次数,达到进程的限制,当pm试图开启更多的子进程的时候(仅当pm工作在dynamic时)
;ping.path = /ping 该ping URI将会去调用fpm监控页面,如果这个没有设置,那么不会有URI被做为ping页
;ping.response = pong 用于定制平请求的响应,响应的格式text/plain(对200响应代码)
;access.log = log/$pool.access.log
;access.format = "%R - %u %t "%m %r%Q%q" %s %f %{mili}d %{kilo}M %C%%"
; The following syntax is allowed
; %%: the '%' character
; %C: %CPU used by the request
; it can accept the following format:
; - %{user}C for user CPU only
; - %{system}C for system CPU only
; - %{total}C for user + system CPU (default)
; %d: time taken to serve the request
; it can accept the following format:
; - %{seconds}d (default)
; - %{miliseconds}d
; - %{mili}d
; - %{microseconds}d
; - %{micro}d
; %e: an environment variable (same as $_ENV or $_SERVER)
; it must be associated with embraces to specify the name of the env
; variable. Some exemples:
; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
; %f: script filename
; %l: content-length of the request (for POST request only)
; %m: request method
; %M: peak of memory allocated by PHP
; it can accept the following format:
; - %{bytes}M (default)
; - %{kilobytes}M
; - %{kilo}M
; - %{megabytes}M
; - %{mega}M
; %n: pool name
; %o: output header
; it must be associated with embraces to specify the name of the header:
; - %{Content-Type}o
; - %{X-Powered-By}o
; - %{Transfert-Encoding}o
; - ....
; %p: PID of the child that serviced the request
; %P: PID of the parent of the child that serviced the request
; %q: the query string
; %Q: the '?' character if query string exists
; %r: the request URI (without the query string, see %q and %Q)
; %R: remote IP address
; %s: status (response code)
; %t: server time the request was received
; it can accept a strftime(3) format:
; %d/%b/%Y:%H:%M:%S %z (default)
; %T: time the log has been written (the request has finished)
; it can accept a strftime(3) format:
; %d/%b/%Y:%H:%M:%S %z (default)
; %u: remote user
;slowlog = log/$pool.log.slow 用于记录慢请求
;request_slowlog_timeout = 0 慢日志请求超时时间,对一个php程序进行跟踪。
;request_terminate_timeout = 0 终止请求超时时间,在worker进程被杀掉之后,提供单个请求的超时间隔。由于某种原因不停止脚本执行时,应该使用该选项,0表示关闭不启用
(在php.ini中,max_execution_time 一般设置为30,表示每一个脚本的最大执行时间)
;rlimit_files = 1024 设置打开文件描述符的限制
;rlimit_core = 0 设置内核对资源的使用限制,用于内核转储
;chroot = 设置chroot路径,程序一启动就将其chroot放置到指定的目录下,该指令值必须是一个绝对路径
;chdir = /var/www 在程序启动时将会改变到指定的位置(这个是相对路径,相对当前路径或chroot后的“/”目录)
;catch_workers_output = yes 将worker的标准输出和错误输出重定向到主要的错误日志记录中,如果没有设置,根据FastCGI的指定,将会被重定向到/dev/null上
;clear_env = no 清理环境
;security.limit_extensions = .php .php3 .php4 .php5 限制FPM执行解析的扩展名
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
; Additional php.ini defines, specific to this pool of workers. These settings
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
; Defining 'extension' will load the corresponding shared extension from
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
; overwrite previously defined php.ini values, but will append the new value
; instead.
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M
总结
1) 在php-fpm的配置文件中,有两个指令非常重要,就是"pm.max_children" 和 "request_terminate_timeout"
第一个指令"pm.max_children" 确定了php-fpm的处理能力,原则上时越多越好,但这个是在内存足够打的前提下,每开启一个php-fpm进程要占用近30M左右的内存
如果请求访问较多,那么可能会出现502,504错误。对于502错误来说,属于繁忙进程而造成的,对于504来说,就是客户发送的请求在限定的时间内没有得到相应,过多的请求导致“504 Gateway Time-out”。这里也有可能是服务器带宽问题。
另外一个需要注意的指令"request_terminate_timeout",它决定php-fpm进程的连接/发送和读取的时间,如果设置过小很容易出现"502 Bad Gateway" 和 “504 Gateway Time-out”,默认为0,就是说没有启用,不加限制,但是这种设置前提是你的php-fpm足够健康,这个需要根据实际情况加以限定。
原文链接:https://www.cnblogs.com/jonsea/p/5522018.html
FPM工作流程
fpm 全名是FastCGI进程管理器,可以参考关于FastCGI的说明:CGI、FastCGI、PHP-CGI和PHP-FPM 概念区分
fpm启动后会先读php.ini,然后再读取相应的conf配置文件,conf配置可以覆盖php.ini的配置。启动fpm之后,会创建一个master进程,监听9000端口(可配置),master进程又会根据fpm.conf/www.conf去创建若干子进程,子进程用于处理实际的业务。当有客户端(比如nginx)来连接9000端口时,空闲子进程会自己去accept,如果子进程全部处于忙碌状态,新进的待accept的连接会被master放进队列里,等待fpm子进程空闲;这个存放待accept的半连接的队列有多长,由 listen.backlog 配置。
php-fpm的启动参数
#测试php-fpm配置
/usr/local/php/sbin/php-fpm -t
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf -t
#启动php-fpm
/usr/local/php/sbin/php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf
#关闭php-fpm
kill -INT `cat /usr/local/php/var/run/php-fpm.pid`
#重启php-fpm
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`
php-fpm.conf重要参数详解
pid = run/php-fpm.pid
#pid设置,默认在安装目录中的var/run/php-fpm.pid,建议开启
error_log = log/php-fpm.log
#错误日志,默认在安装目录中的var/log/php-fpm.log 如果设置为syslog,log就会发送给syslogd服务而不会写进文件里。
syslog.facility = daemon
# 把日志写进系统log,linux还不够熟悉,暂时不用理会。
syslog.ident = php-fpm
#系统日志标示,如果跑了多个fpm进程,需要用这个来区分日志是谁的。
log_level = notice
#错误级别. 可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。
process_control_timeout = 0
#设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0.
daemonize = yes
#后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。
listen = 127.0.0.1:9000
#fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置.
listen.backlog = -1
#未accept处理的socket队列大小,-1 on FreeBSD and OpenBSD,其他平台默认65535,高并发时重要,合理设置会及时处理排队的请求;太大会积压太多,处理完后nginx在前面都等超时断开这个和fpm的socket连接了,就杯具了。不要用-1,建议1024以上,最好是2的幂值。
# 一个池共用一个backlog队列,所有的池进程都去这个队列里accept连接。
# 最大数量受限于系统配置 cat /proc/sys/net/core/somaxconn,系统配置修改:vim /etc/sysctl.conf,增加 net.core.somaxconn = 2000 则最大为2000,然后php最大的backlog可以到2000。
listen.allowed_clients = 127.0.0.1
#允许访问FastCGI进程的IP,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket设置选项,如果使用tcp方式访问,这里注释即可。
user = www
group = www
#启动进程的帐户和组
pm = dynamic
#对于专用服务器,pm可以设置为static。
#如何控制子进程,选项有static和dynamic。如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由下开参数决定:
pm.max_children
#,子进程最大数
pm.start_servers
#,启动时的进程数
pm.min_spare_servers
#,保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers
#,保证空闲进程数最大值,如果空闲进程大于此值,此进行清理
pm.max_requests = 1000
#设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
pm.status_path = /status
#FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. munin监控会使用到
ping.path = /ping
#FPM监控页面的ping网址. 如果没有设置, 则无法访问ping页面. 该页面用于外部检测FPM是否存活并且可以响应请求. 请注意必须以斜线开头 (/)。
ping.response = pong
#用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong.
request_terminate_timeout = 0
#设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。
request_slowlog_timeout = 10s
#当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off'
slowlog = log/$pool.log.slow
#慢请求的记录日志,配合request_slowlog_timeout使用
rlimit_files = 1024
#设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。
rlimit_core = 0
#设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值.
chroot =
#启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用.
chdir =
#设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时)
catch_workers_output = yes
#重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 默认值: 空
fpm进程状态监控
1、nginx配置:遇到 status 的请求,直接转发给php
2、fpm配置:pm.status_path = /status
3、然后重新fpm和nginx,在浏览器里访问就能看到了:
默认以 text/plain 展示结果,可以传参数 ?json/html/xml 分别得到json等格式的结果;参数full可以查看每个子进程的明细
![](http://upload-images.jianshu.io/upload_images/1272254-923f5acaf373ac6c.png?imageMogr2/auto-orient/strip|imageView2/2/w/349/format/webp)
- pool 进程池名称
- process manager 进程管理方式
- start time 进程什么时候启动的
- start since 进程已经运行了多少秒
- accepted conn 该池总共accept了多少连接
- listen queue 等待accept的连接的数量
- max listen queue fpm启动后,历史最高等待accept的连接的数量
- listen queue len 配置的监听队列最大长度 受限于
listen.backlog
和系统cat /proc/sys/net/core/somaxconn
,两者中取最小值 - idle processes 闲置的进程数
- active process 正在工作的进程数(加上限制的,就是总的子进程数)
- total processes 总的子进程数量
- max active processes fpm启动后,历史最多同时工作的进程数
- max children reached 进程管理模式为 'dynamic'和 'ondemand'时,此数值是当子进程不够用时,master创建更多子进程的次数
- slow requests 慢请求个数
- full参数下
- pid 子进程ID;
- state 子进程状态(Idle, Running, ...);
- start time 子进程启动的时间;
- start since 子进程启动后运行了多少秒;
- requests 当前子进程一共处理了多少个请求;
- request duration 请求耗费的纳秒数;
- request method 请求方法 (GET, POST, ...);
- request URI 请求参数;
- content length POST请求时,请求的内容长度;
- user - the user (PHP_AUTH_USER) (or '-' if not set);
- script 请求的哪个php文件;
- last request cpu 上次请求耗费的cpu资源
- last request memory 上次请求耗费的内存峰值
- 如果进程是闲置状态,那这些信息记录的就是上次请求的相关数据,否则就是当前本次请求的相关数据。
链接:https://www.jianshu.com/p/6f3ad46a528b