Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch web server from Thin to Unicorn #172

Closed
wants to merge 3 commits into from
Closed

Conversation

croaky
Copy link
Contributor

@croaky 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

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

before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have access to Rails in here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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//pull/172/files#r3668638
.

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

@harlow
Copy link
Contributor

harlow commented Apr 5, 2013

This looks good Dan. 👍

preload_app true

before_fork do |server, worker|
Signal.trap 'TERM' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants