Unicorn and Ruby memory leak causes server downtime |
1. Reboot your Ruby Periodically
If you are using the popular Unicorn web server, memory issues may be even more severe, as Unicorn forks. During forking, it's copying the whole memory footprint of the parent (Copy on Write or CoW). Therefore, you may use the "Unicorn Worker Killer" gem that will monitor your server and gracefully will restart specific worker when memory reaches a new high or specific number of requrests were served. Since the gem supports randomization, it assures in a very high probablilty that the server will continue server.
Installing the killer:
gem 'unicorn-worker-killer'
Add to config.ru above "require ::File.expand_path('../config/environment', __FILE__)"
# Unicorn self-process killer
require 'unicorn/worker_killer'
And decide your worker graceful reboot method:
# Max requests per worker
use Unicorn::WorkerKiller::MaxRequests, 3072, 4096
# Max memory size (RSS) per worker
use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2))
If you are using Ruby 2.X, you can exploit the CoW by better configuring Unicorn.
config/unicorn.rb (and a detailed explenation on setting at sirupsen)
- worker_processes: 1x your cores
- timeout: worker request timeout, should be 15 to 30 sec max
- preload_app: enables CoW, but requires managning connect/disconnect on fork
3. Take care of GC configuration
You can take a look at a detailed discussion at collective idea's post.
Bottom Line
Dynamic languages has their downs, yet w/ the right design you can keep them up and running,
Keep Performing,