Multi-node deployment introduction

Deployment is always a hot topic. There are developers, most of the time including myself, who do not worry about deployment, until it becomes a problem. Updating one node is never too much of a problem. The average developer can do it in a couple of minutes. But can you still do this with a multi node installation. Do you suddenly need half a day?

As this is the last recipe, I will not provide you with a solution, because it does not exist. There are a dozen ways of deploying nodes:

  • Check out the application from VCS and run it. Pretty simple. However, do you also keep Play itself in the VCS? How do you keep that updated?
  • Start some shell script from one main node, which copies everything via scp or rsync. Great, but you still need to restart. How do you handle database upgrades?
  • You can use BitTorrent. Twitter does this to deploy tens of thousands of nodes in well under a minute. They use a self-written system called murder, which is available at https://github.com/lg/murder.
  • You might want to create packages before distributing your application or the framework itself across your nodes. This makes rollbacks pretty simple, while still making sure that only one installation is on your server. Lunatech Research has a nice module for this for Debian Linux, which can be downloaded at http://www.lunatech-labs.com/open-source/debian-play-module.

How to do it...

You should definitely use an init script, which is executed when the system starts. Possibly a script like this:

#!/bin/sh

PLAY=/usr/local/bin/play
APP=/usr/local/play/myapp
NAME=myapp
DESC="play application"

set -e

case "$1" in
    start)
        echo -n "Starting $DESC: " 
         $PLAY start $APP
         echo "$NAME."
        ;;
    stop)
        echo -n "Stopping $DESC: "
         $PLAY stop $APP
         echo "$NAME."
        ;;
    *)
        echo "Usage: $0 { start | stop }" >&2
        exit 1
        ;;
esac

exit 0

This script requires the correct path of the Play binary and the correct path of the application. If both are symbolical links, you will always be able to point to the most up-to-date application as well as your current Play installation.

This way you could put all your Play installations into /usr/local/play-inst/ and have directories like play-1.1 or play-1.2 Similar to this setup you could have /usr/local/play directory, where /usr/local/play/myapp is a symlink pointing to the application to run in the directory. A sample application directory name could include a timestamp like /usr/local/play/myapp-20110506.

As a preparation for every deployment, you could trigger the checkout of the VCS remotely, so that the application is already put into such a directory, when you switch to your updated application. You should also make sure, that your versioning system always grabs only the latest copy of your repository and not its complete history. Git has a so-called depth option, and bazaar features a lightweight checkout. Mercurial features this with some hacking around the convert extension.

If you do not want to use VCS on your application nodes, you could alternatively create an archive and put it up there.

How it works...

So let's sum up the preparation for each deployment here, in order to give you a guideline:

  1. Optional: Copy a new framework version to /usr/local/play-inst/ (out of your VCS, as a tarball via rsync/scp).
  2. Copy a new version of your application to /usr/local/play/myapp-$timestamp—set your timestamp correctly, so none of your old installations are overwritten.
  3. Stop your application.
  4. Change the symlink of the Play framework, if you did an upgrade.
  5. Change the symlink of the Play installation.
  6. Execute scripts to be executed. Tasks like database migration should be executed only once and not for all nodes.
  7. Start your application, make sure it starts, check the logs, and make sure the web server in front marks the application as up again.

There's more...

Multi node scalability in production is quite a complex topic, even with a shared nothing system like Play. You will run into dozens of obstacles, so always think ahead of problems instead of watching them flying in after deployment.

Add centralized logging to your multi node installation

Whenever you run multiple application nodes, it is pretty hard to track exceptions or even web sessions, as requests switch arbitrarily between hosts. A possible solution to this is a centralized log system, like Splunk. For more information on Splunk, check out http://www.splunk.com/. A possible problem with Splunk is, it not being a free software. The free version has only a limited amount of features, like only logging 500 megabytes of data a day.

Distributing configuration files in a different way

If you want to keep your configuration files away from your version control repository, you need to have another way to distribute them. You might want to check out some configuration management tools like puppet , which is available at http://www.puppetlabs.com/

Another more recent alternative is chef, which is newer than puppet, but does not yet feature as many plugins. Chef is available at http://wiki.opscode.com/display/chef/Home.

If you want to keep your data protected, like database passwords, this strategy might make sense, it also introduces quite some overhead because you have to keep two sources, namely the application and its configuration, in sync.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.97.216