Note that there are some explanatory texts on larger screens.

plurals
  1. POUnicorn Memory Usage filling up almost all the RAM
    primarykey
    data
    text
    <p><img src="https://i.stack.imgur.com/6wiYT.png" alt="New Relic Process snapshot"></p> <p>There are essentially 3 problems here:</p> <p>1) Unicorn seems to be steadily filling up all the RAM, causing me to remove workers manually.</p> <p>2) Unicorn seems to be spawning additional workers for some reason, although I have specified a fixed number of workers (7 of them). This is partly causing the RAM buildup, which also is causing me to remove workers manually.</p> <p>3) Zero downtime deployment is unreliable in my case. Sometimes it picks up the changes, sometimes I get gateway timeouts. Each deploy becomes a very stressful situation.</p> <p>I don't really like using Monit, because it kills workers without waiting for workers to finish serving their requests.</p> <p>So, is this normal? Do other people who deploy using Unicorn have the same problem where the RAM just grows uncontrollably? </p> <p>And also where workers the number of workers spawned do not match the number of workers defined?</p> <p>The other alternative is unicorn worker killer, which I would be trying out after reading <a href="https://stackoverflow.com/questions/8306883/unicorn-eating-memory">Unicorn Eating Memory</a>.</p> <p><strong>Tiny Update:</strong></p> <p><img src="https://i.stack.imgur.com/xenNQ.png" alt="enter image description here"></p> <p>So it came to a point where New Relic was telling me the memory was almost 95%. So I had to kill a worker. Interestingly, killing that worker brought the memory down by quite a lot, as seen from the graph below.</p> <p>What's up with that?</p> <p>For reference, here's my <code>unicorn.rb</code> and <code>unicorn_init.sh</code>. Would love for somebody to tell me that there's a mistake in there somewhere.</p> <p><strong><code>unicorn.rb</code></strong></p> <pre><code>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) &gt;= 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 </code></pre> <p><strong><code>unicorn_init.sh</code></strong></p> <pre><code>#!/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" &amp;&amp; kill -$1 `cat $PID` } oldsig () { test -s $OLD_PIN &amp;&amp; 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 &amp;&amp; echo &gt;&amp;2 "Already running" &amp;&amp; exit 0 run "$CMD" ;; stop) sig QUIT &amp;&amp; exit 0 echo &gt;&amp;2 "Not running" ;; force-stop) sig TERM &amp;&amp; exit 0 echo &gt;&amp;2 "Not running" ;; restart|reload) sig USR2 &amp;&amp; echo reloaded OK &amp;&amp; exit 0 echo &gt;&amp;2 "Couldn't reload, starting '$CMD' instead" run "$CMD" ;; upgrade) if sig USR2 &amp;&amp; sleep 2 &amp;&amp; sig 0 &amp;&amp; oldsig QUIT then n=$TIMEOUT while test -s $OLD_PIN &amp;&amp; test $n -ge 0 do printf '.' &amp;&amp; sleep 1 &amp;&amp; n=$(( $n - 1 )) done echo if test $n -lt 0 &amp;&amp; test -s $OLD_PIN then echo &gt;&amp;2 "$OLD_PIN still exists after $TIMEOUT seconds" exit 1 fi exit 0 fi echo &gt;&amp;2 "Couldn't upgrade, starting '$CMD' instead" run "$CMD" ;; reopen-logs) sig USR1 ;; *) echo &gt;&amp;2 "Usage: $0 &lt;start|stop|restart|upgrade|force-stop|reopen-logs&gt;" exit 1 ;; esac </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload