好的。这是将构建版本注入到要由 Eureka 注册的服务(“service-a”)实例元数据中的代码:
@Configuration
@ConditionalOnClass({ EurekaInstanceConfigBean.class, EurekaClient.class })
public class EurekaClientInstanceBuildVersionAutoConfiguration {
@Autowired(required = false)
private EurekaInstanceConfig instanceConfig;
@Autowired(required = false)
private BuildProperties buildProperties;
@Value("${eureka.instance.metadata.keys.version:instanceBuildVersion}")
private String versionMetadataKey;
@PostConstruct
public void init() {
if (this.instanceConfig == null || buildProperties == null) {
return;
}
this.instanceConfig.getMetadataMap().put(versionMetadataKey, buildProperties.getVersion());
}
}
这是验证“service-b”内元数据传输的代码:
@Component
public class DiscoveryClientRunner implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private DiscoveryClient client;
@Override
public void run(String... args) throws Exception {
client.getInstances("service-a").forEach((ServiceInstance s) -> {
logger.debug(String.format("%s: %s", s.getServiceId(), s.getUri()));
for (Entry<String, String> md : s.getMetadata().entrySet()) {
logger.debug(String.format("%s: %s", md.getKey(), md.getValue()));
}
});
}
}
请注意,如果“虚线组成”(即“实例构建版本”),则元数据键强制采用驼峰式大小写。
这是我发现的根据版本过滤服务实例的解决方案:
@Configuration
@EnableConfigurationProperties(InstanceBuildVersionProperties.class)
public class EurekaInstanceBuildVersionFilterAutoConfig {
@Value("${eureka.instance.metadata.keys.version:instanceBuildVersion}")
private String versionMetadataKey;
@Bean
@ConditionalOnProperty(name = "eureka.client.filter.enabled", havingValue = "true")
public EurekaInstanceBuildVersionFilter eurekaInstanceBuildVersionFilter(InstanceBuildVersionProperties filters) {
return new EurekaInstanceBuildVersionFilter(versionMetadataKey, filters);
}
}
@Aspect
@RequiredArgsConstructor
public class EurekaInstanceBuildVersionFilter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final String versionMetadataKey;
private final InstanceBuildVersionProperties filters;
@SuppressWarnings("unchecked")
@Around("execution(public * org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient.getInstances(..))")
public Object filterInstances(ProceedingJoinPoint jp) throws Throwable {
if (filters == null || !filters.isEnabled()) logger.error("Should not be filtering...");
List<ServiceInstance> instances = (List<ServiceInstance>) jp.proceed();
return instances.stream()
.filter(i -> filters.isKept((String) jp.getArgs()[0], i.getMetadata().get(versionMetadataKey))) //DEBUG MD key is Camel Cased!
.collect(Collectors.toList());
}
}
@ConfigurationProperties("eureka.client.filter")
public class InstanceBuildVersionProperties {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Indicates whether or not service instances versions should be filtered
*/
@Getter @Setter
private boolean enabled = false;
/**
* Map of service instance version filters.
* The key is the service name and the value configures a filter set for services instances
*/
@Getter
private Map<String, InstanceBuildVersionFilter> services = new HashMap<>();
public boolean isKept(String serviceId, String instanceVersion) {
logger.debug("Considering service {} instance version {}", serviceId, instanceVersion);
if (services.containsKey(serviceId) && StringUtils.hasText(instanceVersion)) {
InstanceBuildVersionFilter filter = services.get(serviceId);
String[] filteredVersions = filter.getVersions().split("\\s*,\\s*"); // trimming
logger.debug((filter.isExcludeVersions() ? "Excluding" : "Including") + " instances: " + Arrays.toString(filteredVersions));
return contains(filteredVersions, instanceVersion) ? !filter.isExcludeVersions() : filter.isExcludeVersions();
}
return true;
}
@Getter @Setter
public static class InstanceBuildVersionFilter {
/**
* Comma separated list of service version labels to filter
*/
private String versions;
/**
* Indicates whether or not to keep the associated instance versions.
* When false, versions are kept, otherwise they will be filtered out
*/
private boolean excludeVersions = false;
}
}
您可以为每个使用的服务指定预期或避免版本的列表,并且将相应地过滤发现。
logging.level.com.mycompany.demo=调试
eureka.client.filter.enabled=true
eureka.client.filter.services.service-a.versions=0.0.1-SNAPSHOT
如有任何建议,请作为评论提交。谢谢