Improving Your Heroku App Performance with Asset CDN and Unicorn
-
Upload
simon-bagreev -
Category
Documents
-
view
3.958 -
download
1
Transcript of Improving Your Heroku App Performance with Asset CDN and Unicorn
![Page 1: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/1.jpg)
Optimizing rails applications’ performance
w!"# A$$%" CDN &'( U'!)*r'
S!+*' B&,r%%v, @$"&"-$_200$b&,r%%v@,+&!..)*+
Friday, January 11, 13
![Page 2: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/2.jpg)
Question
Does anyone know what
f5dd
is?
Friday, January 11, 13
![Page 3: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/3.jpg)
What *is Preso is NOT
• not a coding demo or tutorial (strangely)
• not a best practices showcase
Friday, January 11, 13
![Page 4: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/4.jpg)
What *is Preso IS
• tips and tricks on tuning rails application
• personal experience
Friday, January 11, 13
![Page 5: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/5.jpg)
DisclaimerThere are many other ways to improve app’s performance:
•database performance (indexes, N+1, slow queries)•caching•background processing•changing interpreter, GC•conditional asset loading, etc•removing cruft!
Try them first!
Friday, January 11, 13
![Page 6: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/6.jpg)
*is Presentation - Two Parts
• CDN Asset Host using aws*
• unicorn web server*
* Both approaches were tested on heroku, but must work with other hosting solutions
Friday, January 11, 13
![Page 7: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/7.jpg)
Sample App
Friday, January 11, 13
![Page 8: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/8.jpg)
NewRelic Monitoring
average load time for mobile traffic only, includes iframed ads
Friday, January 11, 13
![Page 9: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/9.jpg)
Heroku Dyno Operation
Friday, January 11, 13
![Page 10: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/10.jpg)
Step 1 - Rack::Cache
Serving assets from rack::cache is faster, and frees up app instance to serve more requests
Friday, January 11, 13
![Page 11: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/11.jpg)
Static Asset Caching# Gemfilegem 'dalli'
# config/application.rbconfig.cache_store = :dalli_store
# config/environments/production.rbconfig.action_dispatch.rack_cache = { :metastore => Dalli::Client.new, :entitystore => 'file:tmp/cache/rack/body', :allow_reload => false}config.serve_static_assets = trueconfig.assets.digest = true
config.action_controller.perform_caching = true# provision Memcache addon on Heroku
Friday, January 11, 13
![Page 12: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/12.jpg)
A2er Deploymentshould see entries like this in your log
cache: [GET /assets/application-c0747cab950350f59304a3815f980622.css] miss, storecache: [GET /assets/application-032691d4988a7003c42a10995819a0ce.js] miss, storecache: [GET /assets/s_code.js] miss, store
cache: [GET /assets/application-c0747cab950350f59304a3815f980622.css] freshcache: [GET /assets/application-032691d4988a7003c42a10995819a0ce.js] freshcache: [GET /assets/s_code.js] fresh
Friday, January 11, 13
![Page 13: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/13.jpg)
Using Rack::Cache Effect
down from 4.91 / 201 / 2.29 before the change -- not bad for 8 lines of code!
Friday, January 11, 13
![Page 14: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/14.jpg)
Step 2 - S3 bucket for assets
heroku instance has more time to serve application code because all assets are served from aws s3
Friday, January 11, 13
![Page 15: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/15.jpg)
S3 Bucket for Assets# Gemfilegem "asset_sync" # will push compiled assets into CDN
# Command lineheroku config:add FOG_PROVIDER=AWS \ AWS_ACCESS_KEY_ID=xxx \ AWS_SECRET_ACCESS_KEY=yyy
heroku config:add FOG_DIRECTORY=yourappname-assets
# config/environments/production.rbconfig.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"
# make sure to use AssetTagHelper methods (like image_tag)# to ensure assets are properly referenced
Friday, January 11, 13
![Page 16: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/16.jpg)
Now, on git push heroku
assets are automatically synced to s3 anytime ON rake assets:precompile
Friday, January 11, 13
![Page 17: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/17.jpg)
S3 Bucket effect
down from 4.45 / 179 / 2.43 before the change -- even better!
Friday, January 11, 13
![Page 18: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/18.jpg)
Step 3 - AWS CloudFront
Friday, January 11, 13
![Page 19: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/19.jpg)
CloudFront Effect
down from 3.85 / 179 / 2.19 before the change -- Awesome!
Friday, January 11, 13
![Page 20: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/20.jpg)
Loading Single 5le$ time curl http://careersingear.mobi/assets/application-bdb77a926724ccc3c20b923ab168d89d.js
real 0m0.896suser 0m0.008ssys 0m0.016s
----------------
$ time curl http://d3kd72psxbec02.cloudfront.net/assets/application-bdb77a926724ccc3c20b923ab168d89d.js
real 0m0.293suser 0m0.006ssys 0m0.010s
getting a single application.js file from cloud front is 3x faster
Friday, January 11, 13
![Page 21: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/21.jpg)
WebPageTest ResultsBefore
Friday, January 11, 13
![Page 22: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/22.jpg)
WebPageTest Results A2er
Friday, January 11, 13
![Page 23: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/23.jpg)
Meet Unicorn• HTTp server for Ruby
• Starts one master process
• forks worker processes
• workers handle requests
• master returns
• one port, several concurrent requests
Friday, January 11, 13
![Page 24: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/24.jpg)
Server Setup
classic setup nginx -> smart balancer -> pool of mongrels
Unicorn setup nginx -> unix domain socket -> unicorn workers (os handles load balancing)
Friday, January 11, 13
![Page 25: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/25.jpg)
Unicorn for Rails App# Gemfilegem 'unicorn'
# Procfileweb: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
# config/application.rbconfig.logger = Logger.new(STDOUT)
# also, add config/unicorn.rb
Friday, January 11, 13
![Page 26: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/26.jpg)
Unicorn for Rails App# config/unicorn.rbworker_processes 3timeout 30preload_app true before_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.connection.disconnect! Rails.logger.info('Disconnected from ActiveRecord') end
if defined?(Resque) Resque.redis.quit Rails.logger.info('Disconnected from Redis') end
end after_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.establish_connection Rails.logger.info('Connected to ActiveRecord') end if defined?(Resque) Resque.redis = ENV["REDISTOGO_URL"] Rails.logger.info('Connected to Redis') endend
Friday, January 11, 13
![Page 27: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/27.jpg)
A2er Implementing Unicorn
down from 3.64 / 46.7 / 1.17 before the change -- good, but also...
Friday, January 11, 13
![Page 28: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/28.jpg)
Better Concurrency Handlingrequire 'typhoeus'require "benchmark"
URL = "http://careersingear.mobi"HYDRA = Typhoeus::Hydra.new(max_concurrency: 20)
1000.times do request = Typhoeus::Request.new(URL, method: :get, timeout: 10000) request.on_complete do |response| puts response.code end HYDRA.queue(request)end
Benchmark.bm(7) do |x| x.report("first:") { HYDRA.run }end
# using thin# user system total real# 1.030000 0.380000 1.410000 ( 16.713791)
# using unicorn# user system total real# 1.050000 0.390000 1.440000 ( 7.843766)
Friday, January 11, 13
![Page 29: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/29.jpg)
And ...
my app can process six concurrent requests on two heroku dynos
Friday, January 11, 13
![Page 30: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/30.jpg)
Riding Unicorn
Friday, January 11, 13
![Page 31: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/31.jpg)
To Conclude
• implemented asset cdn
• configured unicorn
• brought down average end user load time from almost 5 sec to 3.5 sec
• app can serve more requests faster and for less $$$
Friday, January 11, 13
![Page 32: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/32.jpg)
Friday, January 11, 13
![Page 33: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/33.jpg)
Creditsdefunkt, unicorn! https://github.com/blog/517-unicorn
heroku dev center, using rack::cache with memcached in rails 3.1+ https://devcenter.heroku.com/articles/
rack-cache-memcached-rails31
Rice, david, using a cdn asset host with rails 3.1 https://devcenter.heroku.com/articles/cdn-asset-
host-rails31
Sikkes, Michael, Complete Guide to serving your Rails assets over S3 with asset_sync http://blog.firmhouse.com/
complete-guide-to-serving-your-rails-assets-over-s3-with-asset_sync
van roijen, michael, more concurrency on a single heroku dyno with the new celadon cedar stack http://
michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-
with-the-new-celadon-cedar-stack/
Friday, January 11, 13
![Page 34: Improving Your Heroku App Performance with Asset CDN and Unicorn](https://reader034.fdocuments.us/reader034/viewer/2022042614/5551e9ebb4c90501638b515a/html5/thumbnails/34.jpg)
Q & AThis presentation can be found on github github.com/semmin/asset-cdn-and-unicorn-preso
twitter: @status_200
Email: [email protected]
Questions?
Friday, January 11, 13