php-fpm占用内存为何持续增高

事件经过#

  • 最近服务器在凌晨 0 点 - 6 点之间,总会发生内存占用特别高,导致出现 oom 的情况
  • 起初猜测是凌晨有部分跑批脚本,导致内存占用升高,但是在我观察的过程中,发现每天凌晨内存占用更高的不是 php 脚本,而是 php-fpm。
  • 写了一个脚本,简单来统计 php-fpm 的总的内存占用,发现在 0-6 点之间,确实 php-fpm 想比较于其他的时间段,内存占用有显著的增加。

问题猜想#

  • 凌晨期间,请求量较少,导致每一个 php-fpm 的子进程需要很长的时间才能达到 max_requests 的数量,造成 php-fpm 子进程长期存活无法重启,以至于期间由于可能的内存泄漏,php-fpm 占用内存逐步升高。6 点过后,请求量增多,php-fpm 进程纷纷重启,内存得到释放。
  • 查了官方的 gc 机制,gc 会发生在缓存区满了情况下,如果一个请求结束后,当前请求的内存使用也应该得到释放才对,为什么凌晨相较于白天而言,内存占用会高出这么多呢?这是一直无法解释的点。有谁碰到过这样的情况么,知道具体的原因么?下图是 php-fpm 的内存占用情况
    php-fpm的内存占用情况
讨论数量: 6
CrazyZard

你可以 strace 去看下对应的进程

4年前 评论

@CrazyZard 好的,我去观察下

4年前 评论
  • 你机器的内存是多少?
  • 你开启的进程总数是多少?
  1. 正常一个 fpm 稳定工作的时候 内存很稳定的,如果平稳运行时的内存消耗就很多,需要看下是不是加载了一些大型模块。
  2. 可以把 max_request 调小一些,让 fpm 进程尽量重启的频繁一些。
4年前 评论

按照我的理解,你应该跑的是定时脚本吧。。。假设是,为何是在 php-fpm 下运行?而不是 cli?

4年前 评论

1. 对比多个 php-fpm 子进程,找出内存占用比较高的进程

2. 使用 strace 跟踪下进程,自行分析

3. 调整 max_requests 的值,(max_requests = 多少秒重启一次 * 并发量 /max_children)

4年前 评论

持续增高可能原因是 php-cgi 内存并没有释放。可以查看开启的 php-fpm 每一个子进程的内存占用量。

ps -ylC php-fpm --sort:rss

将正常情况下的内存消耗量和非正常情况下的内存消耗量做对比。将内存较高的 php-fpm 子进程 kill 掉。定时重启 php-fpm

4年前 评论