Unicorn Speichernutzung füllt fast die ganze RAM
Es gibt im Wesentlichen drei Probleme hier:
1) Unicorn scheint ständig alle RAM füllte werden, was mir Arbeiter manuell zu entfernen.
2) Unicorn scheint aus irgendeinem Grund zusätzliche Arbeiter hervorzubringen, obwohl ich eine feste Anzahl von Arbeitern angegeben habe (7 von ihnen). Dies verursacht teilweise den RAM-Aufbau, wodurch ich Arbeiter auch manuell entferne.
3) Keine Ausfallzeiten Einsatz ist in meinem Fall unzuverlässig. Manchmal nimmt es die Änderungen auf, manchmal bekomme ich Gateway Timeouts. Jeder Einsatz wird zu einer sehr stressigen Situation.
Ich mag es nicht wirklich, Monit zu verwenden, weil es Arbeiter tötet, ohne darauf zu warten, dass Arbeiter ihre Anfragen erfüllen.
Also, ist das normal? Haben andere Leute, die Unicorn einsetzen, das gleiche Problem, wenn der RAM einfach unkontrolliert wächst?
Und auch wo Arbeiter die Anzahl der Arbeiter spawned nicht die Anzahl der Arbeiter definiert?
Die andere Alternative ist Einhorn Worker Killer, die ich nach dem Lesen Unicorn Eating Memory ausprobieren würde.
Tiny Update:
So kam es zu einem Punkt, wo New Relic wurde mir die Erinnerung zu sagen war fast 95%. Also musste ich einen Arbeiter töten. Interessanterweise brachte das Töten dieses Arbeiters die Erinnerung um einiges herunter, wie aus der Grafik unten ersichtlich ist.
Was ist los?
Als Referenz, hier ist meine unicorn.rb
und unicorn_init.sh
. Würde mich freuen, wenn mir jemand sagt, dass da irgendwo ein Fehler ist.
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
wie haben Sie diese Grafik zu erzeugen? – ant