Wykorzystanie pamięci Unicorn wypełnia prawie całą pamięć RAM

Są tu zasadniczo 3 problemy:

1) Unicorn wydaje się stale zapełniać całą pamięć RAM, powodując, że ręcznie usuwam pracowników.

2) Jednorożec zdaje się z jakiegoś powodu pojawiać dodatkowych pracowników, chociaż określiłem określoną liczbę pracowników (7 z nich). Powoduje to częściowo narastanie pamięci RAM, co również powoduje, że ręcznie usuwam pracowników.

3) W moim przypadku wdrożenie „zero przestojów” jest zawodne. Czasami przejmuje zmiany, czasem dostaję limity czasu bramy. Każde wdrożenie staje się bardzo stresującą sytuacją.

Naprawdę nie lubię używać Monit, ponieważ zabija pracowników, nie czekając, aż pracownicy skończą obsłużyć swoje żądania.

Czy to normalne? Czy inni ludzie, którzy wdrażają Unicorn, mają ten sam problem, gdy RAM rośnie w niekontrolowany sposób?

A także tam, gdzie liczba pracowników, którzy się rozrodzili, nie odpowiada liczbie zdefiniowanych pracowników?

Inną alternatywą jest zabójca robotników jednorożca, który próbowałem po przeczytaniuPamięć jedzenia jednorożca.

Tiny Update:

Doszło więc do punktu, w którym New Relic mówił mi, że pamięć wynosiła prawie 95%. Musiałem więc zabić pracownika. Co ciekawe, zabicie tego pracownika znacznie zmniejszyło pamięć, jak widać na poniższym wykresie.

Co z tym?

Dla odniesienia, oto mojaunicorn.rb iunicorn_init.sh. Chciałbym, żeby ktoś mi powiedział, że gdzieś jest 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

questionAnswers(2)

yourAnswerToTheQuestion