Поделиться через


Поддержка конфигурации приложений

В этой статье описывается библиотека Spring Cloud Azure App Configuration. Эта библиотека загружает конфигурации и флаги компонентов из службы Конфигурация приложений Azure. Библиотека создает PropertySource абстракции для сопоставления абстракций, уже созданных средой Spring, таких как переменные среды, конфигурации командной строки, локальные файлы конфигурации конфигурации и т. д.

Spring — это платформа приложений с открытым кодом, разработанная компанией VMware. Она предлагает упрощенный модульный подход к созданию приложений Java. Spring Cloud Azure — это проект с открытым исходным кодом, который обеспечивает простую интеграцию Spring со службами Azure.

Предварительные условия

Настройка хранилища конфигурации приложений

Чтобы создать хранилище Конфигурация приложений Azure, используйте следующую команду:

az appconfig create \
    --resource-group <your-resource-group> \
    --name <name-of-your-new-store> \
    --sku Standard

Эта команда создает новое пустое хранилище конфигурации. Конфигурации можно отправить с помощью следующей команды импорта:

az appconfig kv import \
    --name <name-of-your-new-store> \
    --source file \
    --path <location-of-your-properties-file> \
    --format properties \
    --prefix /application/

Перед загрузкой проверьте конфигурации. Файлы YAML можно отправить, изменив формат на YAML. Поле префикса важно, так как это префикс по умолчанию, загруженный клиентской библиотекой.

Использование библиотеки

Чтобы использовать функцию в приложении, ее можно создать как приложение Spring Boot. Самый удобный способ добавления зависимостей — с помощью начального средства com.azure.spring:spring-cloud-azure-starter-appconfiguration-configSpring Boot. В следующем примере файла pom.xml используется Конфигурация приложений Azure:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>{spring-boot-version}</version>
    <relativePath />
</parent>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-dependencies</artifactId>
      <version>6.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-appconfiguration-config</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
    </plugins>
</build>

В следующем примере показано базовое приложение Spring Boot, использующее Конфигурацию приложений.

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

В этом примере файл application.properties содержит следующую строку:

spring.config.import=azureAppConfiguration
spring.cloud.azure.appconfiguration.stores[0].endpoint=${CONFIG_STORE_ENDPOINT}

CONFIG_STORE_ENDPOINT — это переменная среды с URL-адресом конечной точки в Хранилище конфигурации приложений Azure.

Примечание.

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

По умолчанию, если конфигурации не заданы, загружаются конфигурации, начинающиеся с /application/, с меткой (No Label) по умолчанию, если только не задан профиль Spring, в этом случае метка по умолчанию — это ваш профиль Spring.

Источник свойств под названием /application/https://<name-of-your-store>.azconfig.io/ создается, содержащий свойства этого хранилища. Метка, используемая в запросе, добавляется в конец имени. Если метка не задана, символ \0 присутствует в виде пустого пространства.

Загрузка конфигурации

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

spring.cloud.azure.appconfiguration.stores[0].endpoint=[first-store-endpoint]
spring.cloud.azure.appconfiguration.stores[1].endpoint=[second-store-endpoint]

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

Примечание.

Вы можете использовать параметры конфигурации приложений Azure как любую другую конфигурацию Spring. Дополнительные сведения см. в основных функциях документации по Spring Boot или в Кратком Руководстве по созданию приложения Java Spring с помощью Конфигурации приложений Azure.

Выбор конфигураций

Библиотека загружает конфигурации с помощью ключа и метки. По умолчанию загружаются конфигурации, начинающиеся с ключа /application/ . Метка \0по умолчанию отображается как (No Label) на портале Azure. Если задан профиль Spring, и метка не указана, метка по умолчанию — это профиль Spring, который является ${spring.profiles.active}.

Конфигурации можно настроить, выбрав различные фильтры ключей и меток:

spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter=[my-key]
spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=[my-label]

Свойство key-filter поддерживает следующие фильтры:

Фильтр ключей Действие
* Соответствует любому ключу.
abc Соответствует ключу с именем abc.
abc* Соответствует именам ключей, начинающимся с abc.
abc,xyz Соответствует именам ключей abc или xyz. Ограничено пятью разделенными запятыми значениями.

Свойство label-filter поддерживает следующие фильтры:

Этикетка Описание
* Соответствует любой метки, включая \0.
\0 Совпадает с метками null, которые отображаются в портале Azure (No Label).
1.0.0 Точно соответствует метки 1.0.0 .
1.0.* Соответствует меткам, начинающимся с 1.0.*.
,1.0.0 Соответствует меткам null и 1.0.0. Ограничено пятью разделенными запятыми значениями.

Если вы используете YAML с фильтрами меток и хотите загрузить конфигурации без меток и дополнительных конфигураций с другими метками, необходимо включить пустое ,. Например, ,dev совпадения \0 и dev. В этом случае заключите фильтр меток одними кавычками. Это значение позволяет загружать конфигурацию без меток, а затем конфигурации с определенными метками в том же фильтре:

spring:
  cloud:
    azure:
      appconfiguration:
        stores:
        - selects:
          - label-filter: ',1.0.0'

Примечание.

Нельзя сочетать * с , фильтрами. В этом случае необходимо использовать дополнительное значение выбора.

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

Профили Spring

spring.profiles.active по умолчанию установлен как label-filter для всех выбранных конфигураций. Эту функцию можно переопределить с помощью label-filter. Вы можете использовать профили Spring в label-filter, применяя ${spring.profiles.active}, как показано в следующем примере:

spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=,${spring.profiles.active}
spring.cloud.azure.appconfiguration.stores[0].selects[1].label-filter=${spring.profiles.active}_local

Во-первых label-filter, библиотека сначала загружает все конфигурации с \0 меткой, а затем все конфигурации, соответствующие Spring Profiles. Spring Profiles имеют приоритет над \0 конфигурациями, потому что они в конце.

Во-вторых label-filter, строка _local добавляется к концу Spring Profile, хотя только к последнему spring Profile, если существует несколько.

Отключенные магазины

С помощью конфигурации spring.cloud.azure.appconfiguration.enabledможно отключить загрузку для всех хранилищ конфигураций. spring.cloud.azure.appconfiguration.stores[0].enabled С помощью конфигурации можно отключить отдельное хранилище.

Примечание.

Если вы используете метрики здоровья, вы всё равно увидите свои магазины в списке, но со значением NOT LOADED. При проверке загруженных источников свойств они по-прежнему отображаются, но они не содержат значений. Это поведение связано с заданным свойством spring.config.import . Если azureAppConfiguration не задано для spring.config.import, значения не отображаются.

Проверка подлинности

Библиотека поддерживает все формы удостоверений, которые поддерживаются библиотекой Azure Identity Library. Вы можете осуществить аутентификацию с помощью конфигурации для строк подключения и управляемого удостоверения.

Примечание.

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

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

az appconfig credential list --name <name-of-your-store>

Затем вы можете задать свойство spring.cloud.azure.appconfiguration.stores[0].connection-string на строку подключения. При использовании этого подхода настоятельно рекомендуется задать строку подключения в локальном файле конфигурации значение заполнителя, которое сопоставляется с переменной среды. Этот подход позволяет избежать добавления строки подключения в систему контроля версий.

Конфигурация Spring Cloud Azure

Для настройки библиотеки можно использовать конфигурацию Spring Cloud Azure. Для настройки библиотеки можно использовать следующие свойства:

spring.cloud.azure.appconfiguration.stores[0].endpoint= <URI-of-your-configuration-store>

Если задана только конечная точка, клиентская библиотека использует DefaultAzureCredential для проверки подлинности.

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

az role assignment create \
    --role "App Configuration Data Reader" \
    --assignee <your-client-ID> \
    --scope /subscriptions/<your-subscription>/resourceGroups/<your-stores-resource-group>/providers/Microsoft.AppConfiguration/configurationStores/<name-of-your-configuration-store>

Примечание.

Вы можете определить только один метод проверки подлинности для каждой конечной точки: строка подключения, назначенное пользователем удостоверение или удостоверение токена. Если вам нужно смешивать и соответствовать, можно использовать ConfigurationClientCustomizer для изменения ConfigurationClientBuilder различных методов.

Примечание.

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

Георепликация

Библиотека поддерживает функцию георепликации Azure App Configuration. Эта функция позволяет реплицировать данные в другие локации. Эта функция полезна для обеспечения высокой доступности и аварийного восстановления.

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

По умолчанию библиотека автоматически обнаруживает все реплики, которые существуют для хранилища конфигурации. Когда запрос выполняется в предоставленное хранилище и завершается сбоем, библиотека автоматически повторяет запрос на доступные реплики.

Отработка отказа может произойти, если библиотека наблюдает любое из следующих условий:

  • Получает ответы с недоступным кодом состояния службы (HTTP 500 или более поздней версии) из конечной точки.
  • Возникают проблемы с сетевым подключением.
  • Запросы ограничиваются (код состояния HTTP 429).

После возврата предоставленного хранилища библиотека автоматически повторяет запрос к предоставленному хранилищу.

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

spring.cloud.azure.appconfiguration.stores[0].endpoints[0]=[your primary store endpoint]
spring.cloud.azure.appconfiguration.stores[0].endpoints[1]=[your replica store endpoint]

или

spring.cloud.azure.appconfiguration.stores[0].connection-strings[0]=[your primary store connection string]
spring.cloud.azure.appconfiguration.stores[0].connection-strings[1]=[your replica store connection string]

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

Вы можете отключить репликацию с параметром spring.cloud.azure.appconfiguration.stores[0].replica-discovery-enabled=false.

Создание хранилища конфигурации с георепликацией

Чтобы создать реплику хранилища конфигурации, можно использовать Azure CLI или портал Azure. В следующем примере Azure CLI используется для создания реплики в регионе Восток США 2.

az appconfig replica create --location --name --store-name [--resource-group]

Ключевые значения

Конфигурация приложений Azure поддерживает несколько типов ключевых значений, некоторые из которых имеют специальные функции, встроенные в них. Azure App Configuration имеет встроенную поддержку типа контента JSON, плейсхолдеров Spring и ссылок Key Vault.

Заполнители

Библиотека поддерживает конфигурации с заполнителями среды в стиле ${}. При ссылке на ключ Azure App Configuration с использованием заполнителя, удалите префиксы из этой ссылки. Например, /application/config.message называется ${config.message}.

Примечание.

Префикс, который удаляется, соответствует значению spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter. Префикс, который обрезается, можно изменить, задав для параметра значение spring.cloud.azure.appconfiguration.stores[0].trim-key-prefix[0].

JSON (JavaScript Object Notation)

Конфигурации с типом application/json контента обрабатываются как объекты JSON. Эта функция позволяет сопоставить одну конфигурацию с сложным объектом внутри @ConfigurationProperties. Например, рассмотрим ключ /application/config.colors JSON со следующим значением:

{
 "Red": {
  "value": [255, 0, 0]
 },
 "Blue": {
  "value": [0, 255, 0]
 },
 "Green": {
  "value": [0, 0, 255]
 }
}

Этот ключ сопоставляется со следующим кодом:

@ConfigurationProperties(prefix = "config")
public class MyConfigurations {

    private Map<String, Color> colors;

}

Ссылки на Key Vault

Конфигурация приложений Azure и ее библиотеки поддерживают ссылки на секреты, хранящиеся в Key Vault. В Конфигурация приложений можно создать ключи со значениями, которые сопоставляют с секретами, хранящимися в Key Vault. Секреты остаются безопасными в Key Vault, но доступ к ним можно получить так же, как и к любой другой конфигурации при загрузке приложения.

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

Примечание.

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

Создание ссылок на Key Vault

Вы можете создать ссылку Key Vault в портале Azure, перейдя в раздел "Обозреватель конфигурации" и выбрав "Создать" и "Ссылку Key Vault". Затем можно выбрать секрет для ссылки из любого из хранилищ ключей, к к которых у вас есть доступ. Вы также можете создавать произвольные ссылки Key Vault на вкладке "Входные данные". В портал Azure введите допустимый универсальный код ресурса (URI).

Вы также можете создать ссылку на Key Vault с помощью Azure CLI, выполнив следующую команду:

az appconfig kv set-keyvault \
    --name <name-of-your-store> \
    --key <key-name> \
    --secret-identifier <URI-to-your-secret>

Вы можете создать любой секретный идентификатор с помощью Azure CLI. Идентификаторы секретов просто требуют формата {vault}/{collection}/{name}/{version?} , в котором раздел версии является необязательным.

Использование ссылок на Key Vault

Для настройки библиотеки можно использовать конфигурацию Spring Cloud Azure. Для подключения к Azure Key Vault можно использовать те же учетные данные, которые используются для подключения к Конфигурация приложений.

Вы также можете создать SecretClientCustomizer такой же способ, как и создать ConfigurationClientCustomizer собственный метод проверки подлинности.

Разрешение секретов, отличных от Key Vault

Библиотека конфигурации приложений предоставляет метод переопределения разрешения ссылок на хранилище ключей. Например, его можно использовать для локального разрешения секретов в среде разработки. Это разрешение выполняется с помощью KeyVaultSecretProvider. При KeyVaultSecretProviderуказании вызывается для каждой ссылки на хранилище ключей. Если getSecret возвращает значение, отличное от NULL, оно используется в качестве значения секрета. В противном случае ссылка на Key Vault разрешается обычно.

public class MySecretProvider implements KeyVaultSecretProvider {

    @Override
    public String getSecret(String uri) {
        ...
    }

}

Управление функциями

Управление функциями позволяет приложениям Spring Boot динамически получать доступ к содержимому. Управление функциями имеет различные функции, такие как следующие:

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

Флаги компонентов можно включить с помощью следующей конфигурации:

spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled= true

Включенные признаки функций загружаются в систему конфигурации Spring с префиксом feature-management. Вы также можете зарегистрировать флаги компонентов в локальном файле конфигурации. Дополнительные сведения см. в разделе объявлений флагов функций.

Проще всего использовать управление функциями с помощью spring-cloud-azure-feature-management библиотек и spring-cloud-azure-feature-management-web библиотек. Разница между двумя библиотеками заключается в том, что spring-cloud-azure-feature-management-web зависит от библиотек spring-web и spring-webmvc для добавления дополнительных функций, таких как шлюзы функций.

По умолчанию загружаются все флаги компонентов с \0 меткой, как и (No Label)при этом. Вы можете настроить флаги функций, которые загружаются, задав фильтр меток, как показано в следующем примере:

spring.cloud.azure.appconfiguration.stores[0].feature-flags.selects[0].key-filter=A*
spring.cloud.azure.appconfiguration.stores[0].feature-flags.selects[0].label-filter= dev

Основы управления функциями

Флаги функций

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

Фильтры функций

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

Библиотека управления функциями поставляется с четырьмя предопределенными фильтрами: AlwaysOnFilter, PercentageFilter, TimeWindowFilter и TargetingFilter.

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

Объявление флага функции

Библиотека управления функциями поддерживает конфигурацию приложений Azure вместе с application.yml или application.properties в качестве источников для флагов компонентов. Ниже приведен пример формата, используемого для настройки флагов функций в файле application.yml :

feature-management:
  feature_flags:
  - id: feature-t
    enabled: false
  - id: feature-u
    conditions:
      client_filters:
      - name: Random
  - id: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Wed, 01 May 2019 13:59:59 GMT"
          End: "Mon, 01 July 2019 00:00:00 GMT"

  - id: feature-w
    evaluate: false
    conditions:
      client_filters:
      - name: AlwaysOnFilter

В этом примере имеются следующие флаги функций:

  • feature-t задан как false. Этот параметр всегда возвращает значение флага функции.
  • feature-u используется с фильтрами функций. Эти фильтры определяются в свойстве enabled-for . В этом случае feature-u имеет один фильтр функций под названием Random, который не требует какой-либо конфигурации, поэтому требуется только свойство имени.
  • feature-v указывает фильтр признаков с именем TimeWindowFilter. В этот фильтр возможностей можно передать параметры для использования в качестве конфигурации. В этом примере параметр TimeWindowFilterпередает время начала и окончания, в течение которого функция активна.
  • feature-w используется для AlwaysOnFilter, который всегда вычисляется как true. Поле evaluate используется для остановки оценки фильтров компонентов и приводит к тому, что фильтр компонентов всегда возвращается false.

Оценка флагов функций

Библиотека spring-cloud-azure-feature-management предоставляет FeatureManager сведения о том, включен ли флаг функции. FeatureManager предоставляет асинхронный способ проверки состояния флага.

spring-cloud-azure-feature-management-web наряду с предоставлением FeatureManager содержит FeatureManagerSnapshot, который кэширует состояние ранее оцененных флагов функций в @RequestScope, чтобы гарантировать, что все запросы возвращают одно и то же значение. Кроме того, веб-библиотека предоставляет @FeatureGate, которая может блокировать или перенаправлять веб-запросы на разные конечные точки.

Проверка флага функции

FeatureManager— это @Bean, который можно @Autowired или внедрить в объекты типа @Component. FeatureManager имеет метод isEnabled , который при передаче имени флага компонента возвращает его состояние.

@Autowired
FeatureManager featureManager;

...

if (featureManager.isEnabled("feature-t")) {
    // Do Something
}

Примечание.

FeatureManager также имеет асинхронную версию isEnabled, которая называется isEnabledAsync.

Без настройки управления функциями или при отсутствии флага isEnabled функции всегда возвращается false. Если существующий флаг функции настроен с неизвестным фильтром функции, то FilterNotFoundException будет выброшено исключение. Вы можете изменить это поведение, чтобы вернуть false, настроив fail-fast на false. В следующей таблице описано fail-fast:

Имя Описание Обязательное поле По умолчанию.
spring.cloud.azure.feature.management.fail-fast Если возникает исключение, выбрасывается RuntimeException. Если для этого свойства задано значение false, то возвращается isEnabled вместо false. Нет true

Единственное различие между FeatureManagerSnapshot и FeatureManager — кэширование результатов в @RequestScope.

Шлюз компонентов

С помощью веб-библиотеки управления функциями можно требовать, чтобы данная функция была включена для выполнения конечной точки. Это требование можно настроить с помощью заметки @FeatureGate , как показано в следующем примере:

@GetMapping("/featureT")
@FeatureGate(feature = "feature-t")
@ResponseBody
public String featureT() {
    ...
}

Доступ к конечной точке featureT можно получить только в том случае, если включен параметр feature-t.

Обработка отключенных действий

Если конечная точка заблокирована, так как указанная функция отключена, DisabledFeaturesHandler вызывается. По умолчанию возвращается HTTP 404. Это поведение можно переопределить, реализуя DisabledFeaturesHandler, как показано в следующем примере:

@Component
public class MyDisabledFeaturesHandler implements DisabledFeaturesHandler {

    @Override
    public HttpServletResponse handleDisabledFeatures(HttpServletRequest request, HttpServletResponse response) {
        ...
        return response;
    }

}
Маршрутизация

Некоторые маршруты могут предоставлять возможности приложений, которые вставляются функциями. Если функция отключена, можно перенаправить эти маршруты в другую конечную точку, как показано в следующем примере:

@GetMapping("/featureT")
@FeatureGate(feature = "feature-t" fallback= "/oldEndpoint")
@ResponseBody
public String featureT() {
    ...
}

@GetMapping("/oldEndpoint")
@ResponseBody
public String oldEndpoint() {
    ...
}

Встроенные фильтры функций

Существует несколько фильтров функций, которые входят в spring-cloud-azure-feature-management пакет. Эти фильтры функций добавляются автоматически.

AlwaysOnFilter

Этот фильтр всегда возвращает true. Пример использования см. в разделе объявления флага функции.

Процентный фильтр

При каждом проверке оценка PercentageFilter может возвращать другой результат. Это несоответствие можно обойти с помощью FeatureManagementSnapshotкэша результата флага функции для каждого запроса.

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: PercentageFilter
        parameters:
          Value: 50

TimeWindowFilter (Фильтр TimeWindow)

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

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Wed, 01 May 2019 13:59:59 GMT"
          End: "Mon, 01 July 2019 00:00:00 GMT"

Этот фильтр также поддерживает повторяющиеся фильтры временных окон. Он поддерживает как ежедневные, так и еженедельные повторения, а также время истечения срока действия.

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Mon, 01 July 2019 00:00:00 GMT"
          End: "Mon, 01 July 2019 12:00:00 GMT"
          Recurrence:
            Pattern:
              Type: Weekly
              Interval: 1
              FirstDayOfWeek: Sunday
              DaysOfWeek:
              - Monday
              - Wednesday

Этот шаблон повторения происходит каждую неделю в понедельник и среду с 00:00:00 GMT до 12:00:00 GMT и не истекает.

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Mon, 01 July 2019 00:00:00 GMT"
          End: "Mon, 01 July 2019 12:00:00 GMT"
          Recurrence:
            Pattern:
              Type: Daily
              Interval: 2
            Range:
              Type: EndDate
              EndDate: "Fri, 15 Aug 2025 07:00:00 GMT"

Этот шаблон повторения происходит каждый день с 00:00:00 GMT до 12:00:00 GMT до даты окончания.

Фильтр таргетинга

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

  • Пользователь указан непосредственно в разделе пользователей.
  • Пользователь включен в процент участвующих в любом из групповых развертываний.
  • Пользователь попадает в процент развертывания по умолчанию.
feature-management:
  feature_flags:
  - name: target
    conditions:
      client_filters:
      - name: targetingFilter
        parameters:
          users:
          - Jeff
          - Alicia
          groups:
          - name: Ring0
            rollout-percentage: 100
          - name: Ring1
            rolloutPercentage: 100
          default-rollout-percentage: 50

Фильтры пользовательских функций

Создание настраиваемого фильтра функций позволяет включить функции на основе заданных критериев. Чтобы создать пользовательский фильтр компонентов, необходимо реализовать FeatureFilter интерфейс. FeatureFilter имеет один метод evaluate. Если функция указывает, что она может быть включена с помощью фильтра функций, вызывается метод evaluate. Если evaluate возвращается true, это означает, что эта функция должна быть включена. Если он возвращается false, он продолжает оценивать фильтры функций до тех пор, пока один из них не вернёт true. Если все фильтры возвращают false, то функция отключена.

Фильтры функций определяются как Spring Beans, поэтому они могут быть заданы либо как @Component, либо определены в @Configuration.

@Component("Random")
public class Random implements FeatureFilter {

    @Override
    public boolean evaluate(FeatureFilterEvaluationContext context) {
        double chance = Double.valueOf((String) context.getParameters().get("chance"));
        return Math.random() > chance / 100;
    }

}

Параметризованные фильтры компонентов

Некоторые фильтры функций требуют параметров, чтобы определить, следует ли включить функцию. Например, фильтр функций браузера может включить функцию для определенного набора браузеров. Возможно, вы хотите включить функцию для браузеров Microsoft Edge и Chrome, но не Firefox. Чтобы настроить эту ситуацию, можно разработать фильтр функций для ожидания параметров. Эти параметры будут указаны в конфигурации функций и коде и будут доступны через параметр FeatureFilterEvaluationContextevaluate. FeatureFilterEvaluationContext имеет свойство parameters, которое является Map<String, Object>.

Таргетинг

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

Ниже приведен пример прогрессивного развертывания для новой функции Beta:

  1. Отдельные пользователи Джефф и Алисия получают доступ к бета-версии.
  2. Другой пользователь, Марк, просит подключиться и его включают.
  3. Двадцать процентов пользователей из группы, известной как «Ring1», входят в бета-версию программы.
  4. Число пользователей Ring1, включенных в бета-версию, увеличено до 100 процентов.
  5. Пять процентов пользовательской базы включены в бета-версию.
  6. Процент развертывания вырос до 100 процентов, и функция полностью развернута.

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

Таргетинг в приложении

Пример веб-приложения, использующего фильтр функций целевого объекта, доступен в примере проекта.

Чтобы начать использовать TargetingFilter в приложении, необходимо добавить его как @Bean так же, как и любой другой фильтр функций. TargetingFilter зависит от @Bean для добавления в приложение TargetingContextAccessor. Компонент TargetingContextAccessor позволяет определить текущий TargetingContext, который будет использоваться для установления текущего идентификатора пользователя и групп, как показано в следующем примере:

public class MyTargetingContextAccessor implements TargetingContextAccessor {

    @Override
    public void configureTargetingContext(TargetingContext context) {
        context.setUserId("Jeff");
        ArrayList<String> groups = new ArrayList<String>();
        groups.add("Ring0");
        context.setGroups(groups);
    }

}

Параметры оценки целевой аудитории

Доступны параметры для настройки того, как выполняется оценка нацеливания в заданном TargetingFilter. При создании объекта TargetingEvaluationOptions можно задать необязательный параметр TargetingFilter.

    @Bean
    public TargetingFilter targetingFilter(MyTargetingContextAccessor contextAccessor) {
        return new TargetingFilter(contextAccessor, new TargetingEvaluationOptions().setIgnoreCase(true));
    }

Обновление конфигурации

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

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

Примечание.

Любая операция, которая изменяет ETag триггера мониторинга, вызывает обновление, например изменение типа контента.

spring:
  cloud:
    azure:
      appconfiguration:
        stores:
        - monitoring:
          enabled: true
          triggers:
          - key: [my-watched-key]
            label: [my-watched-label]

Чтобы активировать обновление конфигурации, измените значение ключа в хранилище конфигурации. Затем обновите один из ключей часов до нового значения. Это изменение активирует создание журнала. Например, изменение значения триггеров /application/config.message приводит к следующему сообщению журнала:

INFO 17496 --- [TaskScheduler-1] o.s.c.e.event.RefreshEventListener       : Refresh keys changed: [config.message]

После создания журнала приложение обновляет все элементы @Bean в области обновления.

Примечание.

По умолчанию @ConfigurationProperties в эту область включены аннотированные бобы.

Обновление по pull-механизму

Библиотеки конфигурации приложений Spring поддерживают возможность периодически проверять изменения в триггерах мониторинга с заданным интервалом обновления. По умолчанию интервал обновления имеет значение 30 секунд. После прохождения интервала обновления при попытке обновления все триггеры проверяются в указанном хранилище для внесения изменений. Любое изменение ключа приводит к перезагрузке. Так как библиотеки интегрируются с системой обновления Spring, все обновления перезагружают все конфигурации из всех хранилищ. Интервал обновления можно задать для любого интервала, превышающего 1 секунду. Поддерживаемые единицы интервала обновления: s, mhи d в секундах, минутах, часах и днях соответственно. В следующем примере интервал обновления устанавливается на 5 минут:

spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval= 5m

Автоматизированный

При использовании spring-cloud-azure-appconfiguration-config-web библиотеки приложение автоматически проверяет наличие обновления при каждом возникновении запроса сервлета, в частности ServletRequestHandledEvent. Наиболее распространенный способ отправки этого события — через запросы к конечным точкам по @RestController.

Руководство

В приложениях, использующих только spring-cloud-azure-appconfiguration-config, таких как консольные приложения, можно вручную активировать обновление, вызвав метод AppConfigurationRefreshrefreshConfiguration. AppConfigurationRefresh — это @Bean, который можно внедрить в любой @Component.

Кроме того, так как библиотека использует систему конфигурации Spring, активация обновления приводит к обновлению всех конфигураций, а не только перезагрузке из хранилища конфигураций приложений Azure.

Примечание.

Этот метод больше не рекомендуется, но в настоящее время поддерживается.

Вы можете настроить библиотеку spring-cloud-azure-appconfiguration-config-web для получения push-уведомлений из хранилища конфигурации приложений Azure для обновления значений конфигурации. Эту конфигурацию можно настроить с помощью веб-хука Azure Event Grid, который можно сконфигурировать для отправки уведомлений об изменениях для указанных ключей. Добавив библиотеку Spring Actuator в качестве зависимости, вы можете предоставлять конечные точки обновления конфигурации приложений. Существует две разные конечные точки: appconfiguration-refresh и appconfiguration-refresh-bus. Эти конечные точки работают аналогично их аналогам refresh и refresh-bus, где точки конфигурации приложения позволяют истечению интервала обновления вместо принудительного обновления при получении. Вы по-прежнему можете использовать refresh и refresh-bus, но вы не можете подключить их непосредственно к Azure Event Grid с помощью веб-хука, так как они требуют ответа при настройке.

Свойство appconfiguration-refresh завершает истечение интервала обновления, поэтому оставшийся интервал обновления не ожидается перед следующей проверкой обновления. Свойство appconfiguration-refresh-bus отправляет уведомление в подключенную службу обмена сообщениями, например служебную шину Azure, чтобы уведомить все экземпляры приложения для обновления. В обоих случаях срок действия не окончательно истекает в интервале обновления, но отклоняется на небольшую погрешность. Это jitter гарантирует, что каждый экземпляр приложения не пытается одновременно обновляться.

management.endpoints.web.exposure.include= appconfiguration-refresh, appconfiguration-refresh-bus

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

spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.primary-token.name=[primary-token-name]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.primary-token.secret=[primary-token-secret]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.secondary-token.name=[secondary-token-name]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.secondary-token.secret=[secondary-token-secret]

Настройка веб-хуков

Чтобы настроить вебхук, откройте хранилище Конфигурация приложений Azure и выберите события в меню навигации. Затем выберите подписку на события. Задайте имя вашего события и выберите тип конечной точки — Web Hook. При выборе веб-хука появляется параметр конечной точки. Выберите Выбрать конечную точку. Конечная точка должна выглядеть следующим образом: https://www.myaplication.com/actuator/appconfiguration-refresh?myTokenName=mySecret

Подтвердить выбор отправляет уведомление о настройке по указанному URI и ожидает ответа. Если ответ не возвращается, программа установки завершается ошибкой. Настройка azure-spring-cloud-appconfiguration-web библиотеки для конечных точек возвращает правильный ответ, если для приложения настроено хранилище Конфигурация приложений Azure. Это подтверждение может быть отправлено другими способами. Дополнительные сведения о доставке веб-хуков см. в разделе "Доставка событий веб-хука".

Примечание.

Эта проверка выполняется только при создании или изменении конечной точки.

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

Принудительное обновление клиента

Библиотеку можно настроить для принудительного обновления всех конфигураций с заданным интервалом обновления. Следующая таблица описывает свойство refresh-interval.

Имя Описание Обязательное поле По умолчанию.
spring.cloud.azure.appconfiguration.refresh-interval Стандартный период времени между обновлениями. Duration Это . Нет ноль

Обновление с помощью spring.cloud.azure.appconfiguration.refresh-interval не проверяет никаких настроенных ключей мониторинга. Это свойство используется для того, чтобы убедиться, что секреты Key Vault хранятся в актуальном состоянии, так как Конфигурация приложений Azure не может узнать, когда они обновляются.

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

Обновление флага компонента

Если флаги компонентов и мониторинг включены, по умолчанию интервал обновления флагов компонентов имеет значение 30 секунд. Когда интервал обновления заканчивается, система проверяет все флаги компонентов в указанном хранилище для внесения изменений. Любое изменение ключа приводит к перезагрузке. Так как библиотеки интегрируются с системой обновления Spring, все обновления перезагружают все конфигурации из всех хранилищ. Интервал обновления можно задать для любого интервала, превышающего 1 секунду. Поддерживаемые единицы интервала обновления: s, mhи d в секундах, минутах, часах и днях соответственно. В следующем примере интервал обновления устанавливается на 5 минут:

spring.cloud.azure.appconfiguration.stores[0].monitoring.feature-flag-refresh-interval= 5m

Индикатор состояния здоровья

Клиентская библиотека поставляется с индикатором работоспособности, который проверяет, является ли подключение к хранилищу конфигурации приложений Azure или хранилищам исправным. Если он включен для каждого хранилища, он предоставляет одно из следующих значений состояния:

  • UP — последнее подключение успешно выполнено.
  • DOWN- Последнее подключение привело к ошибке с кодом, отличным от 200. Это состояние может быть вызвано проблемами, начиная от истечения срока действия учетных данных до проблемы со службой. Клиентская библиотека автоматически повторяет попытку подключения к хранилищу через следующий интервал обновления.
  • NOT LOADED — хранилище конфигурации отображается в локальном файле конфигурации, но хранилище конфигурации не было загружено из файла при запуске. Хранилище конфигураций отключено в файле конфигурации, или конфигурация, или конфигурации не смогли загрузиться при запуске, когда fail-fast была установлена как false для хранилища.

Индикатор работоспособности можно включить, задав параметр management.health.azure-app-configuration.enabled=true.

Настройка клиента

Библиотека настройки приложения использует пакет SDK Azure для Java для подключения к настройке приложений Azure и Azure Key Vault. Два интерфейса ConfigurationClientCustomizer и SecretClientCustomizerпредоставляются для изменения клиентов. Каждый интерфейс имеет метод customize, который принимает в качестве параметра своего соответствующего построителя, а также значение URI, для которого настраивается клиент, как показано в следующих примерах определения интерфейсов.

public interface ConfigurationClientCustomizer {
    public void customize(ConfigurationClientBuilder builder, String endpoint);
}

public interface SecretClientCustomizer {
    public void customize(SecretClientBuilder builder, String endpoint);
}

Эти интерфейсы позволяют настраивать HTTP-клиент и его конфигурации. В следующем примере стандартный HttpClient заменяется на другой, который использует прокси-сервер для всего трафика, направленного на Конфигурацию приложений и Key Vault.

Примечание.

Элементы ConfigurationClientBuilder и SecretClientBuilder уже настроены для использования при их передаче в customize. Все изменения клиентов, включая учетные данные и политику повторных попыток, переопределяют значения по умолчанию.

Эту конфигурацию можно также сделать с помощью конфигурации Spring Cloud Azure.

public class CustomClient implements ConfigurationClientCustomizer, SecretClientCustomizer {

    @Override
    public void customize(ConfigurationClientBuilder builder, String endpoint) {
        builder.httpClient(buildHttpClient());
    }

    @Override
    public void customize(SecretClientBuilder builder, String endpoint) {
        builder.httpClient(buildHttpClient());
    }

    private HttpClient buildHttpClient() {
        String hostname = System.getProperty("https.proxyHosts");
        String portString = System.getProperty("https.proxyPort");
        int port = Integer.valueOf(portString);

        ProxyOptions proxyOptions = new ProxyOptions(ProxyOptions.Type.HTTP,
                new InetSocketAddress(hostname, port));
        return new NettyAsyncHttpClientBuilder()
                .proxy(proxyOptions)
                .build();
    }

}