Обработка файлов конфигурации в веб-приложениях Spring

Я несколько раз сталкивался с одной и той же проблемой, и я хотел бы внести свой вклад в то, что другие люди думают об этой проблеме: Предположим, что у нас есть Spring приложение, упакованное как файл .war, и мы хотим запустить его в нескольких средах. (Разработка/испытание/preprod/Prod/и т.д.)

Для доступа к инфраструктуре, необходимой для приложения (базы данных/веб-сервисы и т.д.), мы сохраняем информацию о доступе в файлах конфигурации, а также некоторые бизнес-конфигурации находятся в этих файлах. Скажем, для этой цели мы используем файлы .properties (поскольку во время войны у нас есть приложение Spring, и нам нравится иметь свойства, считанные одним слоем в appcontext)  а также предположим, что в разных средах у нас нет того же контейнера appserver/servlet. (например: dev, test: jetty, preprod: tomcat, prod: glassfish)

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

Недавно я столкнулся с вопросом от парня, который работал: "Итак, действительно ли нам нужно создать новую сборку с соответствующим профилем на сервере-сборщике, если база данных будет изменена в среде preprod?" Я ответил: "Нет, вы действительно можете перейти на... /webapps/currentApp/WEB -INF/classes/config/application.properties и изменить там значения, а затем перезапустить контейнер

Мы придумали решение, которое решает некоторые аспекты этой проблемы: используя плагин сборки Maven, мы внедряем Jetty внутри войны, что делает его пригодным для использования в качестве "исполняемой" войны, а также дает нам возможность иметь глобальную конфигурацию XML, из которого стартер встроенного Jetty создает/изменяет соответствующие файлы .properties в взорванном военном каталоге и только затем запускает приложение.

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

Как все имеют дело с одной и той же ситуацией?

Ответ 1

Переменная среды, внешние файлы конфигурации

У нас есть нечто похожее, веб-приложение, работающее в Tomcat/Weblogic с Spring. Что мы делаем, это определить свойство свойство среды CONFIG_PATH и поместить все XML файлы (включая spring config) и файлы свойств в этот каталог.

У нас есть несколько файлов свойств (для каждой среды), которые мы отправляем как tar файл. Веб-приложение загружает все конфигурационные файлы Properties/ Spring из каталога CONFIG_PATH. Эта переменная определяется как переменная среды в соответствующей среде

Таким образом, мы не касаемся WAR файла и не создаем отдельную WAR для среды. Подумайте об этом сценарии: созданные QA и PROD WAR файлы, проверенные QA файлы War QA, PROD WAR, развернутые в PROD, но что-то взрывается: (

Мы делаем что-то, как показано ниже:

В spring config xml мы определяем:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="order" value="0"></property>
    <property name="locations">
        <list>
            <value>file:${CONFIG_PATH}/App.properties</value>
        </list>
    </property>
</bean>

Обратитесь ко всем переменным, как обычно, в spring config.

В web.xml мы определяем конфигурацию spring следующим образом:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>file:${CONFIG_PATH}/**/spring-config.xml
    </param-value>
</context-param>

Команда QA/PROD развертывает один и тот же артефакт с соответствующими файлами среды. Если что-то взрывается, мы знаем его только env. свойства, которые перепутались. НТН

Ответ 2

База данных

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

Те не требуют переупаковки, перераспределения или отказов сервера. Приложению иногда нужно обновлять конфигурацию только для чтения.

JNDI

Параметры JNDI остаются фиксированными из среды в среду; эти изменения устанавливаются один раз администратором сервера приложений и не изменяются. (См. Учебник Oracle)

Я говорю о парах имя/значение для настройки для самого приложения, а не JNDI.

Ответ 3

Для источников данных; это общий подход в контексте tomcat, чтобы создать запись ресурса JNDI и отделить ваши записи/конфигурации ресурсов от вашего приложения. Если DB изменен, вы можете перенастроить свой ресурс JNDI в своем контейнере (Tomcat, Jetty и т.д.) И перезапустить. Если у вас есть контейнерная ферма, то не будет проблемы с перезагрузкой экземпляров tomcat. вы можете деактивировать их на балансировщике нагрузки и перезапустить, повторно активировать. Я думаю, что есть файл контекста в Jetty, в котором вы можете добавить ресурсы JNDI. Кроме того, существуют профили maven для свойств, которые зависят от разных контекстов. вы можете выбрать свой профиль с параметром "-P" maven, и ваш проект будет построен с этими конфигурациями, например, для разных целевых контекстов, таких как live и test.