spring 云编程元数据生成
spring cloud programmatic metadata generation
我是否可以在注册时生成一些元数据添加到服务中。
我们正在从 Eureka 迁移到 Consul,我需要在服务启动时向已注册的元数据添加一个 UUID 值。以便稍后我可以在按名称检索服务实例时获取此元数据值。
一些背景:我们使用了来自 https://github.com/VanRoy/spring-cloud-dashboard 的优秀前端 UI。它设置为将 Eureka 模型用于您具有名称的应用程序的服务。每个应用程序将有多个实例,每个实例都有一个实例 ID。
因此,对于尤里卡模型,有一个 2 级服务描述,而 spring 云模型是一个平面模型,其中 n 个实例,每个实例都有一个服务 ID。
平面模型不适用于我上面引用的 UI,因为应用程序名称和实例 ID 之间没有区别,即 spring 模型,它们是相同的。
因此,如果我生成自己的实例 ID 并通过元数据处理它,那么我可以保留一些行为而无需重写 ui。
参见 spring 云领事中的 documentation on metadata and tags。 Consul 还不支持服务发现的元数据,但是 spring 云有一个元数据抽象(只是一个字符串映射)。在使用 key=value
样式创建的 consul 标签中,解析到该元数据映射中。
例如,application.yml:
spring:
cloud:
consul:
discovery:
tags: foo=bar, baz
以上配置将生成 foo→bar 和 baz→baz 的映射。
根据 Spencer 的回答,我在我的代码中添加了一个 EnvironmentPostProcessor。
它有效,我能够以编程方式添加我想要的元数据标签,但它是对 "tags: foo=bar, baz" 元素的补充,因此它会覆盖那个元素。我可能会在第二天左右找到解决方法,但我想我会添加我为其他查看此答案的人所做的事情,然后说,你做了什么?
先加一个class如下:
@Slf4j
public class MetaDataEnvProcessor implements EnvironmentPostProcessor, Ordered {
// Before ConfigFileApplicationListener
private int order = ConfigFileApplicationListener.DEFAULT_ORDER - 1;
private UUID instanceId = UUID.randomUUID();
@Override
public int getOrder() {
return this.order;
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("spring.cloud.consul.discovery.tags", "instanceId="+instanceId.toString());
MapPropertySource propertySource = new MapPropertySource("springCloudConsulTags", map);
environment.getPropertySources().addLast(propertySource);
}
}
然后在 resources/META-INF 中添加一个 spring.factories,并在下面的行中添加此处理器
org.springframework.boot.env.EnvironmentPostProcessor=com.example.consul.MetaDataEnvProcessor
除了覆盖 application.yml 文件中的标签内容外,这工作正常
我是否可以在注册时生成一些元数据添加到服务中。
我们正在从 Eureka 迁移到 Consul,我需要在服务启动时向已注册的元数据添加一个 UUID 值。以便稍后我可以在按名称检索服务实例时获取此元数据值。
一些背景:我们使用了来自 https://github.com/VanRoy/spring-cloud-dashboard 的优秀前端 UI。它设置为将 Eureka 模型用于您具有名称的应用程序的服务。每个应用程序将有多个实例,每个实例都有一个实例 ID。
因此,对于尤里卡模型,有一个 2 级服务描述,而 spring 云模型是一个平面模型,其中 n 个实例,每个实例都有一个服务 ID。
平面模型不适用于我上面引用的 UI,因为应用程序名称和实例 ID 之间没有区别,即 spring 模型,它们是相同的。
因此,如果我生成自己的实例 ID 并通过元数据处理它,那么我可以保留一些行为而无需重写 ui。
参见 spring 云领事中的 documentation on metadata and tags。 Consul 还不支持服务发现的元数据,但是 spring 云有一个元数据抽象(只是一个字符串映射)。在使用 key=value
样式创建的 consul 标签中,解析到该元数据映射中。
例如,application.yml:
spring:
cloud:
consul:
discovery:
tags: foo=bar, baz
以上配置将生成 foo→bar 和 baz→baz 的映射。
根据 Spencer 的回答,我在我的代码中添加了一个 EnvironmentPostProcessor。
它有效,我能够以编程方式添加我想要的元数据标签,但它是对 "tags: foo=bar, baz" 元素的补充,因此它会覆盖那个元素。我可能会在第二天左右找到解决方法,但我想我会添加我为其他查看此答案的人所做的事情,然后说,你做了什么?
先加一个class如下:
@Slf4j
public class MetaDataEnvProcessor implements EnvironmentPostProcessor, Ordered {
// Before ConfigFileApplicationListener
private int order = ConfigFileApplicationListener.DEFAULT_ORDER - 1;
private UUID instanceId = UUID.randomUUID();
@Override
public int getOrder() {
return this.order;
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("spring.cloud.consul.discovery.tags", "instanceId="+instanceId.toString());
MapPropertySource propertySource = new MapPropertySource("springCloudConsulTags", map);
environment.getPropertySources().addLast(propertySource);
}
}
然后在 resources/META-INF 中添加一个 spring.factories,并在下面的行中添加此处理器
org.springframework.boot.env.EnvironmentPostProcessor=com.example.consul.MetaDataEnvProcessor
除了覆盖 application.yml 文件中的标签内容外,这工作正常