Вступление
Rоресурс — это среда с открытыми ресурсами для разработки динамических сервисов и компонентов на основе Java, в которой бизнес-логика основана на данных некоторых ресурсов. Ресурс может быть любым — файлом в локальной файловой системе, конфигурацией YAML из репозитория GitHub и т. Д.
Рассмотрим, например, службу прогнозирования погоды или поставщика цен на фондовом рынке, который извлекает новые данные через конечную точку HTTP. Эти виды услуг бесполезны, если они работают с устаревшими данными, поэтому их следует постоянно обнаруживать и перезагружать.
Вам также могут понравиться:
Динамические, Модульные Микросервисы с Java EE
Основная идея Reror состоит в том, чтобы скрыть всю сложность, связанную с работой с источниками данных, анализом контента и динамической перезагрузкой. Он предоставляет декларативный API, с помощью которого вы определяете сервисы один раз и используете их для всей среды выполнения приложения.
Как это работает
Арендатор генерирует специальный прокси-класс, который наследует тип вашего сервиса. Под этим прокси-сервером делегируются все вызовы методов для самого современного экземпляра вашей службы / компонента. Чтобы создать его, он загружает данные из предоставленного источника, анализирует их с помощью переводчиков и вызывает метод конструктора / фабрики вашего класса.
Арендодатель предоставляет декларативный API , реализующий самые популярные источники и форматы файлов. Во время создания службы вы должны определить источник, ресурс и переводчик. Таким образом, после создания сервиса вы можете подписаться на дальнейшие изменения ресурса. Управление версиями также поддерживается с использованием различных стратегий перезагрузки , в зависимости от типа источника данных. Это позволяет перезагрузить только те данные, которые были фактически изменены, сохраняя пропускную способность сети / диска и ресурсы ЦП.
Этот подход лучше всего подходит для платформ IoC / DI, таких как Spring, где вы регистрируете компоненты только один раз во время запуска контекста. Вы можете безопасно сделать это с помощью услуг Арендатора. В этом случае Арендатор неявно удостоверится, что они всегда обновлены.
Пример переключения динамической функции
Определение сервиса
Предположим, вы собираетесь внедрить чрезвычайно простую службу Feature Toggle для своего приложения. Он будет настроен с использованием простого файла YAML, хранящегося в репозитории GitHub. Всякий раз, когда состояние переключения функции изменяется с помощью фиксации в этом хранилище, ваше приложение должно включать / отключать данную функцию во время выполнения. Ниже приводится модель данных:
Джава
1
public class FeatureToggle {
2
"feature") (
3
public String featureName;
4
"state") (
5
public ToggleState state;
6
}
7
public enum ToggleState {
9
ENABLED, DISABLED
10
}
Это очень просто - у нас есть имя объекта и его текущее состояние. Имея эту модель, мы можем реализовать наш сервис:
Джава
xxxxxxxxxx
1
public class FeatureToggleService {
2
private final Map<String, ToggleState> states;
3
4
public FeatureToggleService(List<FeatureToggle> toggleList) {
5
this.states = toggleList.stream().collect(toUnmodifiableMap(
6
k -> k.featureName, v -> v.state));
7
}
8
9
public boolean isEnabled(String featureName) {
10
return Validate.notNull(states.get(featureName), featureName) == ToggleState.ENABLED;
11
}
12
}
Наш сервис принимает список переключателей функций в качестве входных данных и создает карту состояний. Затем мы можем проверить, включена ли функция, используя isEnabled
метод.
Теперь пришло время для Rоресора создать экземпляр службы и начать заполнять его данными из репозитория GitHub:
Джава
xxxxxxxxxx
1
Ressor ressor = Ressor.create();
2
3
FeatureToggleService featureToggle = ressor.service(FeatureToggleService.class)
4
.translator(yamlList(FeatureToggle.class))
5
.source(GitRepository.remote()
6
.repositoryURI("https://github.com/dmart28/ressor-feature-toggle.git")
7
.build())
8
.resource(GitRepository.path("toggles.yaml"))
9
.build();
Давайте опишем наиболее важные части построчно:
# 4: Объявите, что мы ожидаем, что данные будут в формате массива YAML. Арендатор проанализирует его, используя Джексона, в List <FeatureToggle >.
# 5: Объявите, что источником будет Git-репозиторий с удаленного URL.
# 8: Объявите путь к файлу внутри репозитория Git.
# 9: Создает экземпляр прокси-класса, клонирует Git-репозиторий и переводит содержимое YAML в FeatureToggleService
конструктор.
Вы всегда можете повторно использовать источник для нескольких услуг.
Вы можете создать свой сервис асинхронно, но в этом случае вам нужно предоставить начальный экземпляр, который будет работать до первой перезагрузки:
Джава
xxxxxxxxxx
1
var emptyService = new FeatureToggleService(List.of());
2
var featureToggle = ressor.service(FeatureToggleService.class)
4
.translator(yamlList(FeatureToggle.class))
5
...
6
.initialInstance(emptyService)
7
.asyncInitialReload()
8
.build();
Создание службы перезагружаемой
Мы хотели бы, чтобы Арендатор оставил featureToggle
сервис только с актуальной информацией. Кто-то может отключить некоторые функции, внеся изменения в файл toggles.yaml в репозитории GitHub.
Это может быть достигнуто простым опросом с использованием Raser:
Джава
xxxxxxxxxx
1
ressor.poll(featureToggle).every(5, TimeUnit.SECONDS);
Он будет выполнять команду git fetch каждые 5 секунд для исходного хранилища в фоновом режиме. Если обнаружено какое-либо изменение файла (для текущей ветви), будет создан новый экземпляр FeatureToggleService
и заменен внутри прокси.
Таким образом, featureToggle
экземпляр может быть, например, зарегистрирован один раз как bean-компонент Spring во время запуска приложения. Арендатор гарантирует, что он в конечном итоге будет содержать самые последние данные.
Использование сервиса
Когда Арендатор создает экземпляр службы, он может использоваться где угодно в течение всего срока службы приложения:
Джава
xxxxxxxxxx
1
System.out.println(featureToggle.isEnabled("new-design"));
2
System.out.println(featureToggle.isEnabled("items-list"));
Вы можете найти полный пример кода здесь . Вы можете попробовать это, запустив себя. Есть также много других примеров.
Импорт
Релизы доступны через Maven Central. Источники реализации объединены в отдельные модули.
Java 11+
Джава
xxxxxxxxxx
1
implementation 'xyz.ressor:ressor-core:1.3.0'
2
implementation 'xyz.ressor:ressor-git-source:1.3.0'
3
implementation 'xyz.ressor:ressor-http-source:1.3.0'
4
implementation 'xyz.ressor:ressor-s3-source:1.3.0'
Java 8
Джава
xxxxxxxxxx
1
implementation 'xyz.ressor:ressor-core-jdk8:1.3.0'
2
implementation 'xyz.ressor:ressor-git-source-jdk8:1.3.0'
3
implementation 'xyz.ressor:ressor-http-source-jdk8:1.3.0'
4
implementation 'xyz.ressor:ressor-s3-source-jdk8:1.3.0'
Заключение
Идея арендатора довольно проста: взять полную реализацию сервиса и снабдить ее переведенными данными из заданного источника, неявно перезагружая их при необходимости. Помимо Git, у Рессора есть и другие источники данных: файловая система, HTTP, Amazon S3 и т. Д. Есть еще случаи и функции, которые не были рассмотрены в этой статье.
Репозиторий доступен на Github . Вы можете узнать больше об официальной документации Арендатора . Кроме того, есть несколько примеров, чтобы попробовать.
Дальнейшее чтение
Динамические, модульные микросервисы с Java EE
Динамическое управление конфигурацией в архитектуре микросервисов с помощью Spring Cloud