Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • PHP

    • PHP-FPM使用指南
      • 1. 基本介绍
      • 2. PHP-FPM工作原理
      • 3. PHP-FPM配置
        • 3.1 全局配置
        • 3.2 进程池配置
      • 4. 配置优化
        • 4.1 进程配置
        • 4.2 最大处理请求数
        • 4.3 最长执行时间
      • 5. 常见异常
        • 5.1 502错误
        • 5.2 504错误
    • PHP7新特性总结
    • PHP安全编程
    • PHP安全配置总结
    • PHP变量的值类型和引用类型
    • PHP标准规范PSR
    • PHP操作Zookeeper实践
    • PHP错误和异常处理机制详解
    • PHP的Session运行机制
    • PHP底层运行机制和原理
    • PHP反射模拟实现注解路由
    • PHP高级用法总结
    • PHP开发常用文档总结
    • PHP开发入门:Memcached扩展安装
    • PHP开发入门:PHP7安装部署
    • PHP开发入门:Redis扩展安装
    • PHP开发SPL总结
    • PHP框架常见URL模式
    • PHP扩展开发入门
    • PHP垃圾回收机制
    • PHP类的自动加载
    • PHP输入输出流
    • PHP微服务开发指南
    • PHP协程
    • PHP写时拷贝技术
    • PHP性能优化之Opcache
    • PHP依赖注入和控制反转
    • PHP运行模式(SAPI)
    • PHP中file_get_contents与curl区别
    • RPC的简单实现
    • Protobuf:高效数据结构化工具
    • P3P协议详解
    • Laravel之集合(Collection)总结
    • Laravel实践总结
    • Laravel之ORM总结
    • 中高级PHP实践总结
    • PHP Socket编程实战
  • Golang

  • Python

  • Javascript

  • 其他语言

  • 编程语言
  • PHP
Ravior
2017-02-08
目录

PHP-FPM使用指南

# 1. 基本介绍

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

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

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 5.4之后PHP-FPM已经整合进入PHP源代码中,如果需要使用,在安装PHP./configure的时候带上-enable-fpm参数即可:

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

# 2. PHP-FPM工作原理

php-fpm

  1. FastCGI进程管理器自身初始化,包括master和worker进程两部分,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进程情况:

root     16728  0.0  0.3 223832 12320 ?        Ss   Oct10   0:25 php-fpm: master process (/usr/local/php7/etc/php-fpm.conf)
www-data 16729  0.0  0.5 447776 19868 ?        Sl   Oct10   0:08 php-fpm: pool www
www-data 16730  0.0  0.5 523508 23248 ?        Sl   Oct10   0:07 php-fpm: pool www
www-data 16731  0.0  0.4 447592 18624 ?        Sl   Oct10   0:08 php-fpm: pool www
www-data 16732  0.0  0.4 447572 18340 ?        Sl   Oct10   0:08 php-fpm: pool www
www-data 16733  0.0  0.4 447592 18424 ?        Sl   Oct10   0:09 php-fpm: pool www
www-data 16746  0.0  0.4 447572 19524 ?        Sl   Oct10   0:09 php-fpm: pool www
1
2
3
4
5
6
7

# 3. PHP-FPM配置

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

php-fpm

配置文件示例:

[global]
pid = run/php-fpm.pid
log_level = error

[www]
user = www-data
group = www-data

listen = 127.0.0.1:9000
slowlog = /usr/local/php7/var/log/$pool.log.slow
request_slowlog_timeout = 2
request_terminate_timeout = 60
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
pm.status_path = /fpm_status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3.1 全局配置

  • pid:master进程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 数,默认取系统值

# 3.2 进程池配置

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:设置进程管理器如何管理子进程,可用值:static,ondemand,dynamic
    • 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_children:pm设置为static时表示创建的子进程的数量,pm设置为dynamic时表示最大可创建的子进程的数量
  • pm.start_servers:设置启动时创建的子进程数目,仅在pm设置为dynamic时使用
  • pm.min_spare_servers:设置空闲服务进程的最低数目,仅在pm设置为dynamic时使用
  • pm.max_spare_servers:设置空闲服务进程的最大数目,仅在pm设置为dynamic时使用
  • pm.process_idle_timeout:秒数,多久之后结束空闲进程,仅当设置pm为ondemand时使用。 可用单位: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 限制,默认值:系统定义值

# 4. 配置优化

# 4.1 进程配置

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

  • 静态(static):直接开启指定数量的php-fpm进程,不再增加或者减少;启动固定数量的进程,占用内存高。但在用户请求波动大的时候,对Linux操作系统进程的处理上耗费的系统资源低。
  • 动态(dynamic):开始的时候开启一定数量的php-fpm进程,当请求量变大的时候,动态的增加php-fpm进程数到上限,当空闲的时候自动释放空闲的进程数到一个下限。动态模式,会根据max、min、idle children 配置,动态的调整进程数量。在用户请求较为波动,或者瞬间请求增高的时候,进行大量进程的创建、销毁等操作,而造成Linux负载波动升高,简单来说,请求量少,PHP-FPM进程数少,请求量大,进程数多。优势就是,当请求量小的时候,进程数少,内存占用也小。
  • 按需模式(ondemand):这种模式下,PHP-FPM的master不会fork任何的子进程,纯粹就是按需启动子进程,这种模式很少使用,因为这种模式,基本上是无法适应有一定量级的线上业务的。由于php-fpm是短连接的,所以每次请求都会先建立连接,建立连接的过程必然会触发上图的执行步骤,所以,在大流量的系统上master进程会变得繁忙,占用系统cpu资源,不适合大流量环境的部署

大概逻辑如下:

  • 在pm=dynamic时,如果idle worker数量<pm.min_spare_servers,创建新的子进程
  • 在pm=dynamic时,如果idle worker数量>pm.max_spare_servers,杀死多余的空闲子进程
  • 在pm=ondemand时,如果idle worker空闲时间>pm.process_idle_timeout,杀死该空闲进程
  • 当连接到达时,检测如果worker数量>pm.max_children,打印warning日志,退出;如果无异常,使用idle worker服务,或者新建worker服务

进程配置总结:

进程配置关系到PHP-FPM并发处理量,与服务器QPS指数息息相关,以下是几点经验总结:

  • 内存比较少,并发量不是很大的应用,可以考虑采用dynamic的方式,这样可以控制php-fpm所消耗的总内存数。
  • 在并发高或者流量波动大的情况下,使用static可以在高并发下获得比dynamic更快的响应速度。
  • 可配置进程数量: php-fpm 可配置内存 / (php-fpm 子进程的内存占用 * 1.2)

# 4.2 最大处理请求数

最大处理请求数是指一个php-fpm的worker进程在处理多少个请求后就终止掉,master进程会重新respawn一个新的,这个配置的主要目的是避免php解释器或程序引用的第三方库造成的内存泄露。

pm.max_requests = 10240
1

# 4.3 最长执行时间

最大执行时间在php.ini和php-fpm.conf里都可以配置,配置项分别为max_execution_time和request_terminate_timeout

# 5. 常见异常

# 5.1 502错误

502 Bad Gateway 在php.ini和php-fpm.conf中分别有这样两个配置项:max_execution_time和request_terminate_timeout。 这两项都是用来配置一个PHP脚本的最大执行时间的,当超过这个时间时,PHP-FPM不只会终止脚本的执行,还会终止执行脚本的Worker进程,Nginx会发现与自己通信的连接断掉了,就会返回给客户端502错误。

# 5.2 504错误

504 Gateway Time-out由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时。

PHP-FPM设置的脚本最大执行时间已经够长了,但执行耗时PHP脚本时,发现Nginx报错从502变为504了。这是为什么呢?

因为我们修改的只是PHP的配置,Nginx中也有关于与上游服务器通信超时时间的配置 factcgi_connect/read/send_timeout。

# fastcgi连接超时时间,默认60秒
fastcgi_connect_timeout 

# nginx 进程向 fastcgi 进程发送请求过程的超时时间,默认值60秒
fastcgi_send_timeout 

# fastcgi 进程向 nginx 进程发送输出过程的超时时间,默认值60秒 
fastcgi_read_timeout 
1
2
3
4
5
6
7
8

总结:

  • 502网关错误:主要是PHP执行超时,但是没有超过Web设置的响应时长,这个时候PHP-FPM的woker进程挂起重启,所以出现网关错误,即下游服务器中断了,这种情况一般都是调整php执行时间。
  • 504网关超时:主要是PHP执行时间超过Web设置的响应时长,这种情况一般都是修改Web服务器响应时间,
#PHP
上次更新: 2022/12/02, 22:04:34
PHP7新特性总结

PHP7新特性总结→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式