从 Spring 云配置服务器动态更改自定义注释。可能吗?

changing custom annotations on the fly from Spring Cloud Config Server. Is it possible?

上下文:我需要提供一种在生产过程中以尽可能低的性能成本更改参数值的方法。

目标:我想即时更改注释值并立即将其应用于所有微服务实例。

个人背景和限制:我知道我可以使用 Spring Cloud Config 即时更改参数,如 this article and I Know there is some challenges and pitfalls involved on changing annotations on the fly also like discussed in stackoveflow question 中所述。

我知道 Spring Cloud Config 可用于设置在 boot/start 期间应用于所有微服务实例的集中配置。我用过一点。我想知道我是否可以使用它来集中参数,这些参数会影响动态的自定义注释。

一个想象的解决方案是:

...每当我需要 somepPropertyValue

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

@Bean
public String somePropertyValue(){
    return somePropertyValue;
}

所有微服务端点中的配置客户端,不仅在应用程序启动时而且在更新 Spring 云配置服务器 bootstrap.properties 中管理的 somePropertyValue 时都必须调用:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class SpringConfigClientApplication {

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

@RefreshScope
@RestController
class MessageRestController {

    @Value("${server.somePropertyValue:Unable to connect to config server}")
    private String somePropertyValue;

    @RequestMapping("/server/somePropertyValue")
    String getSomePropertyValue() {
        return this.somePropertyValue;
    }
}
 

并且 somePropertyValue 以某种方式在 Spring Cloud Config 中得到维护,如果在生产期间发生变化,它会影响随处可见的 somePropertyValue 在所有微服务实例中被注释。

我目前正在通过在所有 Spring 启动微服务中添加一个 kafka 消费者来实现此行为,该微服务 listen/observe 一个主题,当它收到一条新消息时,它会即时更改参数值。我在所有公司微服务中创建了一个 Kafka 依赖项,这似乎很奇怪。由于我已经将 Spring Config 用于有点类似的场景,所以我想知道是否有更好的替代方法使用一些开箱即用的 Spring 方法。在我的情况下,性能也非常重要,同步所有参数的一点延迟不是问题。延迟是指在所有微服务中更新参数两三秒不是问题。

有两种方法:

i- 有一个刷新端点,您实际上可以为服务调用它,它实际上会在不重新启动自身的情况下刷新其配置,这非常简洁。例如MS-A8080 上列出,然后在此端点执行 POST 请求: localhost:8080/refresh.

注意: Spring Actuator 实际上在我们在 MS-A 中注释控制器时自动向应用程序添加一个 RefreshEndpoint @RefreshScope.

ii- 你还可以使用 Spring Cloud Bus,广播一个事件,然后每个服务 监听 并刷新自己。如果您有许多服务都使用 Config Server,并且您不想像我们在 1st 中所做的那样一个接一个地访问 /refresh 端点,那么这很方便方法。你只想向公共汽车广播一条消息,让所有这些东西自动接收。

参考: 我在 Pluralsight

上课时学到的这两个概念