Архитектура микросервиса соответствует Приложению Двенадцати Факторов (12factor.net). В соответствии с принципом 12 факторов рекомендуется, чтобы конфигурации приложения были отделены от исполняемого приложения. Внешние конфигурации не только предоставляют исполняемые файлы, не зависящие от среды, но также обеспечивают простой и безопасный способ управления конфигурациями во время выполнения без увеличения времени простоя.
Microsoft Azure предоставляет аналогичную функциональность через службу конфигурации приложений, которую можно легко интегрировать с приложением Spring Boot. С помощью этой службы конфигурации приложений разработчики могут экспортировать все настраиваемые параметры своего приложения в приложение Azure.
Вся задача по экстернализации настраиваемых параметров приложения через службу приложений Azure разделена на три подзадачи, как показано ниже, которые будут подробно рассмотрены в последующих разделах.
- Действия, необходимые для конфигурации приложений Azure.
- Требуемые конфигурации в приложении микросервиса.
- Варианты использования для доступа к параметрам в компоненте приложения.
1. Действия, необходимые для настройки приложения Azure
Первый шаг — создать ресурс «Конфигурация приложения» на веб-портале Azure. После этого можно добавить все настраиваемые параметры в эту App-Configuration.
Если мы хотим включить или выключить какую-либо функциональность в приложении, мы также можем создать флаг функции, чтобы воспользоваться этим.
Пожалуйста, выполните следующие шаги для настройки, упомянутой выше.
Шаг 1. Создайте учетную запись в Azure DevOps. Создайте ресурс конфигурации приложения.
Шаг 2. Добавьте новые конфигурации в ресурс конфигурации приложения.
Шаг 3. Добавьте новый флаг функции в ресурс конфигурации приложения.
Шаг 4. Перейдите в раздел «Ключи доступа» и скопируйте значение строки подключения, которое будет использоваться в конфигурации Spring Boot.
Предупреждение. Приведенные выше экраны соответствуют текущему пользовательскому интерфейсу портала Azure. (Пожалуйста, следуйте ресурсу Azure для получения последних изменений здесь: https://learn.microsoft.com/en-us/azure/azure-app-configuration/)
2. Требуемые конфигурации в микросервисном приложении
После настройки всех настраиваемых параметров в облаке Azure вторым шагом является настройка приложения Spring Boot для подключения к приложению Azure и получение конфигураций при запуске сервера.
Обратите внимание, что параметры подключения и необходимые конфигурации ключей должны быть добавлены в bootstrap.yml
.
Давайте пройдемся по шагам ниже:
Шаг 1:добавьте следующие зависимости в build.gradle
.
dependencies { implementation 'com.azure.spring:spring-cloud-azure-appconfiguration-config-web:5.2.0' implementation 'com.azure.spring:spring-cloud-azure-feature-management-web:5.2.0' implementation 'com.azure:azure-sdk-bom:1.2.13' implementation 'com.azure:azure-data-appconfiguration:1.4.5' }
Шаг 2. Добавьте сведения о подключении и конфигурации в bootstrap.yml
.
connection-string
: вы бы скопировали с портала, как указано в предыдущих шагах.key-filter
:ключевой фильтр — это ключ, который вы присвоили своему настраиваемому параметру. (например, «screenConfigurations» — это ключ, используемый в приведенном выше примере), значения с этими ключами будут извлечены из облака.label-filter
: чтобы разделить одно и то же свойство для разных сред.
spring: cloud: azure: appconfiguration: stores: - connection-string: Endpoint=https://xyz.azconfig.io;Id=****;Secret=************* selects: - key-filter: screenConfigurations label-filter: dev - key-filter: filterKey label-filter: dev feature-flags: enabled: true label-filter: dev
Шаг 3.Это необязательная конфигурация. Это требуется только тогда, когда вы хотите получить доступ к настраиваемым параметрам через аннотацию @ConfigurationProperties
.
Аннотируйте пилотный класс вашего приложения Spring Boot с помощью аннотаций @ConfigurationPropertiesScan
и @EnableConfigurationProperties
.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.boot.context.properties.EnableConfigurationProperties; @ConfigurationPropertiesScan @EnableConfigurationProperties @SpringBootApplication public class AppConfig { public static void main(String[] args) { SpringApplication.run(AppConfig.class, args); } }
3. Варианты использования для доступа к параметрам в компоненте приложения
После завершения описанных выше разделов 1 и 2 ваше приложение будет готово к чтению настраиваемых параметров с помощью различных конструкций, предоставляемых Spring Boot, таких как аннотации @Value
или @ConfigurationProperties
.
Теперь давайте рассмотрим различные варианты использования для доступа к значениям параметров и флагам функций в нашем приложении.
Вариант использования 1.Доступ к значениям конфигурации с помощью аннотации @Value
и класса @ConfigurationProperties
Учтите, что у вас разные экраны в ваших приложениях. Каждый экран имеет два свойства: «включен» и «размерен». И вы настроили его значения как JSON в конфигурации приложения Azure, используя ключ «screenConfigurations
» (упомянутый выше вbootstrap.yml
), и его значение JSON выглядит следующим образом:
{ "screens": [ { "gymRegistration": { "enabled": true, "sizeable": false } }, { "libraryRegistration": { "enabled": true, "sizeable": false } } ] }
Приложение будет получать вышеуказанные свойства при запуске сервера и сопоставлять с классом «ScreenProperties.java
», который помечен @ConfigurationProperties
, как показано ниже:
import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; import lombok.Data; @ConfigurationProperties @Data public class ScreenProperties { private Map<String, Map<String, Screen>> screens; public static record Screen (boolean enabled, boolean sizeable){ } }
На всякий случай, чтобы получить доступ к отдельному свойству непосредственно в компоненте, можно использовать аннотацию @value
с именем ключа, как указано ниже.
import java.net.MalformedURLException; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(Constant.RESOURCE_PATH_PROPERTY) public class PropertyController { @Value("${.screens[0].gymRegistration.enabled}") private String isGymRegistrationEnabled; private ScreenProperties screenproperties; public PropertyController(ScreenProperties screenProperties) { this.screenProperties = screenProperties; } @GetMapping(value= {"printProperties"}) public String printProperties() throws MalformedURLException { System.out.println("Single property via @Value annotation : "+ isGymRegistrationEnabled); System.out.println("All properties via @ConfigurationProperties annotation : "+ screenProperties.toString()); } }
Пример использования 2. Включение/отключение функции с помощью флага функции.
Флаг функции используется для включения или отключения определенных функций путем устранения стандартного кодирования.
Его значение извлекается из cloud-config каждые 30 секунд (значение по умолчанию, которое можно изменить), чтобы его можно было переключать во время выполнения без остановки нашего приложения.
В приведенном ниже примере я переключаю возвращаемое значение (которое находится в форме строки) метода на основе значения флага функции.
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.azure.spring.cloud.feature.management.FeatureManager; @RestController @RequestMapping(Constant.RESOURCE_PATH_FEATUE) public class FeatureController { private FeatureManager featureManager; public FeatureController(FeatureManager featureManager) { this.featureManager = featureManager; } @Value("${cloud.config.feature.testFeatureFlag}") private String testFeatureFlag; @GetMapping(value= {"/message/","/"}) public String getFeatureMessage() { featureManager.getAllFeatureNames().forEach(System.out::println); return (featureManager.getAllFeatureNames().contains(biometricFeatureName)) ? (featureManager.isEnabled(biometricFeatureName)) ? "Hey, feature flag is enabled" : "Ooops, feature flag is disabled" : "Ooops, feature flag is not available in the system" ; } }
Вариант использования 3: операции CRUD для конфигураций через Spring Boot
Чтобы выполнить операцию CRUD для настраиваемых параметров, Azure предоставляет пакеты SDK.
Мы можем использовать «ConfigurationClient.class
» для выполнения различных операций CRUD, как указано ниже:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.azure.core.http.rest.PagedIterable; import com.azure.data.appconfiguration.ConfigurationClient; import com.azure.data.appconfiguration.ConfigurationClientBuilder; import com.azure.data.appconfiguration.models.ConfigurationSetting; import com.azure.data.appconfiguration.models.SettingSelector; @Service public class ConfigServiceImpl implements ConfigService{ @Value("${spring.cloud.azure.appconfiguration.stores[0].connection-string}") private String connectionString; private ConfigurationClient getConfigClient(String connectionString) { return new ConfigurationClientBuilder().connectionString(connectionString).buildClient(); } /* * Method to fetch all the configured properties from cloud. */ @Override public String fetchCloudConfigurations() { PagedIterable<ConfigurationSetting> configurationSettingList = getConfigClient(connectionString).listConfigurationSettings(new SettingSelector()); Iterator<ConfigurationSetting> iterator = configurationSettingList.iterator(); Map<String, String> map = new HashMap<String, String>(); while(iterator.hasNext()) { ConfigurationSetting setting = iterator.next(); System.out.println(String.format("[fetchCloudConfigurations] Key: %s, Value: %s", setting.getKey(), setting.getValue())); map.put(setting.getKey(), setting.getValue()); } return map.toString(); } /* * Method to create new property in app configuration. */ @Override public String createNewKeyValueInCloudConfig(Config config) { ConfigurationSetting setting = new ConfigurationSetting(); setting.setContentType(config.contentType()); setting.setKey(config.key()); setting.setLabel(config.label()); setting.setValue(config.value()); setting = getConfigClient(connectionString).addConfigurationSetting(setting); System.out.println(String.format("[createNewKeyValueInCloudConfig] Key: %s, Value: %s", setting.getKey(), setting.getValue())); return "Created"; } /* * Method to update value of existing property in app configuration. */ @Override public String UpdateExistingValueForGivenKeyInCloudConfig(Config config) { ConfigurationSetting setting = new ConfigurationSetting(); setting.setContentType(config.contentType()); setting.setKey(config.key()); setting.setLabel(config.label()); setting.setValue(config.value()); setting = getConfigClient(connectionString).setConfigurationSetting(setting); System.out.println(String.format("[UpdateExistingValueForGivenKeyInCloudConfig] Key: %s, Value: %s", setting.getKey(), setting.getValue())); return "Updated"; } /* * Method to remove particular configuration via its key from app. */ @Override public String removeExistingKeyValueFromCloudConfig(Config config) { ConfigurationSetting setting = getConfigClient(connectionString).deleteConfigurationSetting(config.key(), config.label()); System.out.println(String.format("[removeExistingKeyValueFromCloudConfig] Key: %s, Value: %s", setting.getKey(), setting.getValue())); return "Removed"; } }
Заключение
Вот и все, несколько простых шагов для интеграции приложения конфигурации Azure с приложением микрослужбы Spring Boot. Надеюсь, из этого можно извлечь что-то полезное, если вы хотите иметь внешнюю конфигурацию в своем приложении Spring Boot.
Удачи!