Featured image of post 记一次排查 PHP 队列服务占用大内存过程

记一次排查 PHP 队列服务占用大内存过程

使用 atop 排查内存进程问题

  • 起因是运维反馈说有一个容器组的pod会出现OOM重启, 然后我看了一下监控, 如下图

  • 从图中可以看到内存隔段时间就会有一个尖刺, 看了一下这个服务的代码, 是一个队列视频合成服务

  • 代码里通过shell_exec调用各种命令, 比如ffmpeg, spleeter去将视频声音, 质量等做处理

  • 因为是外部调用, 通过PHP代码无法监控到内存占用, 这边我选择使用atop去记录日志

启动服务

## 安装
apt update && apt install -y atop

## 修改配置文件
cat /etc/default/atop
LOGOPTS=""
LOGINTERVAL=1        # 这边为了监控到每一次变化, 修改为 1s 记录一次
LOGGENERATIONS=28      #日志保留时间为28,一般我们设置为7天
LOGPATH=/var/log/atop  #日志路径


## 启动服务
systemctl start atop

排查问题

  • 通过阿里云查看查看资源暂用, 发现16:20:30有一个尖刺

  • 通过atop命令查看历史记录
## -m 按照内存排序, -r 可以跟 xxx 日志文件(/var/log/atop/xxx), 不填默认是当天
atop -m -r
## 进入界面后, 按 b 然后会要求输入日期, 输入 1620 (跳转到这个时间)
b
1620
## 接下来一直按着小写 t 翻页, (大写 T 返回上一页)

  • 最后找到的进程是

  • 看了一下是调用spleeter命令的时候消耗巨大内存
  • 看了一下文档说可以切分音频再去分离, 完成后再合并可以减少内存使用

https://github.com/deezer/spleeter/wiki/5.-FAQ#why-do-i-have-no-output-produced

解决方案

## 先使用 ffmpeg 按 10 秒(根据内存调试秒数)
$inputAudio = 'http://xxx.wav'
ffmpeg -i '{$inputAudio}' -f segment -segment_time 60 -c copy {$downloadDir}/%03d.{$extension}
## 然后遍历使用 spleeter 分离声音
foreach ($files as $file) {
  spleeter separate -o {$outpuDir} -p spleeter:2stems {$file}
}
## 最后再使用 ffmpeg 去合并起来
ffmpeg -f concat -safe 0 -i {$listFile} -c copy {$outputAudioFile}