我的一个使用 nginx + Passenger 和设置提供服务的应用程序出现内存泄漏min/max_instances 2
。随着时间的推移,内存不断增加,这对于内存有限的机器(例如 Amazon Web Services)来说可能是一个问题,最终可能会导致严重崩溃。
是否有办法/技巧可以定期或当内存达到某个阈值时重新启动同一应用程序的某些乘客进程?
假设我有一个应用程序组 A,最多可以启动 2 个进程 A1 和 A2。我想一次重启 A1 和 A2 以确保服务连续性(这是不是零停机部署,因为它依赖于相同的未修改的应用程序,但需要某种方式来清除内存泄漏并重新启动一个新的过程,直到我找出问题所在)。
例如假设我有以下状态:
队列中的请求:0
* PID: 11124 Sessions: 0 Processed: 14638 Uptime: 1d 12h 31m 29s
CPU: 0% Memory : 341M Last used: 24s
* PID: 11131 Sessions: 0 Processed: 9323 Uptime: 1d 12h 31m 29s
CPU: 0% Memory : 389M Last used: 24s
进程 n°2 开始占用大量内存(~400),所以我想重新启动它(并且只重新启动这个进程),这样应该会将其恢复到 100MB 左右,稍后我会对进程 n°1 执行同样操作
内存泄漏需要一些时间来构建,最好只在检测到内存使用率过高时重新启动,但如果我可以安排每晚左右重新启动进程,这也可以完全正常工作(例如,在凌晨 3 点重新启动进程 n°1,然后在凌晨 4 点重新启动进程 n°2)
我可以向该乘客团体发送什么信号,以便我逐一重新启动流程吗?
答案1
如果这是您的生产应用程序,我建议您使用 Passenger Enterprise。您可以将一项不错的功能添加到 nginx 配置中:
乘客内存限制1024;
当内存达到 1024 或您想要指定的任何数字时,Passenger 将重新加载该进程。您还可以利用多线程,因为 Passenger Standalone 是单线程的。
答案2
对于 OP 来说这可能有点晚了,但我们每分钟都会在 AWS 主机上运行以下 cron 脚本:
#!/bin/bash
let "TARGET = 400 * 1024" # = 400 MB
ps aux --sort -rss | grep "Passenger RackApp" | while read -r LINE; do
read PID MEMORY <<< $(echo $LINE | awk '{ print $2; print $6 }')
if [ $MEMORY -gt $TARGET ]
then
`kill -15 $PID`
fi
done
exit 0
根据配置,乘客将立即重新启动已停止的进程。