跳到主要内容

SpringBoot灵活的映射配置信息

在用@ConfigurationProperties最常用的功能是用此注解对类进行修饰,设置好prefix前缀,这样在springboot的配置文件中,配置信息的key和value就会对应的配置到类中的属性上。

以设置eureka信息为例设置实例id

@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean
implements CloudEurekaInstanceConfig, EnvironmentAware {

private static final String UNKNOWN = "unknown";


/**
* Get the unique Id (within the scope of the appName) of this instance to be
* registered with eureka.
*/
private String instanceId;

/**
* set get省略
*/

}
eureka:
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}

一般都是这么使用的。但还有一种情况,要加上新的配置信息,但又不想在@ConfigurationProperties类中添加新的属性值,想要更加的灵活。这种情况一般用于对于框架的扩展,又不能修改源码的情况下。

这时,可以在类中设置Map类型的属性,这样既不用添加或修改属性,又能实现灵活的设置添加和删除配置信息。

仍以eureka为例

@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean
implements CloudEurekaInstanceConfig, EnvironmentAware {

private static final String UNKNOWN = "unknown";


/**
* Gets the metadata name/value pairs associated with this instance. This information
* is sent to eureka server and can be used by other instances.
*/
private Map<String, String> metadataMap = new HashMap<>();

/**
* set get省略
*/

}
eureka:
instance:
metadata-map:
test-flag: true

这样metadataMap中就有了以test-flag为key,true为value的配置信息。

nacos中也提供了这样的配置

以nacos为例

@ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {

private static final Logger log = LoggerFactory
.getLogger(NacosDiscoveryProperties.class);


public static final String PREFIX = "spring.cloud.nacos.discovery";



/**
* extra metadata to register.
*/
private Map<String, String> metadata = new HashMap<>();


/**
* set get省略
*/
}
spring:
cloud:
nacos:
discovery:
metadata:
test-flag: true

eurekanacos这样做,也是为了让我们用户来灵活的存放自己设置的信息来达到想要的功能。

当灰度和生产使用同一个注册中心来做环境隔离的负载均衡功能正好可以利用这一点。

思路

  • 先设置一个灰度标识,利用这种灵活的配置特性放到eurekanacos中服务列表中

  • 继承ribbon-loadbalance中的AbstractServerPredicate,重写apply(PredicateKey input)方法,此方法作用是当ribboneurekanacos获取了服务列表后,列表要循环调用此方法,返回true保留,返回false则过滤掉。

  • apply(PredicateKey input)方法中,通过查看服务中的request中灰度标识。

    • 如果为false,则为生产环境的请求。和eurekanacos中服务列表中的灰度标识进行对比,也为false的,说明是生产的服务,则apply(PredicateKey input)返回true保留。为true的说明为灰度服务,则apply(PredicateKey input)返回false过滤掉。

    • 如果为true,则为灰度环境的请求。和eurekanacos中服务列表中的灰度标识进行对比,为false的,说明是生产的服务,则apply(PredicateKey input)返回false过滤掉。为true的说明为灰度服务,则apply(PredicateKey input)返回true保留。