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
Conversation
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' |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
This looks good Dan. 👍 |
preload_app true | ||
|
||
before_fork do |server, worker| | ||
Signal.trap 'TERM' do |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"...
There was a problem hiding this comment.
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.
Lower timeout to 5 seconds.
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