Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

Другие советы

Вам обязательно стоит взглянуть на 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

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

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

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

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

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

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

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

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

Когда вы будете довольны новой установкой, отключите исходный запущенный экземпляр, ПЕРЕИМЕНУЙТЕ исходный каталог (mv application application_old), переименуйте НОВЫЙ каталог (mv application_new application) и запустите его обратно.

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

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

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

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

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

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

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

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

Рекомендуется!

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top