Prewarm your workers before they receive real traffic.
Add this line to your application's Gemfile:
gem 'unicorn-prewarm'
And then execute:
$ bundle
Or install it yourself as:
$ gem install unicorn-prewarm
In unicorn config after_fork
do:
after_fork do |server,worker|
response = Unicorn.prewarm(server)
# check if the response is OK, it shall be Net::HTTPSuccess
end
If you are using Rack::Timeout
you might want to do something like:
after_fork do |server, worker|
# Code to reconnect all databases belongs here
server.logger.info("worker=#{worker.nr} spawned pid=#{$$}")
timeout = Rack::Timeout.service_timeout
begin
Rack::Timeout.service_timeout = 60
server.logger.info("worker=#{worker.nr} prewarming")
start = Time.now
Unicorn.prewarm(server).is_a?(Net::HTTPSuccess) or raise "Prewarm of worker #{worker.nr} failed"
server.logger.info("worker=#{worker.nr} prewarmed in #{Time.now - start}")
rescue => error
server.logger.error("worker=#{worker.nr} prewarm failed: #{error} in #{Time.now - start}")
raise
ensure
Rack::Timeout.service_timeout = timeout
end
end
To prevent from timeouting on first requests.
- Fork it ( https://github.com/3scale/unicorn-prewarm/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request