34
Optimizing rails applications’ performance w A CDN Ur S Brv, @_200 brv@. Friday, January 11, 13

Improving Your Heroku App Performance with Asset CDN and Unicorn

Embed Size (px)

Citation preview

Page 1: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

Question

Does anyone know what

f5dd

is?

Friday, January 11, 13

Page 3: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

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

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

*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

Sample App

Friday, January 11, 13

Page 8: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

Heroku Dyno Operation

Friday, January 11, 13

Page 10: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

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

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

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

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

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

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

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

Step 3 - AWS CloudFront

Friday, January 11, 13

Page 19: Improving Your Heroku App Performance with Asset CDN and Unicorn

CloudFront Effect

down from 3.85 / 179 / 2.19 before the change -- Awesome!

Friday, January 11, 13

Page 21: Improving Your Heroku App Performance with Asset CDN and Unicorn

WebPageTest ResultsBefore

Friday, January 11, 13

Page 22: Improving Your Heroku App Performance with Asset CDN and Unicorn

WebPageTest Results A2er

Friday, January 11, 13

Page 23: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

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

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

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

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

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

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

Riding Unicorn

Friday, January 11, 13

Page 31: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

Friday, January 11, 13

Page 33: Improving Your Heroku App Performance with Asset CDN and Unicorn

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

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