SlideShare une entreprise Scribd logo
1  sur  147
Télécharger pour lire hors ligne
zero     deploys
downtime   for Rails
                                           photo by Chris
             http://www.flickr.com/people/chrisinplymouth/
class ApparentlyHarmlessMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end
end
class CompletelySafeMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end

  def self.down
    add_column :users, :notes, :text
  end
end
class CompletelySafeMigration < ActiveRecord::Migration
  def self.up
    remove_column :users, :notes
  end

  def self.down
    add_column :users, :notes, :text
  end
end
PGError: ERROR: column "notes" does not exist
INSERT INTO users(email, password, ..., notes)
Zero downtime deploys for Rails apps
Zero downtime deploys for Rails apps
Zero downtime deploys for Rails apps
Zero downtime?




Challenge accepted
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Zero downtime deploys for Rails apps
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Testable code +
                             TDD
    Test coverage


  Easy maintenance            DRY


Zero downtime deploys   Hot compatibility
Hot compatibility


• Run concurrent versions of your
  application
• That are compatible between each other
Hot compatibility


  v1         v2
Hot compatibility


      v1                   v2

writes to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                          v1’                     v2

writes to `notes`        stop writing to `notes`   drop column `notes`
Hot compatibility


      v1                              v1’                      v2

writes to `notes`            stop writing to `notes`    drop column `notes`


               class User
                 def self.columns
                   super.reject { |c| c.name == "notes" }
                 end
               end
Self dependency
Self dependency
user loads form
Self dependency
new form is deployed
Self dependency
              user submits the form



 POST /login
 username=bill@microsoft.com&password=q1w2e3
Self dependency
            server blows up
Self dependency
• Make controllers compatible:
Self dependency
• Make controllers compatible:
  class AuthController < ApplicationController

    protected

    def filtered_params
      params.dup.tap do |p|
        p.merge!(:email => p.delete(:username))
      end
    end
  end
Assets - Rails 2

                          Server 1


GET /dashboard

200


GET /stylesheets/all.js

200
Assets - Rails 2

                          Server 1   Server 2


GET /dashboard

200


GET /stylesheets/all.js

404
Assets - Rails 2


• https://github.com/ddollar/asset-resource
Asset pipeline - Rails 3

                                    v1


  GET /dashboard

  200


  GET /assets/application-{v1}.js

  200
Asset pipeline - Rails 3

                                    v1   v2


  GET /dashboard

  200


  GET /assets/application-{v1}.js

  404
Asset pipeline - Rails 3
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
• We’re still in need of tooling to help
  cleaning up old assets
Asset pipeline - Rails 3

• When updating assets, keep the existing
  version around
• We’re still in need of tooling to help
  cleaning up old assets
  rake assets:clean:outdated
Migration strategies
Migration strategies
• Read-only models
Migration strategies
• Read-only models

   class Role < ActiveRecord::Base
     def readonly?
       true
     end
   end
Migration strategies
• Read-only models
• Ignore cached columns
Migration strategies
• Read-only models
• Ignore cached columns
   class User
     def self.columns
       super.reject { |c| c.name == "notes" }
     end
   end
Migration strategies
• Read-only models
• Ignore cached columns
• Know your database
Migration strategies
• Read-only models
• Ignore cached columns
• Know your database
 • Beware of O(n) db locks!
MyISAM
MyISAM
InnoDB
InnoDB
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
InnoDB
1. Create a new table with the same structure
2. Apply changes to new table
3. Copy data over
4. Acquire lock on original table
5. Sync new/updated/deleted rows
6. Swap tables
7. Release lock
InnoDB
1. Create a new table with the same structure
2. Apply changes to new table
3. Copy data over
4. Acquire lock on original table
5. Sync new/updated/deleted rows
6. Swap tables
7. Release lock
InnoDB
https://github.com/freels/table_migrator
InnoDB
https://github.com/freels/table_migrator

class AddStuffToMyBigTable < TableMigration

  migrates :users

  change_table do |t|
    t.integer :foo, :null => false, :default => 0
    t.string :bar
    t.index   :foo, :name => 'index_for_foo'
  end
end
InnoDB
https://github.com/freels/table_migrator
• Requires acts_as_paranoid
• Pretty old/stale codebase
  • Check forks for Rails 3 compatibility
Postgres
• Table locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
• O(n) locks on:
            constant time if you avoid default
                 values and constraints


 • Adding, updating or removing columns
 • Adding or removing indexes
Postgres
•   O(n) locks on:           constant time


    • Adding, updating or removing columns
    • Adding or removing indexes
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
   can be done without any locking
Postgres
• O(n) locks on:
 • Adding, updating or removing columns
 • Adding or removing indexes
                  constant time
Postgres
• Adding fields with defaults
Postgres
• Adding fields with defaults

         before_save :assign_defaults

         def assign_defaults
           self.admin ||= false
         end
Postgres
• Adding fields with defaults
• Create indexes concurrently
Postgres
   • Adding fields with defaults
   • Create indexes concurrently
CREATE INDEX CONCURRENTLY users_email_index ON users(email);
Postgres
• Adding fields with defaults
• Create indexes concurrently
 • Outside a transaction!
Postgres
       • Adding fields with defaults
       • Create indexes concurrently
        • Outside a transaction!
class AddIndexToUsers < ActiveRecord::Migration
  def self.up
    return if indexes("users").map(&:name).include?("users_email_index")
    add_index :users, :email, :name => "users_email_index"
  end

  def self.down
    remove_index :users, :name => "users_email_index"
  end
end
What about renaming?

        v1                 v2

  reads and writes   reads and writes
      to `foo`           to `bar`
What about renaming?

      v1                v1’               v1’’               v2

reads and writes   add column `bar`   populate `bar`   reads and writes
    to `foo`               +          where needed         to `bar`
                   reads from `foo`
                    writes to both
                    `foo` and `bar`
What about renaming?

       v2              v2’               v3

 reads and writes   ignore `foo`   drop column `foo`
     to `bar`
NoSQL
NoSQL

• Schema migrations / O(n) locks are just
  part of hot compatibility
NoSQL

• Schema migrations / O(n) locks are just
  part of hot compatibility
• You still need to put effort into data
  migration
Workflow
Workflow


• Make sure pull requests are addressing
  hot compatibility
Workflow


• Make sure pull requests are addressing
  hot compatibility
• Work after code is merged
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Meanwhile, in production...
$ thin -C config/server.yml restart
Stopping server on 0.0.0.0:5000 ...
Sending QUIT signal to process 3463 ...
Stopping server on 0.0.0.0:5001 ...
Sending QUIT signal to process 3464 ...
Stopping server on 0.0.0.0:5002 ...
Sending QUIT signal to process 3465 ...
Starting server on 0.0.0.0:5000 ...
Starting server on 0.0.0.0:5001 ...
Starting server on 0.0.0.0:5002 ...
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Production
Production

• Run multiple server processes
Production

• Run multiple server processes
• Cycle them individually, or in batches
Production

• Run multiple server processes
• Cycle them individually, or in batches
 • Watch out for capacity!
Production

• Run multiple server processes
• Cycle them individually, or in batches
 • Watch out for capacity!
• Cycle them gracefully
Cycling techniques

• Above the stack
• Within the stack
• Platform
Above the stack


• Use your favorite web server
• Setup a load balancer above them, route
  around servers that are cycling
Above the stack
• PROTIP: default setup won’t work
• Configure load balancer to poll for your
  application health:
  class HealthController < ApplicationController
    def index
      if File.exists?(Rails.root.join("MAINTENANCE"))
        render :text => "Forget me!", :status => 503
      else
        render :text => "I'm alive!"
      end
    end
  end
Cycling + Load balancer
                 Server   Load balancer


 touch MAINTENANCE


       bounce servers     remove server from rotation
   rm MAINTENANCE

new servers come online

                           add server to rotation
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
HAProxy
      tell HAProxy where to check for the health

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                       do not let your web server queue requests
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                             tell HAProxy to run the health check specified above
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                                             every 2s
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                              stop routing to it once the health check failed once
HAProxy

option httpchk GET /health

listen myapp :9000
  server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1
  server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1


                                       and bring it back once it worked once
ELB

$ elb-configure-healthcheck MyLoadBalancer 
    --target "HTTP:5000/health" 
    --interval 2 
    --unhealthy-threshold 1 
    --healthy-threshold 1
Above the stack
Above the stack
•   Minimal impact
Above the stack
•   Minimal impact

•   Extended availability
    comes for free
Above the stack
•   Minimal impact          •   Complicated setup

•   Extended availability
    comes for free
Above the stack
•   Minimal impact          •   Complicated setup

•   Extended availability   •   Another component you
    comes for free              have to track and maintain
Within the stack
Within the stack
Unicorn


• Replaces your web server
• Bounces gracefully
Unicorn
63480   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
$ kill -USR2 63480

63480   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
$ kill -USR2 63480

63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
$ kill -QUIT 63480

63480   0.0   1.4   2549796   unicorn_rails   master (old) -c config/unicorn.rb
63489   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63490   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63491   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
63521   0.0   1.4   2549796   unicorn_rails   master -c config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0] -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1] -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2] -c config/unicorn.rb
Unicorn
$ kill -QUIT 63480

63521   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Unicorn
63521   0.0   1.4   2549796   unicorn_rails   master -c   config/unicorn.rb
63535   0.0   0.2   2549796   unicorn_rails   worker[0]   -c config/unicorn.rb
63536   0.0   0.2   2549796   unicorn_rails   worker[1]   -c config/unicorn.rb
63537   0.0   0.2   2549796   unicorn_rails   worker[2]   -c config/unicorn.rb
Within the stack
Within the stack
•   Easy to setup and deploy
Within the stack
•   Easy to setup and deploy

•   Optimal performance to
    cycle the server
Within the stack
•   Easy to setup and deploy   •   Changes your application
                                   stack
•   Optimal performance to
    cycle the server
Within the stack
•   Easy to setup and deploy   •   Changes your application
                                   stack
•   Optimal performance to
    cycle the server           •   Doesn’t address availability
                                   issues
Platform
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku

$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku

$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     starting for 1s   bundle exec thin start -p $PORT
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     starting for 5s   bundle exec thin start -p $PORT
Heroku


Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 1s         bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ heroku labs:enable preboot

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
Heroku            BETA




$ git push heroku master

Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
web.1     starting for 5s   bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 10h        bundle exec thin start -p $PORT
web.1     up for 1s         bundle exec thin start -p $PORT
Heroku            BETA




Process   State             Command
-------   ---------------   -------------------------------
web.1     up for 5s         bundle exec thin start -p $PORT
Heroku
• Migrations
Heroku
• Migrations
  $ git push pre-production master
  $ heroku run rake db:migrate --remote pre-production
  $ git push production master
Agenda

• Introduction
• Development practices
• Production environment setup
• Future
• Conclusion
Future
Future

• Asset pipeline
Future

• Asset pipeline
• Mysql tooling
Future

• Asset pipeline
• Mysql tooling
• Can Rails help making the development of
  hot compatible applications easier?
Future

• Asset pipeline
• Mysql tooling
• Can Rails help making the development of
  hot compatible applications easier?
• Can databases?
Future
Future


• Hot compatibility beyond zero downtime
  deploys
Conclusion
Conclusion

• Zero downtime is a pain in the ass
Conclusion

• Zero downtime is a pain in the ass
• Hot compatibility to the rescue
Conclusion

• Zero downtime is a pain in the ass
• Hot compatibility to the rescue
• Make sure your production env is ready
Thank you!
http://pedro.heroku.com

        @ped

Contenu connexe

Tendances

Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSShekhar Gulati
 
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015Matt Raible
 
Puppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedInYevgeniy Brikman
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Matt Raible
 
How to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onHow to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onAtlassian
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)ColdFusionConference
 
Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Matt Raible
 
Capacity Management for Web Operations
Capacity Management for Web OperationsCapacity Management for Web Operations
Capacity Management for Web OperationsJohn Allspaw
 
Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Pavel Kaminsky
 
BDD in Java using Cucumber
BDD in Java using CucumberBDD in Java using Cucumber
BDD in Java using Cucumberslavkurochkin
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksAddy Osmani
 
Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Matt Raible
 
Continuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixContinuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixAtlassian
 
Continuous deployment-at-flipkart
Continuous deployment-at-flipkartContinuous deployment-at-flipkart
Continuous deployment-at-flipkartPankaj Kaushal
 
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Dave Olsen
 

Tendances (20)

Node.js vs Play Framework
Node.js vs Play FrameworkNode.js vs Play Framework
Node.js vs Play Framework
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJS
 
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
 
Rebooting a Cloud
Rebooting a CloudRebooting a Cloud
Rebooting a Cloud
 
Puppet Release Workflows at Jive Software
Puppet Release Workflows at Jive SoftwarePuppet Release Workflows at Jive Software
Puppet Release Workflows at Jive Software
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedIn
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
How to Build a Better JIRA Add-on
How to Build a Better JIRA Add-onHow to Build a Better JIRA Add-on
How to Build a Better JIRA Add-on
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)
 
Cache is King
Cache is KingCache is King
Cache is King
 
Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015Developing, Testing and Scaling with Apache Camel - UberConf 2015
Developing, Testing and Scaling with Apache Camel - UberConf 2015
 
Capacity Management for Web Operations
Capacity Management for Web OperationsCapacity Management for Web Operations
Capacity Management for Web Operations
 
Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments Java 6 [Mustang] - Features and Enchantments
Java 6 [Mustang] - Features and Enchantments
 
BDD in Java using Cucumber
BDD in Java using CucumberBDD in Java using Cucumber
BDD in Java using Cucumber
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & Tricks
 
Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013Play Framework vs Grails Smackdown - JavaOne 2013
Play Framework vs Grails Smackdown - JavaOne 2013
 
Continuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at NetflixContinuously Integrating Distributed Code at Netflix
Continuously Integrating Distributed Code at Netflix
 
Continuous deployment-at-flipkart
Continuous deployment-at-flipkartContinuous deployment-at-flipkart
Continuous deployment-at-flipkart
 
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
Everything You Know is Not Quite Right Anymore: Rethinking Best Practices to ...
 

En vedette

Continuous delivery for databases
Continuous delivery for databasesContinuous delivery for databases
Continuous delivery for databasesDevOpsGroup
 
LSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemLSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemMario Juric
 
Integrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideIntegrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideYu Tao Zhang
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeMichael May
 
Automate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopAutomate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopRed Gate Software
 
Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with DjangoRoger Barnes
 
Fault Tolerance with Kubernetes
Fault Tolerance with KubernetesFault Tolerance with Kubernetes
Fault Tolerance with KubernetesAditya Patawari
 
How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1Thoughtworks
 
Tricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationTricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationSimon Willison
 
Scalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosScalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosOlivier Paugam
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentRobert Treat
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsAndrei Solntsev
 
Docker - Sysmana 2014
Docker - Sysmana 2014Docker - Sysmana 2014
Docker - Sysmana 2014quaip
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentChristopher Read
 
Machine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksMachine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksNicolas Le Roux
 
Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Olivier Chapelle
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBrendan Gregg
 

En vedette (20)

Continuous delivery for databases
Continuous delivery for databasesContinuous delivery for databases
Continuous delivery for databases
 
Database compatibility
Database compatibilityDatabase compatibility
Database compatibility
 
How To Avoid Database Migration Hell
How To Avoid Database Migration HellHow To Avoid Database Migration Hell
How To Avoid Database Migration Hell
 
LSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing SystemLSST/DM: Building a Next Generation Survey Data Processing System
LSST/DM: Building a Next Generation Survey Data Processing System
 
Integrate UFT with Jenkins Guide
Integrate UFT with Jenkins GuideIntegrate UFT with Jenkins Guide
Integrate UFT with Jenkins Guide
 
Rails Caching Secrets from the Edge
Rails Caching Secrets from the EdgeRails Caching Secrets from the Edge
Rails Caching Secrets from the Edge
 
Automate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City WorkshopAutomate Database Deployment - SQL In The City Workshop
Automate Database Deployment - SQL In The City Workshop
 
Towards Continuous Deployment with Django
Towards Continuous Deployment with DjangoTowards Continuous Deployment with Django
Towards Continuous Deployment with Django
 
Fault Tolerance with Kubernetes
Fault Tolerance with KubernetesFault Tolerance with Kubernetes
Fault Tolerance with Kubernetes
 
How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1How do you implement Continuous Delivery? Part 1
How do you implement Continuous Delivery? Part 1
 
Tricks & challenges developing a large Django application
Tricks & challenges developing a large Django applicationTricks & challenges developing a large Django application
Tricks & challenges developing a large Django application
 
Scalable Eventing Over Apache Mesos
Scalable Eventing Over Apache MesosScalable Eventing Over Apache Mesos
Scalable Eventing Over Apache Mesos
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps Environment
 
Hadoop summit-ams-2014-04-03
Hadoop summit-ams-2014-04-03Hadoop summit-ams-2014-04-03
Hadoop summit-ams-2014-04-03
 
Liquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOpsLiquibase & Flyway @ Baltic DevOps
Liquibase & Flyway @ Baltic DevOps
 
Docker - Sysmana 2014
Docker - Sysmana 2014Docker - Sysmana 2014
Docker - Sysmana 2014
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous Deployment
 
Machine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris DatageeksMachine learning at Criteo - Paris Datageeks
Machine learning at Criteo - Paris Datageeks
 
Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014Response prediction for display advertising - WSDM 2014
Response prediction for display advertising - WSDM 2014
 
Blazing Performance with Flame Graphs
Blazing Performance with Flame GraphsBlazing Performance with Flame Graphs
Blazing Performance with Flame Graphs
 

Similaire à Zero downtime deploys for Rails apps

Version control with subversion
Version control with subversionVersion control with subversion
Version control with subversionxprayc
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database DeploymentsMike Willbanks
 
Kubernetes Workshop
Kubernetes WorkshopKubernetes Workshop
Kubernetes Workshoploodse
 
9th docker meetup 2016.07.13
9th docker meetup 2016.07.139th docker meetup 2016.07.13
9th docker meetup 2016.07.13Amrita Prasad
 
Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Michael Dimmitt
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Bostonbenbrowning
 
Docker for Dummies
Docker for DummiesDocker for Dummies
Docker for DummiesRoel Hartman
 
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructureFrom Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructurePerforce
 
Elixir Programming Language 101
Elixir Programming Language 101Elixir Programming Language 101
Elixir Programming Language 101Around25
 
Serverless: A love hate relationship
Serverless: A love hate relationshipServerless: A love hate relationship
Serverless: A love hate relationshipJürgen Brüder
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011Bachkoutou Toutou
 
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...Simplilearn
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side SwiftChad Moone
 
Version Control With Subversion
Version Control With SubversionVersion Control With Subversion
Version Control With SubversionSamnang Chhun
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Nilesh Panchal
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLMario-Leander Reimer
 

Similaire à Zero downtime deploys for Rails apps (20)

Version control with subversion
Version control with subversionVersion control with subversion
Version control with subversion
 
Versioning for Developers
Versioning for DevelopersVersioning for Developers
Versioning for Developers
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database Deployments
 
Kubernetes Workshop
Kubernetes WorkshopKubernetes Workshop
Kubernetes Workshop
 
9th docker meetup 2016.07.13
9th docker meetup 2016.07.139th docker meetup 2016.07.13
9th docker meetup 2016.07.13
 
Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.Elixir/Phoenix releases and research about common deployment strategies.
Elixir/Phoenix releases and research about common deployment strategies.
 
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 BostonScaling Rails With Torquebox Presented at JUDCon:2011 Boston
Scaling Rails With Torquebox Presented at JUDCon:2011 Boston
 
Docker for Dummies
Docker for DummiesDocker for Dummies
Docker for Dummies
 
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix InfrastructureFrom Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
From Windows to Linux: Converting a Distributed Perforce Helix Infrastructure
 
Elixir Programming Language 101
Elixir Programming Language 101Elixir Programming Language 101
Elixir Programming Language 101
 
Serverless: A love hate relationship
Serverless: A love hate relationshipServerless: A love hate relationship
Serverless: A love hate relationship
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
DevOps Interview Questions Part - 2 | Devops Interview Questions And Answers ...
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side Swift
 
Version Control With Subversion
Version Control With SubversionVersion Control With Subversion
Version Control With Subversion
 
TorqueBox
TorqueBoxTorqueBox
TorqueBox
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
 
VS Debugging Tricks
VS Debugging TricksVS Debugging Tricks
VS Debugging Tricks
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPL
 

Dernier

Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 

Dernier (20)

Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 

Zero downtime deploys for Rails apps

  • 1. zero deploys downtime for Rails photo by Chris http://www.flickr.com/people/chrisinplymouth/
  • 2. class ApparentlyHarmlessMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end end
  • 3. class CompletelySafeMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end   def self.down     add_column :users, :notes, :text   end end
  • 4. class CompletelySafeMigration < ActiveRecord::Migration   def self.up     remove_column :users, :notes   end   def self.down     add_column :users, :notes, :text   end end
  • 5. PGError: ERROR: column "notes" does not exist
  • 6. INSERT INTO users(email, password, ..., notes)
  • 11. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 13. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 14. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 15. Testable code + TDD Test coverage Easy maintenance DRY Zero downtime deploys Hot compatibility
  • 16. Hot compatibility • Run concurrent versions of your application • That are compatible between each other
  • 18. Hot compatibility v1 v2 writes to `notes` drop column `notes`
  • 19. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 20. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 21. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 22. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes`
  • 23. Hot compatibility v1 v1’ v2 writes to `notes` stop writing to `notes` drop column `notes` class User   def self.columns     super.reject { |c| c.name == "notes" }   end end
  • 27. Self dependency user submits the form POST /login username=bill@microsoft.com&password=q1w2e3
  • 28. Self dependency server blows up
  • 29. Self dependency • Make controllers compatible:
  • 30. Self dependency • Make controllers compatible: class AuthController < ApplicationController   protected   def filtered_params     params.dup.tap do |p|       p.merge!(:email => p.delete(:username))     end   end end
  • 31. Assets - Rails 2 Server 1 GET /dashboard 200 GET /stylesheets/all.js 200
  • 32. Assets - Rails 2 Server 1 Server 2 GET /dashboard 200 GET /stylesheets/all.js 404
  • 33. Assets - Rails 2 • https://github.com/ddollar/asset-resource
  • 34. Asset pipeline - Rails 3 v1 GET /dashboard 200 GET /assets/application-{v1}.js 200
  • 35. Asset pipeline - Rails 3 v1 v2 GET /dashboard 200 GET /assets/application-{v1}.js 404
  • 36. Asset pipeline - Rails 3
  • 37. Asset pipeline - Rails 3 • When updating assets, keep the existing version around
  • 38. Asset pipeline - Rails 3 • When updating assets, keep the existing version around • We’re still in need of tooling to help cleaning up old assets
  • 39. Asset pipeline - Rails 3 • When updating assets, keep the existing version around • We’re still in need of tooling to help cleaning up old assets rake assets:clean:outdated
  • 42. Migration strategies • Read-only models class Role < ActiveRecord::Base   def readonly?     true   end end
  • 43. Migration strategies • Read-only models • Ignore cached columns
  • 44. Migration strategies • Read-only models • Ignore cached columns class User   def self.columns     super.reject { |c| c.name == "notes" }   end end
  • 45. Migration strategies • Read-only models • Ignore cached columns • Know your database
  • 46. Migration strategies • Read-only models • Ignore cached columns • Know your database • Beware of O(n) db locks!
  • 50. InnoDB • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 51. InnoDB 1. Create a new table with the same structure 2. Apply changes to new table 3. Copy data over 4. Acquire lock on original table 5. Sync new/updated/deleted rows 6. Swap tables 7. Release lock
  • 52. InnoDB 1. Create a new table with the same structure 2. Apply changes to new table 3. Copy data over 4. Acquire lock on original table 5. Sync new/updated/deleted rows 6. Swap tables 7. Release lock
  • 54. InnoDB https://github.com/freels/table_migrator class AddStuffToMyBigTable < TableMigration   migrates :users   change_table do |t|     t.integer :foo, :null => false, :default => 0     t.string :bar     t.index :foo, :name => 'index_for_foo'   end end
  • 55. InnoDB https://github.com/freels/table_migrator • Requires acts_as_paranoid • Pretty old/stale codebase • Check forks for Rails 3 compatibility
  • 56. Postgres • Table locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 57. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes
  • 58. Postgres • O(n) locks on: constant time if you avoid default values and constraints • Adding, updating or removing columns • Adding or removing indexes
  • 59. Postgres • O(n) locks on: constant time • Adding, updating or removing columns • Adding or removing indexes
  • 60. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes can be done without any locking
  • 61. Postgres • O(n) locks on: • Adding, updating or removing columns • Adding or removing indexes constant time
  • 63. Postgres • Adding fields with defaults before_save :assign_defaults def assign_defaults   self.admin ||= false end
  • 64. Postgres • Adding fields with defaults • Create indexes concurrently
  • 65. Postgres • Adding fields with defaults • Create indexes concurrently CREATE INDEX CONCURRENTLY users_email_index ON users(email);
  • 66. Postgres • Adding fields with defaults • Create indexes concurrently • Outside a transaction!
  • 67. Postgres • Adding fields with defaults • Create indexes concurrently • Outside a transaction! class AddIndexToUsers < ActiveRecord::Migration   def self.up     return if indexes("users").map(&:name).include?("users_email_index")     add_index :users, :email, :name => "users_email_index"   end   def self.down     remove_index :users, :name => "users_email_index"   end end
  • 68. What about renaming? v1 v2 reads and writes reads and writes to `foo` to `bar`
  • 69. What about renaming? v1 v1’ v1’’ v2 reads and writes add column `bar` populate `bar` reads and writes to `foo` + where needed to `bar` reads from `foo` writes to both `foo` and `bar`
  • 70. What about renaming? v2 v2’ v3 reads and writes ignore `foo` drop column `foo` to `bar`
  • 71. NoSQL
  • 72. NoSQL • Schema migrations / O(n) locks are just part of hot compatibility
  • 73. NoSQL • Schema migrations / O(n) locks are just part of hot compatibility • You still need to put effort into data migration
  • 75. Workflow • Make sure pull requests are addressing hot compatibility
  • 76. Workflow • Make sure pull requests are addressing hot compatibility • Work after code is merged
  • 77. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 78. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 79. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 80. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 81. Meanwhile, in production... $ thin -C config/server.yml restart Stopping server on 0.0.0.0:5000 ... Sending QUIT signal to process 3463 ... Stopping server on 0.0.0.0:5001 ... Sending QUIT signal to process 3464 ... Stopping server on 0.0.0.0:5002 ... Sending QUIT signal to process 3465 ... Starting server on 0.0.0.0:5000 ... Starting server on 0.0.0.0:5001 ... Starting server on 0.0.0.0:5002 ...
  • 82. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 84. Production • Run multiple server processes
  • 85. Production • Run multiple server processes • Cycle them individually, or in batches
  • 86. Production • Run multiple server processes • Cycle them individually, or in batches • Watch out for capacity!
  • 87. Production • Run multiple server processes • Cycle them individually, or in batches • Watch out for capacity! • Cycle them gracefully
  • 88. Cycling techniques • Above the stack • Within the stack • Platform
  • 89. Above the stack • Use your favorite web server • Setup a load balancer above them, route around servers that are cycling
  • 90. Above the stack • PROTIP: default setup won’t work • Configure load balancer to poll for your application health: class HealthController < ApplicationController   def index     if File.exists?(Rails.root.join("MAINTENANCE"))       render :text => "Forget me!", :status => 503     else       render :text => "I'm alive!"     end   end end
  • 91. Cycling + Load balancer Server Load balancer touch MAINTENANCE bounce servers remove server from rotation rm MAINTENANCE new servers come online add server to rotation
  • 92. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
  • 93. HAProxy tell HAProxy where to check for the health option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1
  • 94. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 do not let your web server queue requests
  • 95. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 tell HAProxy to run the health check specified above
  • 96. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 every 2s
  • 97. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 stop routing to it once the health check failed once
  • 98. HAProxy option httpchk GET /health listen myapp :9000 server myapp-1 1.0.0.1:5000 maxconn 1 check inter 2000 fall 1 rise 1 server myapp-2 1.0.0.2:5000 maxconn 1 check inter 2000 fall 1 rise 1 and bring it back once it worked once
  • 99. ELB $ elb-configure-healthcheck MyLoadBalancer --target "HTTP:5000/health" --interval 2 --unhealthy-threshold 1 --healthy-threshold 1
  • 101. Above the stack • Minimal impact
  • 102. Above the stack • Minimal impact • Extended availability comes for free
  • 103. Above the stack • Minimal impact • Complicated setup • Extended availability comes for free
  • 104. Above the stack • Minimal impact • Complicated setup • Extended availability • Another component you comes for free have to track and maintain
  • 107. Unicorn • Replaces your web server • Bounces gracefully
  • 108. Unicorn 63480 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 109. Unicorn $ kill -USR2 63480 63480 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 110. Unicorn $ kill -USR2 63480 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 111. Unicorn 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 112. Unicorn $ kill -QUIT 63480 63480 0.0 1.4 2549796 unicorn_rails master (old) -c config/unicorn.rb 63489 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63490 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63491 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 113. Unicorn $ kill -QUIT 63480 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 114. Unicorn 63521 0.0 1.4 2549796 unicorn_rails master -c config/unicorn.rb 63535 0.0 0.2 2549796 unicorn_rails worker[0] -c config/unicorn.rb 63536 0.0 0.2 2549796 unicorn_rails worker[1] -c config/unicorn.rb 63537 0.0 0.2 2549796 unicorn_rails worker[2] -c config/unicorn.rb
  • 116. Within the stack • Easy to setup and deploy
  • 117. Within the stack • Easy to setup and deploy • Optimal performance to cycle the server
  • 118. Within the stack • Easy to setup and deploy • Changes your application stack • Optimal performance to cycle the server
  • 119. Within the stack • Easy to setup and deploy • Changes your application stack • Optimal performance to cycle the server • Doesn’t address availability issues
  • 121. Heroku Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 122. Heroku $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 123. Heroku $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 starting for 1s bundle exec thin start -p $PORT
  • 124. Heroku Process State Command ------- --------------- ------------------------------- web.1 starting for 5s bundle exec thin start -p $PORT
  • 125. Heroku Process State Command ------- --------------- ------------------------------- web.1 up for 1s bundle exec thin start -p $PORT
  • 126. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 127. Heroku BETA $ heroku labs:enable preboot Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 128. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 129. Heroku BETA $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT
  • 130. Heroku BETA $ git push heroku master Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT web.1 starting for 5s bundle exec thin start -p $PORT
  • 131. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 10h bundle exec thin start -p $PORT web.1 up for 1s bundle exec thin start -p $PORT
  • 132. Heroku BETA Process State Command ------- --------------- ------------------------------- web.1 up for 5s bundle exec thin start -p $PORT
  • 134. Heroku • Migrations $ git push pre-production master $ heroku run rake db:migrate --remote pre-production $ git push production master
  • 135. Agenda • Introduction • Development practices • Production environment setup • Future • Conclusion
  • 136. Future
  • 139. Future • Asset pipeline • Mysql tooling • Can Rails help making the development of hot compatible applications easier?
  • 140. Future • Asset pipeline • Mysql tooling • Can Rails help making the development of hot compatible applications easier? • Can databases?
  • 141. Future
  • 142. Future • Hot compatibility beyond zero downtime deploys
  • 144. Conclusion • Zero downtime is a pain in the ass
  • 145. Conclusion • Zero downtime is a pain in the ass • Hot compatibility to the rescue
  • 146. Conclusion • Zero downtime is a pain in the ass • Hot compatibility to the rescue • Make sure your production env is ready