gpt4 book ai didi

ruby-on-rails - Unicorn 内存使用几乎填满了所有 RAM

转载 作者:数据小太阳 更新时间:2023-10-29 06:38:05 25 4
gpt4 key购买 nike

New Relic Process snapshot

这里基本上有3个问题:

1) Unicorn 似乎在稳定地填满所有 RAM,导致我手动移除 worker 。

2) Unicorn 似乎出于某种原因正在产生更多的 worker ,尽管我指定了固定数量的 worker (其中 7 个)。这在一定程度上导致了 RAM 堆积,这也导致我手动删除工作人员。

3) 零停机部署在我的案例中是不可靠的。有时它会接受更改,有时我会收到网关超时。每次部署都会成为压力很大的情况。

我不太喜欢使用 Monit,因为它会在不等待工作人员完成请求处理的情况下杀死工作人员。

那么,这正常吗?其他使用 Unicorn 部署的人是否有同样的问题,即 RAM 不受控制地增长?

还有,生成的 worker 数量与定义的 worker 数量不匹配的地方?

另一种选择是 unicorn worker killer ,我会在阅读后尝试一下 Unicorn Eating Memory .

小更新:

enter image description here

所以到了 New Relic 告诉我内存几乎 95% 的地步。所以我不得不杀了一个 worker 。有趣的是,杀掉那个 worker 会使内存减少很多,如下图所示。

这是怎么回事?

作为引用,这是我的 unicorn.rbunicorn_init.sh。很想有人告诉我哪里有错误。

unicorn.rb

root = "/home/deployer/apps/myapp/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.stderr.log"
stdout_path "#{root}/log/unicorn.log"

listen "/tmp/unicorn.myapp.sock"
worker_processes 7
timeout 30

preload_app true

before_exec do |_|
ENV["BUNDLE_GEMFILE"] = '/home/deployer/apps/myapp/current/Gemfile'
end

before_fork do |server, worker|
# Disconnect since the database connection will not carry over
if defined? ActiveRecord::Base
ActiveRecord::Base.connection.disconnect!
end

old_pid = "#{root}/tmp/pids/unicorn.pid.oldbin`"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
sleep 1
end

after_fork do |server, worker|
# Start up the database connection again in the worker
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end

Redis.current.quit
Rails.cache.reconnect
end

unicorn_init.sh

#!/bin/sh
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/deployer/apps/myapp/current
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; BUNDLE_GEMFILE=/home/deployer/apps/myapp/current/Gemfile bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=deployer
set -u
OLD_PIN="$PID.oldbin"

sig () {
test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}

run () {
if [ "$(id -un)" = "$AS_USER" ]; then
eval $1
else
su -c "$1" - $AS_USER
fi
}

case "$1" in
start)
sig 0 && echo >&2 "Already running" && exit 0
run "$CMD"
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig USR2 && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
run "$CMD"
;;
upgrade)
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
then
n=$TIMEOUT
while test -s $OLD_PIN && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo

if test $n -lt 0 && test -s $OLD_PIN
then
echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
run "$CMD"
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
exit 1
;;
esac

最佳答案

你似乎有两个问题:1)你在优雅重启的协调上有错误导致老 unicorn worker 和老主人坚持; 2) 您的应用程序(不是 unicorn )正在泄漏内存。

对于前者,查看您的 before_fork 代码,您似乎正在使用来自 the example config 的内存限制方法。但是,您在 .oldbin 文件名中有一个拼写错误(末尾有一个无关的反引号),这意味着您永远不会向旧进程发出信号,因为您无法从不存在的进程中读取 pid文件。

对于后者,您将不得不进行调查和演练。在您的应用程序中查找随时间累积数据的缓存语义;仔细检查全局变量、类变量和类实例变量的所有使用,它们可以保留请求之间的数据引用。运行一些内存配置文件来描述您的内存使用情况。您可以通过在工作人员增长超过某个上限时将其杀死来减轻内存泄漏; unicorn-worker-killer让这一切变得简单。

关于ruby-on-rails - Unicorn 内存使用几乎填满了所有 RAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18158496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com