Building Cloud Castles - LRUG

1,281 views
1,201 views

Published on

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.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,281
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Building Cloud Castles - LRUG

  1. 1. BUILDING CLOUD CASTLESben scofield / @bscofield / LRUG / 11 April 2011
  2. 2. this presentation is a WORK IN PROGRESShttp://www.flickr.com/photos/natlockwood/1006351276/
  3. 3. not just
  4. 4. the cloud allowsLIMITED ACCESS
  5. 5. FINDING PROBLEMS
  6. 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. 7. NODE NODE NODE NODENODE NODE NODE NODE
  8. 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. 9. http://hoptoadapp.com
  10. 10. http://newrelic.com
  11. 11. source
  12. 12. FIXING PROBLEMS
  13. 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. 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. 15. the cloud isUNRELIABLElocally
  16. 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. 17. NODE NODE NODE NODENODE NODE NODE NODE
  18. 18. EVENTUALCONSISTENCY
  19. 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. 20. SERVER SERVER
  21. 21. STORAGESERVER SERVER
  22. 22. the cloud can beEXPENSIVE
  23. 23. NODE NODE NODE NODENODE NODE NODE NODE
  24. 24. CACHINGNODE NODE NODE NODENODE NODE NODE NODE
  25. 25. SERVER
  26. 26. CACHINGSERVER
  27. 27. the cloud prefersSMALL APPS
  28. 28. NODE NODE NODE NODENODE NODE NODE NODE
  29. 29. NODE NODE NODE NODENODE NODE NODE NODE
  30. 30. REST
  31. 31. NODE NODE NODE EXTERNAL SERVICENODE NODE NODE
  32. 32. SERVER
  33. 33. SERVER SERVER
  34. 34. SERVER SERVICE
  35. 35. the cloud isUNRELIABLEremotely
  36. 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. 37. EXPECT FAILURE
  38. 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. 39. DEFENSIVE CODING
  40. 40. the cloud isALWAYS CURRENT
  41. 41. RAISE YOUR HAND if
  42. 42. INFRASTRUCTURE
  43. 43. PATTERNS and VIRTUES
  44. 44. HUMILITY
  45. 45. LAZINESS
  46. 46. PARANOIA
  47. 47. SOLIDsingle responsibility principleliskov substitution principleinterface segregation principle
  48. 48. CLOUD PRACTICESareBEST PRACTICES
  49. 49. THANK YOU! Ben Scofield / @bscofield http://benscofield.com http://speakerrate.com/t/7123

×