Switch web server from Thin to Unicorn #172

Closed
wants to merge 3 commits into
from

Projects

None yet

5 participants

@croaky
Member
croaky commented Apr 5, 2013

As the Rails application scales to more Heroku dynos, a lack of concurrency
can result in poor performance and an over-provisioning of resources.
Modifying the app to handle requests more efficiently is a simple process
with immediate benefits.

Unicorn is a concurrent web server that spawns several processes within
a single dyno without requiring concurrency or threading awareness in your
app. Applications that migrate to Unicorn often require fewer dynos and see
increased performance.

The config/unicorn.rb file specifies the number of concurrent web
processes to run on each dyno as well as the proper forking and termination
behavior.

[1] https://blog.heroku.com/archives/2013/2/16/routing_performance_update
[2] https://blog.heroku.com/archives/2013/2/27/unicorn_rails
[3]
https://devcenter.heroku.com/articles/rails-unicorn#adding-unicorn-to-your-application

@croaky croaky Switch web server from Thin to Unicorn
As the Rails application scales to more Heroku dynos, a lack of
concurrency can result in [poor performance](1) and an over-provisioning
of resources. Modifying the app to handle requests more efficiently is
a simple process with immediate benefits.

Unicorn is a [concurrent web server](2) that spawns several processes
within a single dyno without requiring concurrency or threading
awareness in your app.  Applications that migrate to Unicorn often
require fewer dynos and see increased performance.

The [config/unicorn.rb file](3) specifies the number of concurrent web
processes to run on each dyno as well as the proper forking and
termination behavior.

[1] https://blog.heroku.com/archives/2013/2/16/routing_performance_update
[2] https://blog.heroku.com/archives/2013/2/27/unicorn_rails
[3] https://devcenter.heroku.com/articles/rails-unicorn#adding-unicorn-to-your-application
d4dfb84
@harlow harlow commented on the diff Apr 5, 2013
templates/unicorn.rb
@@ -0,0 +1,24 @@
+worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
+timeout (ENV['WEB_TIMEOUT'] || 15).to_i
+preload_app true
+
+before_fork do |server, worker|
+ Signal.trap 'TERM' do
+ puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
@harlow
harlow Apr 5, 2013 Contributor

Is there a reason for puts over Rails.logger.info? I'm not sure if it makes any difference in the console output.

@mike-burns
mike-burns Apr 5, 2013 Member

Do we have access to Rails in here?

@croaky
croaky Apr 5, 2013 Member

Not sure of the benefits of either. Heroku uses puts pretty regularly in
their docs.

Anything written to standard out (stdout) or standard error (stderr) is
captured into your logs. This means that you can log from anywhere in your
application code with a simple output statement.

On Thursday, April 4, 2013, Harlow Ward wrote:

In templates/unicorn.rb:

@@ -0,0 +1,24 @@
+worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
+timeout (ENV['WEB_TIMEOUT'] || 15).to_i
+preload_app true
+
+before_fork do |server, worker|

  • Signal.trap 'TERM' do
  • puts 'Unicorn master intercepting TERM and sending myself QUIT instead'

Is there a reason for puts over Rails.logger.info? I'm not sure if it
makes any difference in the console output.


Reply to this email directly or view it on GitHubhttps://github.com/thoughtbot/suspenders/pull/172/files#r3668638
.

Dan Croak
@croaky http://github.com/croaky
thoughtbot's internal research http://tinyletter.com/thoughtbot/letters

@harlow
Contributor
harlow commented Apr 5, 2013

This looks good Dan. 👍

@jferris jferris and 2 others commented on an outdated diff Apr 5, 2013
templates/unicorn.rb
@@ -0,0 +1,24 @@
+worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
+timeout (ENV['WEB_TIMEOUT'] || 15).to_i
+preload_app true
+
+before_fork do |server, worker|
+ Signal.trap 'TERM' do
@jferris
jferris Apr 5, 2013 Member

There's a decent amount of code in here, and I'm a little nervous about generating it into all our applications. We'd also need to copy/paste to get this in existing applications.

What do you think about making a small, new gem (I like the name "fork_you"), which just handles the concern of "what do I need to do when dealing with a forking server?"

It could also be useful for abstracting the forking concept. Currently, you'd need different hooks for forking web servers (Unicorn/Passenger) and forking job processors (Delayed Job/Resque).

If we like this idea, it may make sense as a follow-up to this commit, rather than blocking the merge.

@mjankowski
mjankowski Apr 5, 2013 Member

Maybe add a comment line pointing to an official heroku source for this? Blog post, template file, whatever.

https://github.com/heroku/ruby-rails-unicorn-sample/blob/master/config/unicorn.rb

So that this comes off as "oh, this is actually heroku's official recommendation for unicorn setup" and not "this is some random ruby/forking/whatever that we hacked together"...

@croaky
croaky Apr 6, 2013 Member

@mjankowski Good call. Done in 99eaf5d.

@croaky croaky closed this Apr 6, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment