【问题标题】:How to update a flag in existing running Spring Boot Application without restart如何在不重启的情况下更新现有正在运行的 Spring Boot 应用程序中的标志
【发布时间】:2021-10-13 01:02:13
【问题描述】:

我有一个运行功能的 Spring Boot 应用程序。我想在运行时切换该功能(开/关)而不重新部署或重新启动应用程序。问题是我无法部署任何休息端点,因为服务器由于安全原因只暴露了一些特定的端口。

我想远程控制切换开关,以便我可以打开和关闭该功能。我尝试使用以下方法读取本地机器上的环境变量:

System.getEnv("envVariable")

但即使在使用 export envVariable=true 更新它之后,它也没有反映代码中的更新值。

有人可以建议任何方法来实现这一点吗?

谢谢,

【问题讨论】:

  • 请提供读取此环境变量的代码。如果这是在 bean 级别,并且 bean 是单例的,那么您必须重新启动应用程序以重新初始化 bean 以读取更新的值。要每次获取更新的值,您需要在方法级别读取此值。

标签: java spring-boot jar runtime


【解决方案1】:

有一种编程模式功能切换,它提供了一种在运行时打开/关闭应用程序组件的方法。核心思想是向属性文件或数据库配置表询问配置字段的当前状态,并在配置更改时更改应用程序功能。这种模式在这里描述https://martinfowler.com/bliki/FeatureToggle.html。您可以使用关键字“Feature Flags”找到更多信息。

Java 特性标志的流行实现之一是 togglz (https://www.togglz.org/quickstart.html)。

这里是一个使用 togglz 的例子:

  1. 为特征表示创建枚举

     public enum MyFeatures implements Feature {
    
     @EnabledByDefault
     @Label("First Feature")
     FEATURE_ONE,
    
     @Label("Second Feature")
     FEATURE_TWO;
    
     public boolean isActive() {
         return FeatureContext.getFeatureManager().isActive(this);
     }
    
  2. 实现 TogglzConfig

     @ApplicationScoped
     public class DemoConfiguration implements TogglzConfig {
    
     public Class<? extends Feature> getFeatureClass() {
         return MyFeatures.class;
     }
    
     public StateRepository getStateRepository() {
         return new FileBasedStateRepository(new File("/tmp/features.properties"));
     }
    
     public UserProvider getUserProvider() {
         return new ServletUserProvider("admin");
     }
    

    }

  3. 描述依赖于切换的特性行为:

    if( MyFeatures.FEATURE_ONE.isActive() ) {
    

    // 这里有新东西 }

来源:https://www.togglz.org/quickstart.html

【讨论】:

    【解决方案2】:

    为此,您需要更多的依赖项。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    在你需要写的属性文件中

    management.endpoints.web.exposure.include=*
    

    无论你在哪里使用环境变量,都可以在类上使用 Annotation @RefreshScope 之类的

    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    @RefreshScope
    @RestController
    public class DemoController {   
        @Value("${my.data}")
        String str;
        // code
    }
    

    每当您更改环境变量时,只需点击发布请求 http://localhost:PORT/actuator/refresh

    使用上述配置,您可以更改环境变量。

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2020-02-23
      • 2018-04-01
      • 2020-02-27
      • 2019-05-01
      • 2017-04-29
      • 2016-02-23
      • 2018-12-15
      • 1970-01-01
      相关资源
      最近更新 更多