Building Cloud Castles - LRUG
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Building Cloud Castles - LRUG

on

  • 1,184 views

Latest version of Building Cloud Castles, given at LRUG in April 2011....

Latest version of Building Cloud Castles, given at LRUG in April 2011.

A year ago, I was a committed VPS and dedicated-machine deployer. I thought the cloud imposed silly restrictions - how dare you take away my shell account! Whaddya mean I can't save files locally?

Since then, I've had some interesting experiences. I've worked on big cloud-deployed systems, and certain large traditionally-deployed systems, and I've seen how a lot of the decisions that you're ... encouraged to make when designing an app to run in the cloud. Most interestingly, I've discovered how those same decisions can make for a much better app regardless of where it'll end up. In this talk, I'll share those architectural patterns with you, and show why they work. Hopefully, I'll convince all of you to build cloud castles -- even if you've got your foundation firmly on the ground.

Statistics

Views

Total Views
1,184
Views on SlideShare
1,159
Embed Views
25

Actions

Likes
0
Downloads
4
Comments
0

3 Embeds 25

http://coderwall.com 23
https://twitter.com 1
http://localhost:3000 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Building Cloud Castles - LRUG Presentation Transcript

  • 1. BUILDING CLOUD CASTLESben scofield / @bscofield / LRUG / 11 April 2011
  • 2. this presentation is a WORK IN PROGRESShttp://www.flickr.com/photos/natlockwood/1006351276/
  • 3. not just
  • 4. the cloud allowsLIMITED ACCESS
  • 5. FINDING PROBLEMS
  • 6. LOCAL$ ssh deploy@production.server.comLinux production.server #1 SMP Sat Dec 5 16:04:55 UTC 2009 i686To access official Ubuntu documentation, please visit:http://help.ubuntu.com/Last login: Fri Jan 28 16:33:49 2011 from local.hostdeploy@production:~$ cd /var/log/apache2deploy@production:/var/log/apache2$ tail error.log[Sun Jan 23 06:25:02 2011] [notice] Apache/2.2.12 (Ubuntu) Phusion_Passenger...[Tue Jan 25 15:21:42 2011] [error] [client 118.129.166.97] Invalid URI in ...[Fri Jan 28 12:01:50 2011] [error] [client 85.132.70.133] client sent HTTP/1...[Sun Jan 30 06:25:06 2011] [notice] SIGUSR1 received. Doing graceful restart
  • 7. NODE NODE NODE NODENODE NODE NODE NODE
  • 8. CLOUD$ heroku logs --remote production2011-04-11T01:34:22-07:00 app[web.1]: Rendered text template within layout...2011-04-11T01:34:22-07:00 app[web.1]: Completed 200 OK in 54ms2011-04-11T01:34:30-07:00 app[web.3]: Rendered text template within layout...2011-04-11T01:34:30-07:00 app[web.3]: Completed 200 OK in 111ms (Views:57....2011-04-11T08:34:42+00:00 heroku[router]: GET devcenter.heroku.com/article...2011-04-11T01:34:42-07:00 heroku[nginx]: GET /articles/facebook HTTP/1.0 |...2011-04-11T01:34:42-07:00 app[worker.1]: [Worker(host:railgun64.53370 pid:...2011-04-11T01:34:42-07:00 app[worker.1]: [Worker(host:railgun64.53370 pid:...
  • 9. http://hoptoadapp.com
  • 10. http://newrelic.com
  • 11. source
  • 12. FIXING PROBLEMS
  • 13. LOCAL$ ssh deploy@production.server.comLinux production.server #1 SMP Sat Dec 5 16:04:55 UTC 2009 i686To access official Ubuntu documentation, please visit:http://help.ubuntu.com/Last login: Fri Jan 28 16:33:49 2011 from local.hostdeploy@production:~$ cd /var/www/app/current/deploy@production:/var/www/app/current$ rails console productionLoading production environment (Rails 3.0.3)>> Article.count => 112>> Article.where(:problem => true).update_attributes(:problem => false)
  • 14. CLOUDrequire test_helperclass ArticleTest < ActiveSupport::TestCase context Broken articles do setup do 5.times.do { Factory :broken_article } end should be fixable do assert_equal 5, Article.where(:problem => true).count Article.fix_problem_articles assert_equal 0, Article.where(:problem => true).count end endendclass Article def self.fix_problem_articles where(:problem => true).update_attributes(:problem => false) endend
  • 15. the cloud isUNRELIABLElocally
  • 16. LOCALclass Comic < ActiveRecord::Base has_attached_file :cover, :styles => { :thumb => "80x120>", :medium => "300x450>" }end$ cd public/system$ ls /covers10/ 12/ 53/ 81/$ ls /covers/10/medium/ original/ thumb/$ ls /covers/10/mediumbatman-450.png
  • 17. NODE NODE NODE NODENODE NODE NODE NODE
  • 18. EVENTUALCONSISTENCY
  • 19. CLOUDclass Comic < ActiveRecord::Base has_attached_file :cover, :storage => s3, :s3_credentials => { :access_key_id => ENV[S3_KEY], :secret_access_key => ENV[S3_SECRET] }, :bucket => comicsapp, :url => ":s3_path_url", :s3_headers => { Expires => 1.year.from_now.httpdate }, :styles => { :thumb => "80x120>", :medium => "300x450>" }end
  • 20. SERVER SERVER
  • 21. STORAGESERVER SERVER
  • 22. the cloud can beEXPENSIVE
  • 23. NODE NODE NODE NODENODE NODE NODE NODE
  • 24. CACHINGNODE NODE NODE NODENODE NODE NODE NODE
  • 25. SERVER
  • 26. CACHINGSERVER
  • 27. the cloud prefersSMALL APPS
  • 28. NODE NODE NODE NODENODE NODE NODE NODE
  • 29. NODE NODE NODE NODENODE NODE NODE NODE
  • 30. REST
  • 31. NODE NODE NODE EXTERNAL SERVICENODE NODE NODE
  • 32. SERVER
  • 33. SERVER SERVER
  • 34. SERVER SERVICE
  • 35. the cloud isUNRELIABLEremotely
  • 36. CLOUDclass Searcher cattr_accessor :index def self.index @api ||= IndexTank::Client.new(ENV[INDEXTANK_API_URL]) @index = @api.indexes articles end def self.search(term) raw = self.index.search(term, :function => 1) results = raw[results].to_a article_ids = results.map {|result| result[docid] } unsorted = Article.published.where(:id => article_ids) results.map { |result| unsorted.find {|u| u.id.to_i == result[docid].to_i} }.compact endend
  • 37. EXPECT FAILURE
  • 38. CLOUDclass Searcher # ... def self.search(term) results = begin raw = self.index.search(term, :function => 1) raw[results].to_a rescue URI::InvalidURIError # An IndexTank error occurred search_by_sql(term)[results] end # ... end def self.search_by_sql(term) {results => Article.where([content ILIKE ?, "%#{term}%"]). map {|a| {docid => a.id}}} endend
  • 39. DEFENSIVE CODING
  • 40. the cloud isALWAYS CURRENT
  • 41. RAISE YOUR HAND if
  • 42. INFRASTRUCTURE
  • 43. PATTERNS and VIRTUES
  • 44. HUMILITY
  • 45. LAZINESS
  • 46. PARANOIA
  • 47. SOLIDsingle responsibility principleliskov substitution principleinterface segregation principle
  • 48. CLOUD PRACTICESareBEST PRACTICES
  • 49. THANK YOU! Ben Scofield / @bscofield http://benscofield.com http://speakerrate.com/t/7123