Spring Cloud Config Server实现灰度发布

1、灰度发布

所谓灰度发布,即某个服务存在多个实例时,当修改服务配置信息后只想让其中的一个或者某几个实例更新配置,而不是全部实例更新配置。

2、实现方式

场景一(不常见):当多个实例部署在同一台机器上

由于是同一台机器,多个相同实例的端口必然不同,此时可以使用 destination=应用名称:端口号 的形式进行灰度发布。

destination的值(即 应用名称:端口号,也可能是其他形式)对应ApplicationContextId,后面会说明ApplicationContextId是如何获取的。

比如:

curl -X POST "http://localhost:8050/bus/refresh?destination=appName:8801"

curl -X POST "http://localhost:8050/bus/refresh?destination=appName:8802"

场景二:当多个实例部署在不同的机器上

在不同的机器上,为了方便管理,多个实例的应用名称、端口号一般是相同的,那么就无法通过场景一的方式进行灰度发布了,因为没有唯一的因素能够确定要发布哪些实例,此时可以想到的是不同机器的ip是唯一的,这就是切入点!

在org.springframework.boot.context.ContextIdApplicationContextInitializer类中有如下代码:

private String getApplicationId(ConfigurableEnvironment environment) {
    String name = environment.resolvePlaceholders(this.name);
    String index = environment.resolvePlaceholders("${vcap.application.instance_index:${spring.application.index:${server.port:${PORT:null}}}}");
    String profiles = StringUtils.arrayToCommaDelimitedString(environment.getActiveProfiles());
    if (StringUtils.hasText(profiles)) {
        name = name + ":" + profiles;
    }

    if (!"null".equals(index)) {
        name = name + ":" + index;
    }

    return name;
}

可以看出ApplicationContextId其实是由name:profiles:index组成的,其中name的表达式为${spring.application.name:${vcap.application.name:${spring.config.name:application}}},该表达式的意思是,如果spring.application.name参数有值则使用,后面的不再匹配;如果没有值,则继续匹配后面的,以此类推。index的表达式为${vcap.application.instance_index:${spring.application.index:${server.port:${PORT:null}}}},同理,可知如果没有配置其他配置项,那么默认的是server.port,因此一般来说,默认返回的是${spring.application.name}:${server.port}

在上面提到,可以利用不同机器ip不同的特点进行灰度发布改造,那么可以对优于server.port匹配的sping.application.index参数进行配置,所有实例都添加:sping.application.index=${spring.cloud.client.ipAddress}:${server.port}配置,那么组成的ApplicationContextId就是${spring.application.name}:${spring.application.index},即应用名称:实例ip:实例port,这种方式不仅适用于场景二,同样也适用于场景一。

比如:

curl -X POST "http://localhost:8050/bus/refresh?destination=appName:192.168.1.250:8801"

curl -X POST "http://localhost:8050/bus/refresh?destination=appName:192.168.1.250:8802"

curl -X POST "http://localhost:8050/bus/refresh?destination=appName:192.168.1.251:8801"

 

你可能感兴趣的:(springboot,springcloud,configserver,配置中心,灰度发布,destination)