PHP `PHP-FPM` `pm.max_children` / `pm.start_servers` 等参数调优策略

各位老铁,大家好!今天咱们来聊聊PHP-FPM的“孩子”们,也就是pm.max_childrenpm.start_servers等等这些参数,看看怎么把它们管教好,让咱们的网站跑得飞起。

开场白:为啥要关心这些“孩子”?

想象一下,你的网站是个餐厅,PHP-FPM就是负责做饭的厨师团队。如果厨师太少,客人来了只能饿着肚子等,网站就会慢;如果厨师太多,闲着没事干,浪费资源不说,还容易互相吵架,增加管理成本。所以,合理分配厨师数量,让餐厅既能满足顾客需求,又不浪费资源,这就是咱们今天调优的目标。

第一节课:PHP-FPM的几种模式

PHP-FPM主要有三种进程管理模式,咱们先认识一下它们:

  • static (静态模式): 一开始就创建固定数量的子进程,用完就扔,不管忙不忙。就像雇佣了一批固定数量的厨师,不管有没有客人,工资照付。
  • dynamic (动态模式): 根据实际请求量动态调整子进程数量。忙的时候多雇几个厨师,闲的时候就让一些厨师休息。
  • ondemand (按需模式): 只有在有请求时才创建子进程,请求处理完就销毁。就像来了客人再临时找厨师,处理完就解雇。

这三种模式各有优缺点,咱们一个一个来看。

第二节课:static模式:简单粗暴,适合土豪

static模式的配置非常简单,只需要设置pm.max_children参数,指定子进程的数量即可。

pm = static
pm.max_children = 50

优点:

  • 简单易懂,配置方便。
  • 性能稳定,因为子进程一直存在,省去了创建和销毁的开销。

缺点:

  • 浪费资源。即使没有请求,子进程也会占用内存。
  • 扩展性差。如果请求量超过pm.max_children,新的请求只能排队等待。

适用场景:

  • 服务器资源充足,不在乎浪费。
  • 请求量比较稳定,变化不大。

第三节课:dynamic模式:灵活应变,精打细算

dynamic模式可以根据实际请求量动态调整子进程数量,可以有效利用资源。

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

这些参数的含义如下:

  • pm.max_children: 子进程的最大数量。
  • pm.start_servers: 启动时创建的子进程数量。
  • pm.min_spare_servers: 空闲子进程的最小数量。如果空闲子进程的数量小于这个值,FPM会创建新的子进程。
  • pm.max_spare_servers: 空闲子进程的最大数量。如果空闲子进程的数量大于这个值,FPM会杀死多余的子进程。

工作原理:

  1. FPM启动时,创建pm.start_servers个子进程。
  2. 当有新的请求到达时,FPM会从空闲子进程中选择一个来处理。
  3. 如果空闲子进程的数量小于pm.min_spare_servers,FPM会创建新的子进程,直到达到pm.max_children
  4. 如果空闲子进程的数量大于pm.max_spare_servers,FPM会杀死多余的子进程,直到达到pm.min_spare_servers

优点:

  • 资源利用率高。根据实际请求量动态调整子进程数量,避免资源浪费。
  • 扩展性好。可以根据请求量自动扩展子进程数量,应对突发流量。

缺点:

  • 配置复杂。需要根据实际情况调整多个参数。
  • 性能有一定损耗。创建和销毁子进程需要一定的开销。

适用场景:

  • 服务器资源有限,需要精打细算。
  • 请求量波动较大。

第四节课:ondemand模式:极致省电,冷启动慢

ondemand模式只有在有请求时才创建子进程,请求处理完就销毁。

pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s
pm.max_requests = 500

这些参数的含义如下:

  • pm.max_children: 子进程的最大数量。
  • pm.process_idle_timeout: 子进程空闲多久后销毁。
  • pm.max_requests: 每个子进程处理多少个请求后重启。

工作原理:

  1. FPM启动时,不创建任何子进程。
  2. 当有新的请求到达时,FPM创建一个新的子进程来处理。
  3. 请求处理完后,子进程会空闲一段时间,如果超过pm.process_idle_timeout,FPM会销毁该子进程。

优点:

  • 资源利用率极高。只有在有请求时才占用资源。
  • 安全性高。每次请求都使用新的子进程,可以防止内存泄漏和代码污染。

缺点:

  • 冷启动慢。每次请求都需要创建新的子进程,会增加请求的延迟。
  • 不适合高并发场景。频繁创建和销毁子进程会带来额外的开销。

适用场景:

  • 服务器资源非常有限,需要极致省电。
  • 请求量非常小,而且不频繁。
  • 对请求延迟不敏感。

第五节课:参数调优的黄金法则

选择哪种模式取决于你的实际情况。一般来说,dynamic模式是比较通用的选择,既能保证性能,又能有效利用资源。

接下来,咱们来聊聊如何调整dynamic模式下的参数。

1. pm.max_children:决定你的“厨师团队”规模

pm.max_children是FPM能创建的最大子进程数量。这个参数决定了你的网站能同时处理多少个请求。

如何确定合适的值?

一个常用的方法是:

  • 计算每个PHP进程的内存占用量: 可以使用topps等命令查看。
  • 计算服务器的总内存: 减去操作系统和其他服务的占用量。
  • 用剩余内存除以每个PHP进程的内存占用量: 得到的值就是pm.max_children的合理范围。

公式:

pm.max_children = (服务器总内存 - 其他服务占用内存) / 每个PHP进程占用内存

举个栗子:

假设你的服务器有4GB内存,操作系统和其他服务占用1GB,剩余3GB内存。每个PHP进程占用50MB内存。

pm.max_children = (3GB * 1024MB/GB) / 50MB = 61.44

所以,pm.max_children可以设置为60左右。

注意事项:

  • pm.max_children的值不宜设置过大,否则会导致服务器内存耗尽,引发OOM(Out Of Memory)错误。
  • pm.max_children的值也不宜设置过小,否则会导致请求排队等待,影响网站性能。

2. pm.start_servers:你的“预备厨师”数量

pm.start_servers是FPM启动时创建的子进程数量。这个参数决定了你的网站在启动时就能处理多少个请求。

如何确定合适的值?

  • 可以根据网站的平均访问量来确定。如果网站的平均访问量比较高,可以适当增加pm.start_servers的值。
  • 一般来说,pm.start_servers的值可以设置为pm.min_spare_serverspm.max_spare_servers之间的某个值。

3. pm.min_spare_serverspm.max_spare_servers:你的“空闲厨师”数量范围

pm.min_spare_serverspm.max_spare_servers分别代表空闲子进程的最小和最大数量。这两个参数决定了FPM在空闲时会保留多少个子进程。

如何确定合适的值?

  • pm.min_spare_servers的值应该大于等于网站的最低访问量。
  • pm.max_spare_servers的值应该小于等于网站的最高访问量。
  • 这两个参数的值应该根据实际情况进行调整,以达到最佳的性能和资源利用率。

建议:

  • pm.min_spare_servers的值可以设置为pm.max_children的10%-20%。
  • pm.max_spare_servers的值可以设置为pm.max_children的30%-50%。

举个栗子:

如果pm.max_children设置为60,那么:

  • pm.min_spare_servers可以设置为6-12。
  • pm.max_spare_servers可以设置为18-30。

4. pm.max_requests:让“厨师”轮休,保持状态

pm.max_requests参数指定了每个子进程在重启之前处理的请求数量。这个参数可以防止内存泄漏和代码污染。

如何确定合适的值?

  • pm.max_requests的值可以设置为一个比较大的值,例如500、1000甚至更高。
  • 如果你的网站经常出现内存泄漏或代码污染的问题,可以适当降低pm.max_requests的值。

第六节课:监控和调优:持续改进,精益求精

参数调优不是一蹴而就的,需要不断地监控和调整。可以使用以下工具来监控FPM的性能:

  • php-fpm status page 可以查看FPM的运行状态、子进程数量、请求队列等信息。
  • tophtop 可以查看服务器的CPU、内存、IO等资源使用情况。
  • 慢日志 可以记录执行时间超过阈值的PHP脚本,帮助你找到性能瓶颈。

调优步骤:

  1. 监控FPM的性能: 观察子进程数量、请求队列、CPU和内存使用情况。
  2. 分析性能瓶颈: 找到导致性能下降的原因。
  3. 调整参数: 根据分析结果调整pm.max_childrenpm.start_serverspm.min_spare_serverspm.max_spare_servers等参数。
  4. 重复以上步骤: 直到达到最佳的性能和资源利用率。

第七节课:一些奇技淫巧

  • 使用opcache: 启用opcache可以缓存PHP脚本,避免重复编译,显著提高性能。
  • 优化数据库查询: 数据库查询是PHP应用中最常见的性能瓶颈之一。使用索引、缓存等技术可以优化数据库查询。
  • 使用CDN: CDN可以缓存静态资源,减轻服务器的压力,提高网站的访问速度。
  • 代码优化: 编写高效的PHP代码可以减少CPU和内存的占用,提高性能。

第八节课:实战案例

假设你的网站是一个电商网站,每天的访问量比较大,而且波动比较明显。

配置方案:

  • pm = dynamic
  • pm.max_children = 100
  • pm.start_servers = 20
  • pm.min_spare_servers = 10
  • pm.max_spare_servers = 50
  • pm.max_requests = 500

调优策略:

  1. 监控FPM的性能: 观察子进程数量、请求队列、CPU和内存使用情况。
  2. 如果CPU使用率过高: 可以适当增加pm.max_children的值。
  3. 如果内存使用率过高: 可以适当降低pm.max_children的值。
  4. 如果请求队列过长: 可以适当增加pm.max_childrenpm.start_servers的值。
  5. 如果空闲子进程数量过多: 可以适当降低pm.min_spare_serverspm.max_spare_servers的值。
  6. 如果出现内存泄漏或代码污染的问题: 可以适当降低pm.max_requests的值。

总结:

PHP-FPM的参数调优是一个复杂而重要的任务。通过了解不同的模式和参数,并结合实际情况进行监控和调整,你可以让你的网站跑得更快、更稳定。记住,没有万能的配置,只有不断地学习和实践,才能找到最适合你的方案。

好了,今天的讲座就到这里,希望对大家有所帮助!各位老铁,下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注