我最近将一个客户端迁移到运行 Nginx + PHP-FPM 的 EC2 实例。当我第一次设置服务器时,我设置了pm=static
40 个工作进程。大约一周后,我决定尝试将pm=dynamic
工作进程数量设置为最多 200 个,最少 30 个。
我注意到,在静态设置下,40 个进程占用了大约 2.3GB 内存,而在动态设置下,我看到 60 个进程的峰值仅使用了 1.2GB 内存。
请参阅下面来自 New Relic 的图表,我的注释用红色表示。
你可以看到我在 11/25 白天把静态改成动态,然后重启了 php-fpm,之后我们可以看到 48 个进程只占用了 990MB 内存,60 个进程只占用了 1.2GB 内存。
什么可能导致静态和动态管理之间的这种差异?可能是因为对于动态,我将最大请求数设置为 50?也许静态内存使用更多的是由于内存泄漏而不是 php-fpm 内部的原因?
答案1
pm.max_requests
不特定于任何进程管理器 ( pm
) 模式。其优点是,在处理指定数量的请求后,重新生成工作进程。
在极端情况下,它可以避免内存泄漏,但通常它只是释放执行内存消耗大脚本时积累的内存分配。内存分配会堆积起来,分配的内存总量会增长,但只有在退出时(即重生时)才会释放。
pm.max_requests
正如您所说,您在使用时似乎没有激活pm static
。您应该已经看到了差异,而且肯定不止一条直线。
pm dynamic
还有一个额外的好处,就是可以根据其中的空闲进程数量(pm.min_spare_servers
、pm.max_spare_servers
)来停止工作进程,这是一种衡量即时负载的指标。停止无用的进程会释放相关的已分配内存,但会以进程处理(CPU)为代价,这pm.min_spare_servers
抵消了在出现峰值时确保安全缓冲的作用,使空闲的工作进程随时准备处理请求。
现在,如果您真的在关注内存,pm ondemand
则更积极,在不再需要时(取消)生成进程。此模式最接近边缘,因为它不会像 那样吸收峰值pm dynamic
,但它对内存消耗最少(与之相对的是使用更多 CPU 进行进程管理)。
总结
任何工作进程的内存分配都会堆积起来。如果某个请求占用大量内存,它将占据处理工作进程内存分配的顶部,并且直到进程停止时才会释放。
用于pm.max_requests
回收进程,无论您使用什么模式。
pm.dynamic
将根据另一个标准(即负载)回收进程,当有太多进程处于空闲状态时,将终止进程。进程周转率越高,越有可能防止它们占用过多的内存,但代价是需要更多 CPU 周期用于进程管理。