Transcript
Page 1: Building Cloud Castles - LRUG

ben scofield / @bscofield / LRUG / 11 April 2011

BUILDINGCLOUD

CASTLES

Page 2: Building Cloud Castles - LRUG

http://www.flickr.com/photos/natlockwood/1006351276/

WORK IN PROGRESSthis presentation is a

Page 3: Building Cloud Castles - LRUG
Page 4: Building Cloud Castles - LRUG

not just

Page 5: Building Cloud Castles - LRUG

the cloud allowsLIMITED ACCESS

Page 6: Building Cloud Castles - LRUG

FINDING PROBLEMS

Page 7: Building Cloud Castles - LRUG

LOCAL$ ssh [email protected] production.server #1 SMP Sat Dec 5 16:04:55 UTC 2009 i686

To 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

Page 8: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

Page 9: Building Cloud Castles - LRUG

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:...

Page 10: Building Cloud Castles - LRUG

http://hoptoadapp.com

Page 11: Building Cloud Castles - LRUG

http://newrelic.com

Page 12: Building Cloud Castles - LRUG

source

Page 13: Building Cloud Castles - LRUG

FIXING PROBLEMS

Page 14: Building Cloud Castles - LRUG

LOCAL$ ssh [email protected] production.server #1 SMP Sat Dec 5 16:04:55 UTC 2009 i686

To 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)

Page 15: Building Cloud Castles - LRUG

CLOUDrequire 'test_helper'

class 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 endend

class Article def self.fix_problem_articles where(:problem => true).update_attributes(:problem => false) endend

Page 16: Building Cloud Castles - LRUG

the cloud isUNRELIABLE locally

Page 17: Building Cloud Castles - LRUG

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

Page 18: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

Page 19: Building Cloud Castles - LRUG

EVENTUAL CONSISTENCY

Page 20: Building Cloud Castles - LRUG

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

Page 21: Building Cloud Castles - LRUG

SERVER SERVER

Page 22: Building Cloud Castles - LRUG

SERVER SERVER

STORAGE

Page 23: Building Cloud Castles - LRUG

the cloud can beEXPENSIVE

Page 24: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

Page 25: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

CACHING

Page 26: Building Cloud Castles - LRUG

SERVER

Page 27: Building Cloud Castles - LRUG

SERVER

CACHING

Page 28: Building Cloud Castles - LRUG

the cloud prefersSMALL APPS

Page 29: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

Page 30: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODE

NODE

NODE

Page 31: Building Cloud Castles - LRUG

REST

Page 32: Building Cloud Castles - LRUG

NODE

NODE

NODE

NODE

NODE

NODEEXTERNALSERVICE

Page 33: Building Cloud Castles - LRUG
Page 34: Building Cloud Castles - LRUG

SERVER

Page 35: Building Cloud Castles - LRUG

SERVER SERVER

Page 36: Building Cloud Castles - LRUG

SERVICESERVER

Page 37: Building Cloud Castles - LRUG

the cloud isUNRELIABLEremotely

Page 38: Building Cloud Castles - LRUG

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

Page 39: Building Cloud Castles - LRUG

EXPECT FAILURE

Page 40: Building Cloud Castles - LRUG

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

Page 41: Building Cloud Castles - LRUG

DEFENSIVE CODING

Page 42: Building Cloud Castles - LRUG

the cloud isALWAYS CURRENT

Page 43: Building Cloud Castles - LRUG

RAISE YOUR HAND if

Page 44: Building Cloud Castles - LRUG

INFRASTRUCTURE

Page 45: Building Cloud Castles - LRUG

PATTERNS and VIRTUES

Page 46: Building Cloud Castles - LRUG

HUMILITY

Page 47: Building Cloud Castles - LRUG

LAZINESS

Page 48: Building Cloud Castles - LRUG

PARANOIA

Page 49: Building Cloud Castles - LRUG

SOLIDsingle responsibility principleliskov substitution principleinterface segregation principle

Page 50: Building Cloud Castles - LRUG

CLOUD PRACTICESareBEST PRACTICES

Page 51: Building Cloud Castles - LRUG

THANK YOU!

Ben Scofield / @bscofieldhttp://benscofield.comhttp://speakerrate.com/t/7123