Рекомендации по развертыванию веб-приложений Java с минимальным временем простоя? - PullRequest
55 голосов
/ 29 октября 2009

При развертывании большого веб-приложения Java (> 100 МБ .war) в настоящее время я использую следующий процесс развертывания:

  • Файл приложения .war локально разворачивается на компьютере разработчика.
  • Расширенное приложение rsync: ed из машины разработки в живую среду.
  • Сервер приложений в рабочей среде перезапускается после rsync. Этот шаг не является строго обязательным, но я обнаружил, что перезапуск сервера приложений при развертывании позволяет избежать «java.lang.OutOfMemoryError: PermGen space» из-за частой загрузки классов.

Что хорошего в этом подходе:

  • rsync минимизирует объем данных, отправляемых с компьютера разработчика в оперативную среду. Загрузка всего файла .war занимает более десяти минут, тогда как rsync занимает пару секунд.

Недостатки этого подхода:

  • Во время работы rsync контекст приложения перезапускается, так как файлы обновляются. В идеале перезапуск должен произойти после завершения rsync, а не когда он все еще работает.
  • Перезапуск сервера приложений вызывает примерно две минуты простоя.

Я бы хотел найти процесс развертывания со следующими свойствами:

  • Минимальное время простоя во время процесса развертывания.
  • Минимальное время загрузки данных.
  • Если процесс развертывания зависит от сервера приложений, то сервер приложений должен быть с открытым исходным кодом.

Вопрос:

  • С учетом заявленных требований, каков оптимальный процесс развертывания?

Ответы [ 18 ]

1 голос
/ 31 октября 2009

Я не уверен, что это ответит на ваш вопрос, но я просто расскажу о процессе развертывания, который я использую или сталкиваюсь в нескольких проектах, которые я сделал.

Схоже с вами, я никогда не вспоминаю о полном передислокации или обновлении войны. В большинстве случаев мои обновления ограничены несколькими jsp-файлами, возможно, библиотекой, некоторыми файлами классов. Я могу управлять и определять, какие именно артефакты затронуты, и обычно мы упаковывали это обновление в zip-файл вместе со скриптом обновления. Я буду запускать скрипт обновления. Сценарий выполняет следующие действия:

  • Резервное копирование файлов, которые будут перезаписаны, возможно, в папку с сегодняшними датой и временем.
  • Распакуйте мои файлы
  • Остановить сервер приложений
  • Переместить файлы поверх
  • Запустить сервер приложений

Если время простоя является проблемой, и обычно это так, мои проекты обычно представляют собой HA, даже если они не имеют общего состояния, но используют маршрутизатор, который обеспечивает маршрутизацию слипших сессий.

Еще одна вещь, которую мне любопытно было бы, зачем нуждаться в rsync? Вы должны знать, какие изменения необходимы, определяя их в своей среде подготовки / разработки, а не выполнять дельта-проверки в режиме реального времени. В большинстве случаев вам придется настроить rsync так, чтобы он все равно игнорировал файлы, например, определенные файлы свойств, которые определяют ресурсы, используемые производственным сервером, такие как соединение с базой данных, сервер smtp и т. Д.

Надеюсь, это полезно.

1 голос
/ 30 апреля 2010

Мы загружаем новую версию веб-приложения в отдельный каталог, затем либо перемещаемся, чтобы заменить его работающей, либо используем символические ссылки. Например, у нас есть символическая ссылка в каталоге веб-приложений tomcat с именем «myapp», которая указывает на текущее веб-приложение с именем «myapp-1.23». Мы загружаем новое веб-приложение в «myapp-1.24». Когда все будет готово, остановите сервер, удалите символическую ссылку и создайте новую, указывающую на новую версию, затем снова запустите сервер.

Мы отключаем автоматическую перезагрузку на производственных серверах для повышения производительности, но даже в этом случае изменение файлов в веб-приложении неядерным способом может вызвать проблемы, так как статические файлы или даже страницы JSP могут изменяться так, что это приводит к повреждению ссылок или хуже.

На практике веб-приложения на самом деле располагаются на общем устройстве хранения, поэтому кластерные серверы, серверы с балансировкой нагрузки и аварийным переключением имеют один и тот же код.

Основным недостатком вашей ситуации является то, что загрузка займет больше времени, поскольку ваш метод позволяет rsync передавать только измененные или добавленные файлы. Вы можете сначала скопировать старую папку веб-приложения в новую, и rsync, если это имеет существенное значение и если это действительно проблема.

1 голос
/ 01 августа 2014

Вы используете Resin, в Resin встроена поддержка контроля версий веб-приложений.

http://www.caucho.com/resin-4.0/admin/deploy.xtp#VersioningandGracefulUpgrades

Обновление: сторожевой процесс также может помочь с проблемами в permgenspace.

1 голос
/ 05 ноября 2009

На каком вашем PermSpace установлен? Я ожидал бы увидеть и этот рост, но должен упасть после сбора старых классов? (или ClassLoader все еще сидит без дела?)

Думая громко, вы можете rsync в отдельную директорию с именем или датой. Если контейнер поддерживает символические ссылки, не могли бы вы SIGSTOP корневого процесса, переключить корневой каталог файловой системы контекста через символическую ссылку, а затем SIGCONT?

1 голос
/ 19 апреля 2014

Просто используйте 2 или более сервера Tomcat с прокси-сервером. Этот прокси может быть apache / nignix / haproxy.

Теперь в каждом из прокси-серверов есть URL-адреса «in» и «out» с портами.

Сначала скопируйте свою войну в кота, не останавливая службу. Когда война развернута, она автоматически открывается механизмом кота.

Примечание: перекрестная проверка unpackWARs = "true" и autoDeploy = "true" в узле "Host" внутри server.xml

Это похоже на это

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true"
        xmlValidation="false" xmlNamespaceAware="false">

Теперь посмотрите логи кота. Если ошибки нет, значит, она успешно работает.

Теперь нажмите все API для тестирования

Теперь зайдите на ваш прокси-сервер.

Просто измените фоновое отображение URL на имя новой войны. Поскольку регистрация на прокси-серверах, таких как apache / nignix / haProxy, занимает очень мало времени, вы будете чувствовать минимальное время простоя

Обратитесь - https://developers.google.com/speed/pagespeed/module/domains для отображения URL

1 голос
/ 02 ноября 2013

Tomcat 7 имеет замечательную функцию под названием " параллельное развертывание ", предназначенную для этого варианта использования.

Суть в том, что вы расширяете .war в каталог, либо непосредственно под webapps /, либо по символической ссылке. Последующие версии приложения находятся в каталогах с именами app##version, например myapp##001 и myapp##002. Tomcat будет обрабатывать существующие сеансы, переходя на старую версию, а новые сеансы переходить на новую версию.

Загвоздка в том, что вы должны быть очень осторожными с утечками PermGen. Это особенно верно с Grails, который использует много PermGen. VisualVM - твой друг.

0 голосов
/ 31 октября 2012

Я написал скрипт bash, который принимает несколько параметров и выполняет rsyncs файл между серверами. Ускоряет передачу rsync для больших архивов:

https://gist.github.com/3985742

0 голосов
/ 21 мая 2010

Не "лучшая практика", а то, о чем я только что подумал.

Как насчет развертывания веб-приложения через DVCS, например, git?

Таким образом, вы можете позволить git выяснить, какие файлы передавать на сервер. У вас также есть хороший способ отойти от этого, если он окажется разорившимся, просто сделайте возврат!

...