Каков наилучший способ управления данными конфигурации
Я работаю над набором продуктов, в котором есть 4 продукта. Прямо сейчас все данные конфигурации находятся либо в файлах XML, либо в файлах свойств. Этот подход не поддерживается, поскольку мы должны управлять другим конфигурационным файлом для разных сред (например, Production, Development и т.д.).
Итак, Каков наилучший способ обработки данных конфигурации?
Кроме того, можем ли мы модулировать это в отдельный модуль? Так что все продукты могут использовать этот модуль.
Мы не хотим использовать файлы свойств. Я ищу решение, в котором мы можем переместить весь код конфигурации в качестве нового модуля конфигурации и сохранить все данные конфигурации в базе данных.
Ответы
Ответ 1
Используя commons-configuration, у вас есть унифицированный API для доступа к свойствам, независимо от того, как они представлены -.properties, xml, JNDI, и т.д. Например:
config.properties
:
jdbcHost=192.168.12.35
jdbcUsername=dbuser
jdbcPassword=pass
config.xml
:
<config>
<jdbcHost>192.168.12.35</jdbcHost>
<jdbcUsername>dbuser</jdbcUsername>
<jdbcPassword>pass</jdbcPassword>
</config>
в обоих случаях они будут доступны с чем-то вроде:
String host = config.getString("jdbcHost");
Ответ 2
Вы почти там... Я бы придерживался того же подхода и вставлял правильный файл конфигурации для экземпляра приложения, которое работает по методу, аналогичному любому из следующих:
-
Поищите все ваши файлы конфигурации по-разному и попросите приложение применить их к некоторым уникальным критериям (имя пользователя, имя хоста и т.д.):
- производство.properties
- developer1.properties
- developer2.properties
-
Храните их вне кодовой базы в местоположении на основе переменной среды, которую предполагает приложение:
- YOURAPP_CONFIG_DIR/server_config.xml
- YOURAPP_CONFIG_DIR/database_config.properties
Я даже использовал комбинацию этих подходов в одном проекте (# 1 для конфигураций процесса сборки и # 2 для конфигураций времени исполнения).
Ответ 3
Если ваши приложения работают с базой данных, вы можете создать таблицу "Конфигурация" следующим образом:
create table configuration (mode char(3), key varchar(255), value varchar(1023));
Вы инициализируете его с помощью init script, скажем, init.sql с содержимым в строках:
insert into configuration values ('pro', 'param1', 'value1'); -- production
insert into configuration values ('dev', 'param1', 'value1'); -- development
insert into configuration values ('tst', 'param1', 'value1'); -- testing
...
Преимущества этого подхода заключаются в следующем:
- вы используете версию script вместе с
ваш код
- вы можете легко расширить его, включив
для каждого пользователя или для каждой группы
добавление идентификатора пользователя/группы
- вы можете изменить настройки в
если вам нужно это сделать
- вы можете использовать один и тот же стек (JPA +
DAO, Cayenne...), вы обычно используете для
обрабатывать данные приложения ядра
обрабатывать данные конфигурации
Ответ 4
Для всех наших сред данные конфигурации хранятся на целевых компьютерах в виде файлов свойств. Мы используем PropertyPlaceholderconfigurer из SpringFramework, чтобы привязать эти свойства к нашим приложениям, чтобы сохранить все переносимые среды.
Например, если я знаю, что /etc/myapp/database.properties будет присутствовать на какой-либо машине, на которой будет работать мое приложение, тогда в моей конфигурации spring мне просто нужно что-то вроде этого:
<bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/etc/myapp/database.properties</value>
</list>
</property>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://${db.host}:3306/${db.name}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.pass}" />
</bean>
В этом классе spring имеется множество опций о том, где могут находиться файлы свойств. Вы можете даже сделать их замену и передать их в качестве переменных среды:
<bean id="myPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>${database.configuration.file.url}</value>
</list>
</property>
</bean>
И в bash_profile (или что-то еще):
export JAVA_OPTS = "-Ddatabase.configuration.file.url = файл:///etc/myapp/database.properties"
Или просто тот же параметр -D передается, когда вы вызываете "java" в зависимости от того, что вы делаете.
FWIW, мы сохраняем наши файлы свойств отдельно как RPM.
Ответ 5
Существует множество различных стратегий. Все они хороши и зависят от того, что вам лучше всего.
- Создайте один артефакт и разворачивайте конфигурацию в отдельном месте. Артефакт может иметь переменные-заполнители и при развертывании может быть прочитан конфиг. Посмотрите на местозаполнитель свойств Springs. Он работает фантастически для webapps, которые используют Spring и не связаны с привлечением ops.
- Имейте внешний файл конфигурации, который живет за пределами webapp. Держите место постоянным и всегда читайте из конфигурации свойств. Обновите конфигурацию на любом этапе и перезапустите новые значения.
- Если вы изменяете среду (например, сервер приложений или пользовательские/групповые разрешения), посмотрите на использование вышеуказанных методов с марионеткой или шеф-поваром. Также рассмотрите управление файлами конфигурации с помощью этих инструментов.
Ответ 6
Переменные окружения - это самый простой способ. Установите их так же, как и в любое другое время, и получите доступ к ним w/System.getenv("...")
Ответ 7
Вот держите простое глупое решение.
Фрагмент кода, который сначала пытается использовать файл свойств в текущем каталоге. В противном случае используйте файл свойств в каталоге ресурсов (или в файле jar).
Properties configFile = new Properties();
try {
configFile.load(new FileInputStream("production.properties"));
} catch (Exception e) {
System.err.println("Can not read properties, try to use default properties file.");
configFile.load(this.getClass().getClassLoader().
getResourceAsStream("development.properties"));
}