title: Best practices for deploying Java webapps with minimal downtime?
body: <p>When deploying a large Java webapp (>100 MB .war) I'm currently use the following deployment process:</p>
  
  <ul>
  <li>The application .war file is expanded locally on the development machine.</li>
  <li>The expanded application is rsync:ed from the development machine to the live environment.</li>
  <li>The app server in the live environment is restarted after the rsync. This step is not strictly needed, but I've found that restarting the application server on deployment avoids "java.lang.OutOfMemoryError: PermGen space" due to frequent class loading.</li>
  </ul>
  
  <p>Good things about this approach:</p>
  
  <ul>
  <li>The rsync minimizes the amount of data sent from the development machine to the live environment. Uploading the entire .war file takes over ten minutes, whereas an rsync takes a couple of seconds.</li>
  </ul>
  
  <p>Bad things about this approach:</p>
  
  <ul>
  <li>While the rsync is running the application context is restarted since the files are updated. Ideally the restart should happen after the rsync is complete, not when it is still running.</li>
  <li>The app server restart causes roughly two minutes of downtime.</li>
  </ul>
  
  <p>I'd like to find a deployment process with the following properties:</p>
  
  <ul>
  <li>Minimal downtime during deployment process.</li>
  <li>Minimal time spent uploading the data.</li>
  <li>If the deployment process is app server specific, then the app server must be open-source.</li>
  </ul>
  
  <p>Question:</p>
  
  <ul>
  <li><b>Given the stated requirements, what is the optimal deployment process?</b></li>
  </ul>