2009-02-24 4 views
15

В настоящее время я работаю над проектом j2ee, который был в бета-версии некоторое время. Сейчас мы просто избиваем некоторые проблемы с процессом развертывания. В частности, существует множество файлов, встроенных в войну (некоторые xml-файлы и .properties), которые требуют развертывания разных версий в зависимости от того, находитесь ли вы в среде разработчика, тестирования или производства. Такие вещи, как loglevels, пулы соединений и т. Д.Как управлять встроенными конфигурационными файлами и библиотеками в java webapps?

Так что мне было интересно, как разработчики здесь структурируют свой процесс развертывания webapps. Вы разгружаете как можно больше конфигурации на сервер приложений? Вы программно заменяете файлы настроек перед развертыванием? Выберите версию во время процесса сборки? Вручную отредактировать войны?

Также как вы занимаетесь предоставлением зависимостей через статические библиотеки серверов приложений и сколько вы сами ввели в войну? Все это просто для того, чтобы получить некоторые идеи о том, какова общая (или, возможно, лучшая) практика на данный момент.

ответ

6

Я работаю в среде, где отдельная команда сервера выполняет конфигурацию серверов контроля качества и производства для наших приложений. Каждое приложение обычно развертывается на двух серверах в QA и трех серверах в Production. Моя команда разработчиков обнаружила, что лучше всего минимизировать требуемую конфигурацию на сервере, поставив как можно большую конфигурацию в войне (или ухе). Это упрощает настройку сервера и минимизирует вероятность того, что команда сервера неправильно настроит сервер.

У нас нет конфигурации, характерной для машины, но у нас есть конфигурация, специфичная для среды (Dev, QA и Production). У нас есть файлы конфигурации, хранящиеся в военном файле, которые называются средой (например, dev.properties, qa.properties, prod.properties). Мы помещаем свойство -D в командную строку Java Java сервера, чтобы указать среду (например, java -Dapp.env = prod ...). Приложение может искать системное свойство app.env и использовать его для определения имени используемого файла свойств.

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

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

+0

Большинство ответов касательно того, чтобы сказать то же самое, принимая это, так как мы, вероятно, закончим что-то очень похожее. – wds

8

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

Что мне нравится делать, это построить проект с файлом properties.example, каждая машина имеет .properties, которая живет где-то, когда война может получить к ней доступ.

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

0

Я поместил всю конфигурацию в базу данных. Контейнер (Tomcat, WebSphere и т. Д.) Дает мне доступ к исходному соединению с базой данных, и с этого момента все выходит из базы данных. Это позволяет использовать несколько сред, кластеров и динамических изменений без простоев (или, по крайней мере, без повторного развертывания). Особенно приятным является возможность изменения уровня журнала на лету (хотя вам потребуется либо экран администратора, либо обновить фон, чтобы поднять изменения). Очевидно, что это работает только для вещей, которые не требуются для запуска приложения, но, как правило, вы можете быстро добраться до базы данных после запуска.

2

Я обычно делаю два свойства файла:

  • один для специфических приложений (сообщения, внутренние «волшебные» слова), встроенных в приложение,
  • другой конкретики среды (доступ к БД, уровни & войти пути ...), отображаемые на пути каждого класса к классу и «прикрепленные» (не поставляемые вместе с моим приложением). Обычно я «mavenise» или «anttise» эти, чтобы поставить конкретные значения, в зависимости от целевого env.
  • Прохладные ребята используют JMX для поддержки своего приложения conf (conf может быть изменен в реальном времени, без перераспределения), но он слишком сложный для моих нужд.

(статическая?) Библиотека-сервера: Я настоятельно не рекомендую использовать библиотеку сервера в своих приложениях, поскольку это добавляет зависимость к серверу:

  1. ИМО, мое приложение должно быть «сам-упаковывают»: сбросив мой войны, и все. Я видел войны с 20 Мб банок в нем, и это не беспокоит меня.
  2. Общей практикой является ограничение ваших внешних зависимостей от того, что предлагается догмой J2EE: J2EE API (использование сервлетов, Ejbs, Jndi, JMX, JMS ...). Ваше приложение должно быть «агностиком сервера».
  3. Включение зависимостей в ваше приложение (война, ухо, наблюдатель) самодокументируется: вы знаете, от каких библиотек зависит ваше приложение. С серверами libs вы должны четко документировать эти зависимости, поскольку они менее очевидны (и вскоре ваши разработчики забудут эту маленькую магию).
  4. Если вы обновляете свой сервер приложений, вероятность того, что зависит от вас, зависит и от сервера lib. Редакторы AppServer не должны поддерживать совместимость в своих внутренних libs от версии к версии (и большую часть времени они этого не делают).
  5. Если вы используете широко распространенную lib, встроенную в ваш appServer (jararta commons logging, aka jcl, придет на ум) и хотите, чтобы версия угасла, чтобы получить последние функции, вы рискуете, что ваш appServer не будет поддерживать Это.
  6. Если вы полагаетесь на статический объект сервера (в статическом поле класса сервера, например, на карте или в журнале), вам необходимо перезагрузить ваш сервер приложений для очистки этого объекта. Вы теряете возможность горячего повторного развертывания своего приложения (старый серверный объект все еще существует между перераспределениями). Использование объектов allSphereServer (кроме тех, которые определены J2EE) может привести к тонким ошибкам, особенно если этот объект используется совместно несколькими приложениями. Вот почему я категорически не рекомендую использовать объекты, которые находятся в статическом поле appServer lib.

Если вы абсолютно необходимо «этот объект в банке этого Appserver в» попытке скопировать банку в вашем приложении, надеясь, что нет зависимости от кувшина другого сервера, и проверка политики загрузки классов вашего приложения (я беру привычку ставить «политика родительского последнего класса» для всех моих приложений: я уверен, что я не буду «загрязнен» банками сервера, но я не знаю, является ли это «лучшей практикой»).

4

wrt файлы конфигурации, я думаю, Steve's ответ самый лучший. Я бы добавил предложение сделать внешние файлы относительно пути установки военного файла - таким образом, вы можете иметь несколько установок войны на одном сервере с различными конфигурациями.

например.Если мой dev.war распакуется в /opt/tomcat/webapps/dev, я бы воспользовался ServletContext.getRealPath, чтобы найти базовую папку и имя папки войны, поэтому файлы конфигурации будут жить в ../../config/dev относительно войны или /opt/tomcat/config/dev для абсолютного.

Я также согласен с Bill о размещении как можно меньше в этих файлах внешней конфигурации. Использование базы данных или JMX в зависимости от вашей среды для хранения, насколько это имеет смысл. Конфигурация Apache Commons имеет nice object для обработки конфигураций, поддерживаемых таблицей базы данных.

Что касается библиотек, я согласен с unknown, чтобы иметь все библиотеки в папке WEB-INF/lib в файле войны (самораспаковывающийся). Преимущество состоит в том, что каждая установка приложения является автономной, и вы можете иметь разные сборки войны, используя одновременно разные версии библиотек.

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

Если это представляет серьезную проблему, вы можете поместить банки в общую папку библиотеки для своего контейнера сервлетов ($CATALINA_HOME/lib для tomcat). Однако все установки вашего веб-приложения, работающие на одном сервере, должны использовать одни и те же версии библиотек. (На самом деле, это не совсем так, как если бы вы могли поместить переопределенные версии в папку WEB-INF/lib, если это необходимо, но это становится довольно беспорядочным для поддержания.)

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