Unicorn Wykorzystanie pamięci napełniania prawie cały RAM
Zasadniczo istnieją trzy problemy:
1) Unicorn wydaje się być stale zapełniać cały RAM, powodując mnie, aby usunąć ręcznie pracowników.
2) Jednorożec wydaje się być źródłem dodatkowych pracowników z jakiegoś powodu, chociaż określiłem określoną liczbę pracowników (7 z nich). To częściowo powoduje gromadzenie się pamięci RAM, co również powoduje ręczne usuwanie pracowników.
3) Wdrożenie z zerowym czasem przestoju jest nierealne w moim przypadku. Czasami odbiera zmiany, czasami dostaję limity czasu bramki. Każde wdrożenie staje się bardzo stresującą sytuacją.
Nie lubię używać Monita, ponieważ zabija pracowników bez czekania, aż pracownicy skończą wypełniać ich prośby.
Czy to normalne? Czy inne osoby, które używają Unicorn, mają ten sam problem, gdy pamięć RAM po prostu rośnie niekontrolowanie?
A także skąd pracownicy, ilu pracowników zrodziło się, nie zgadzają się z określoną liczbą pracowników?
Inną alternatywą jest zabójca robotnik jednorożca, który wypróbowałbym po przeczytaniu Unicorn Eating Memory.
Tiny Aktualizacja:
Więc przyszło do punktu, w którym New Relic mówił mi pamięć była prawie 95%. Więc musiałem zabić pracownika. Interesujące jest to, że zabicie tego pracownika znacznie zmniejszyło pamięć, co widać z poniższego wykresu.
Co z tym?
Dla porównania, oto moje unicorn.rb
i unicorn_init.sh
. Chciałbym, żeby ktoś mi powiedział, że gdzieś tam jest jakiś błąd.
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
jaki sposób można wygenerować ten wykres? – ant