Подтвердить что ты не робот

Как вы дистанционно обновляете Java-приложения?

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

Процесс должен быть без присмотра и надежным (т.е. мы не можем позволить себе разорвать приложение из-за несвоевременного отключения интернета).

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

Кто-нибудь нашел хорошее решение для этого уже? Есть идеи или предложения?

Просто уточнить: это приложение является сервером, но не для веб-приложений (здесь нет контейнеров webapp или WAR файлов). Это просто автономная программа Java.

4b9b3361

Ответ 1

Вы не указали тип серверных приложений - я предполагаю, что вы не используете веб-приложения (поскольку развертывание WAR уже делает то, о чем вы говорите, и вам очень редко требуется веб-приложение для если вы говорите о веб-приложении, следующее обсуждение может по-прежнему применяться - вы просто реализуете проверку обновлений и пинг-понг для файла WAR вместо отдельных файлов).

Вы можете взглянуть на jnlp - на этом основан WebStart (это технология развертывания клиентских приложений), но я уверен, что он может быть адаптирован для выполнения обновлений для приложения типа сервера. Несмотря на это, jnlp выполняет довольно хорошую работу по предоставлению дескрипторов, которые могут быть использованы для загрузки требуемых версий требуемых JAR...

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

  • Рассмотрите наличие файла bootstrap.jar, который способен считывать файл jnlp и загружать необходимые/обновленные банки перед запуском приложения.

  • Файлы JAR могут быть обновлены даже во время работы приложения (по крайней мере, в Windows, и это ОС, скорее всего, будет содержать блокировки при запуске файлов). Вы можете столкнуться с проблемами, если используете пользовательские загрузчики классов, или у вас есть куча JAR, которые могут быть загружены или выгружены в любое время, но если вы создадите механизмы для предотвращения этого, то перезаписывание JAR, а затем повторное запуск приложения должно быть достаточно для обновления.

  • Несмотря на то, что можно перезаписать JAR, вам может потребоваться подход ping-pong для вашего пути к lib (если у вас еще нет приложения, которое настроено для автоматического чтения всех файлов jar в lib и автоматически добавить их в путь к классу, а затем то, что вы действительно хотите сделать). Вот как работает пинг-понг:

Приложение запускает и просматривает файлы lib-ping\version.properties и lib-pong\version.properties и определяет, что является более новым. Скажем, что lib-ping имеет более позднюю версию. Launcher ищет lib-ping *.jar и добавляет эти файлы в CP во время запуска. Когда вы делаете обновление, вы загружаете файлы jar в lib-pong (или копируете файлы jar из lib-ping, если вы хотите сохранить пропускную способность, и JAR фактически не изменился - это редко стоит усилий!). После того, как все JAR файлы скопированы в lib-pong, самое последнее, что вы делаете, это создать файл version.properties(таким образом может быть обнаружено и очищено прерывистое обновление, которое приводит к частичной папке lib). Наконец, вы снова запускаете приложение, и bootstrap выбирает, что lib-pong - это нужный путь к классам.

  1. Пинг-понг, как описано выше, позволяет откатить. Если вы правильно его разработали, вы можете использовать одну часть своего приложения, из которой вы проверите heck, а затем никогда не меняете эти проверки, чтобы проверить, следует ли откатываться от данной версии. Таким образом, если вы испортите и разворачиваете то, что нарушает приложение, вы можете аннулировать версию. Эта часть приложения просто должна удалить файл version.properties из плохой папки lib- *, а затем перезапустить. Важно сохранить эту часть грязи простой, потому что она безопасна для вас.

  2. У вас может быть более 2 папок (вместо ping/pong, просто используйте lib-yyyymmdd и очистите все, кроме новейших 5, например). Это позволяет более продвинутый (но более сложный!) Откат JAR.

Ответ 2

Вы обязательно должны взглянуть на OSGi, он был создан именно для этих случаев (особенно для встроенных продуктов) и используется большим количеством компаний. Вы можете обновлять "пакеты" jar, добавлять и удалять их, пока приложение запущено. Я не использовал его сам, поэтому я не знаю о качестве фреймворков/серверов с открытым исходным кодом, но вот куча полезных ссылок, чтобы начать:

http://www.osgi.org/Main/HomePage
http://www.aqute.biz/Code/Bnd
http://blog.springsource.com/2008/02/18/creating-osgi-bundles/
http://blog.springsource.com/
http://www.knopflerfish.org/
http://felix.apache.org/site/index.html

Ответ 3

Я бы рекомендовал Capistrano для многосерверного развертывания. Хотя он создан для развертывания приложений Rails, я видел, что он успешно использовался для развертывания приложений Java.

Ссылка: Capistrano 2.0 Не только для Rails

Ответ 4

Jars нельзя изменить, пока JVM работает поверх него и приведет к ошибкам. Я пробовал аналогичные задачи, и лучше всего я придумал сделать копию обновленного Jar и перенести запуск script, чтобы посмотреть на этот Jar. После того, как у вас есть обновленный Jar, запустите его и подождите, пока старый Jar закончится, после того, как он даст сигнал. К сожалению, это означает потерю графического интерфейса и т.д. В течение секунды, но сериализация большинства структур в Java просто, и текущий графический интерфейс может быть перенесен на обновленное приложение до фактического закрытия (некоторые вещи могут не быть сериализуемыми, хотя!).

Ответ 5

Очень сложно сделать обновление атомарным, особенно если у вас есть обновление базы данных.

Но, если вы этого не сделаете, вы можете сначала убедиться, что ваше приложение может работать с относительным путем. То есть вы можете поместить свое приложение в какой-то каталог, и все важные файлы будут найдены относительно этого местоположения, так что ваше фактическое место установки не очень важно.

Затем дублируйте свою установку. Теперь у вас есть "работающая" версия, и у вас есть "новая" версия.

Обновите "новую" версию, используя любую технику, которая вам нравится (FTP, rsync, бумажная лента, все, что плавает на вашей лодке).

Проверьте свою установку (контрольные суммы, быстрые модульные тесты, что вам нужно - даже запустите его на тестовом порту, если хотите).

Когда вы довольны новой установкой, в исходном исполняемом экземпляре, RENAME - исходный каталог (mv application application_old), переименуйте NEW-каталог (приложение mv application_new) и запустите его.

Время простоя сокращается до выключения сервера и времени запуска (поскольку rename является "бесплатным" ).

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

Другая приятная вещь: ваша инфраструктура обслуживания статична (например, ваши rc-скрипты, задания cron и т.д.), поскольку они указывают на каталог "приложение", и это не изменяется.

Это также можно сделать с помощью программных ссылок вместо переименования каталогов. в любом случае это нормально.

Но метод прост и почти пуленепробиваемый, если ваше приложение сотрудничает.

Теперь, если у вас есть изменения в БД, ну, это совершенно другая неприятная проблема. В идеале, если вы можете сделать изменения в базе данных "обратно совместимыми", то, надеюсь, старая версия приложения может работать на новой схеме, но это не всегда возможно.

Ответ 6

Я считаю, что вы можете развернуть JAR файлы, если используете сервер приложений на основе OSGi, например SpringSource dm Server. Я никогда не использовал его сам, но, зная общее качество портфеля Spring, я уверен, что это стоит посмотреть.

Ответ 7

Мы используем Eclipse, который обновляет систему OSGi, и наш опыт очень хорош.

Рекомендуем!

Ответ 8

Последняя версия Java Web Start позволяет вводить приложение в локальный кеш без фактического вызова программы и его можно пометить как "автономный". Поскольку кэш используется для вызова программы, он будет обновлен только для следующего запуска. Для этого вам, скорее всего, понадобятся банки с номерами версий в их имени (например, наша библиотека-2009-06-01.jar).