Как «переместить» конфигурацию Spring Boot?

Java

предисловие

Локализация конфигурации — большая проблема для микросервисов.Невозможно перезапускать службу каждый раз, когда нужно изменить конфигурацию.Поэтому окончательным решением является экстернализация конфигурации и размещение ее на платформе, чтобы избежать ненужного.Просто перезапустите службу.一次修改多处生效цель.

Но для Spring Boot проекта одного приложения динамическое обновление явно несколько избыточно, да и вообще это всего лишь сервис, можно ли его изменить и перезапустить?

Однако динамическое обновление необходимо использовать в некоторых особых сценариях, например:

  1. 添加数据源: При подключении к сторонней платформе вы не можете перезапускать службу каждый раз, когда добавляете источник данных
  2. 固化的对接: Большое количество фиксированных способов стыковки, отличается только один из фиксированных сегментов кода, например поля в предоставленном представлении разные, и поля в сервисе интерфейса разные.

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

Каковы основные решения в рамках микросервисов?

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

主流的配置中心

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

  1. Nacos: Недавний проект Alibaba с открытым исходным кодом, этот парень очень хорош, один убилEureka(остановился) иConfig+Bus, который может использоваться и как центр конфигурации, и как центр регистрации, и имеет собственную независимую платформу управления, которую можно назвать самой массовой.

  2. Config+Bus: на центр конфигурации микросервисов, использовавшийся в первые дни, можно положиться.GitHubФайлы конфигурации для управления микросервисами, которые сейчас используются многими предприятиями, но требуют самостоятельного развертывания микросервиса, иNacosПо сравнению с ним намного хуже.

  3. Apollo: Проект с открытым исходным кодом Ctrip, Apollo, также используется многими компаниями. Чен мало что знает о нем. Те, кому интересно, могут подробно его изучить.

Несколько решений для Spring Boot?

На самом деле, три вышеупомянутых решения можно адаптировать в проекте Spring Boot, но как отдельное приложение это тяжеловато. Автор кратко представляет два доступных решения.

Spring Boot+Nacos (не рекомендуется)

Я должен сказать, что Alibaba действительно амбициозна. То, что Alibaba хочет сделать, это на самом деле экосистема микросервисов. Nacos можно не только использовать в качестве центра настройки и регистрации Spring Cloud, но и адаптировать к Dubbo и K8s. Подробное введение был сделан, и автор не будет подробно представлять его здесь, как показано на следующем рисунке:

Nacos.io

Конечно, Nacos также применим к проектам Spring и Spring Boot.

Как это использовать? Здесь автор только предлагает следующие идеи и не проводит слишком глубоких исследований.Эта статья находится в следующей колонке автора.Расширенное весеннее облакоПодробно представим:

  1. Загрузите соответствующую версию Nacos, запустите проект и посетитеhttp://localhost:8848Войдите в интерфейс управления Nacos;

  2. Проект Spring Boot представляет зависимости конфигурации Nacosnacos-config-spring-boot-starter, настройте адрес центра управления Nacos.

  3. @NacosPropertySource,@NacosValueДве аннотации объединяются для завершения.

  • @NacosPropertySource: указывает центр конфигурацииdataId, и нужно ли автоматически обновлять
  • @NacosValueальтернатива@ValueАннотация завершает автоматическое связывание свойств
  1. Если проект компании управляется в фоновом режиме, вы можете напрямую вызвать открытый API Nacos, чтобы изменить значение соответствующей конфигурации (заменив ручное управление интерфейсом управления Nacos).Адрес API:что cos.IO/this-capable/docs/…

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

Spring Boot+Config+актуатор (рекомендуется)

Это решение на самом деле использует центр конфигурации Config, но оно не такое тяжелое, как Nacos, и оно полностью подходит для проекта SpringBoot одного приложения, и для достижения эффекта можно внести лишь небольшое количество изменений.

Вариант 1 (не рекомендуется)

  1. Добавьте зависимости конфигурации следующим образом:
<!-- springCloud的依赖-->
<dependencyManagement>
    <dependencies>
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
    </dependencies>
</dependencyManagement>

<!-- config的依赖-->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

  <!-- actuator的依赖-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  1. Предоставьте конечные точки Spring Boot в файле конфигурации следующим образом:
management.endpoints.web.exposure.include=*
  1. В файл конфигурации добавлены три новые конфигурации свойств:
config.version=22
config.app.name=dynamic-project
config.platform=mysql
  1. комбинировать@RefreshScopeАннотация динамически обновляется, а контроллер записывается следующим образом:
@RestController
//@RefreshScope该注解必须标注,否则无法完成动态更新
@RefreshScope
public class DynamicConfigController {
    @Value("${config.version}")
    private String version;

    @Value("${config.app.name}")
    private String appName;

    @Value("${config.platform}")
    private String platform;


    @GetMapping("/show/version")
    public String test(){
        return "version="+version+"-appName="+appName+"-platform="+platform;
    }
  1. Запустить тест проекта, доступ через браузерhttp://localhost:8080/show/version, возвращаемая информация выглядит следующим образом:

  1. ИсправлятьtargetФайлы конфигурации в каталоге следующие:
config.version=33
config.app.name=dynamic-project
config.platform=ORACLE
  1. POST-запросhttp://localhost:8080/actuator/refreshИнтерфейс, обновление конфигурации вручную (обязательно, иначе обновление не может быть выполнено автоматически)

  2. Введите браузер еще разhttp://localhost:8080/show/version, результат следующий:

Видно, что конфигурация была автоматически изменена, и на этом все.

Вариант 2 (рекомендуется)

Что вы думаете, когда видите план? Разве это не немного сырно?

Первый вопрос: зачем вообще вызывать ручное обновление?

Второй вопрос: Его можно изменить только вручную в конфигурационном файле? Что делать, если вы хотите управлять системными изменениями в фоновом режиме?

Если вы хотите решить две вышеупомянутые проблемы, вы должны посмотреть наConfigИсходный код , ключевая часть кода находится вorg.springframework.cloud.context.refresh.ContextRefresher#refresh()метод, как показано ниже:

Поэтому просто вызовите следующее после изменения свойстваContextRefresher#refresh()(Асинхронный, чтобы избежать блокировки и постоянного ожидания) метод.

Чтобы облегчить тестирование, мы вручную пишем интерфейс обновления следующим образом:

@GetMapping("/show/refresh")
    public String refresh(){
        //修改配置文件中属性
        HashMap<String, Object> map = new HashMap<>();
        map.put("config.version",99);
        map.put("config.app.name","appName");
        map.put("config.platform","ORACLE");
        MapPropertySource propertySource=new MapPropertySource("dynamic",map);
        //将修改后的配置设置到environment中
        environment.getPropertySources().addFirst(propertySource);
        //异步调用refresh方法,避免阻塞一直等待无响应
        new Thread(() -> contextRefresher.refresh()).start();
        return "success";
    }

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

Тестируем, запускаем проект, посещаемhttp://localhost:8080/show/version, обнаружил, что ранее он был настроен вapplication.propertiesЗначение в , как показано на следующем рисунке:

перечислитьrefreshинтерфейс:http://localhost:8080/show/refreshсбросить значение свойства;

позвони сноваhttp://localhost:8080/show/versionПроверьте, была ли изменена конфигурация, как показано ниже:

Как видно из рисунка выше, конфигурация изменена, и достигнут эффект динамического обновления.

Суммировать

В этой статье представлены несколько возможных решений от внедрения центра конфигурации микросервисов до простого центра конфигурации, созданного Spring Boot, Автор настоятельно рекомендует последнее решение, упрощенную версию.Config, полностью подходит для монолитных приложений.

Исходный код проекта выложен, если нужно обратить внимание на паблик аккаунтКолонка технологий Code Apeключевые слова ответа008Получать.