【问题标题】:Override spring-boot EurekaInstanceConfigBean覆盖spring-boot EurekaInstanceConfigBean
【发布时间】:2015-05-01 23:12:58
【问题描述】:

我正在构建一个基于 dockerized spring-cloud 的微服务,该微服务向 eureka 注册。注册过程的一部分是向主机询问映射到容器的端口,以便 docker 可以为容器化服务选择一个空闲的主机端口。

我有一个基于主机的服务,dockerized 服务可以请求端口映射,现在我正在尝试使用外部端口向 eureka 注册微服务。

我在微服务中获得了正确的端口,但无法覆盖 EurekaInstanceConfig

我尝试过的:

@SpringBootApplication
@EnableEurekaClient
public class ApplicationBootstrapper {

    @Value("${containerIp}")
    private String containerIp;

    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
        String hostPort = new RestTemplate().getForObject(
            "http://{hostname}:7691/container/{id}/hostPort", 
            String.class, 
            containerIp, 
            config.getHostname());

        config.setPreferIpAddress(true);
        config.setIpAddress(containerIp);
        config.setNonSecurePort(Integer.valueOf(hostPort));

        return config;
}

我的自定义EurekaInstanceConfigBean 被创建,但配置没有被拾取(服务注册到它的内部容器端口)。

问题是:我如何覆盖EurekaInstanceConfigBean

编辑(2):

正如史蒂夫指出的那样,现在 spring-cloud-1.0.0.RELEASE 可用,我以前的大多数解决方案现在已经过时了。我附上了我的最终解决方案,以防有人尝试类似的事情:

@Configuration
public class EurekaConfig {

    private static final Log logger = LogFactory.getLog(EurekaConfig.class);

    @Value("${containerIp}")
    private String containerIp;

    @Value("${kompositPort:7691}")
    private String kompositPort;

    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
        Integer hostPort = new RestTemplate().getForObject(
            "http://{containerIp}:{port}/container/{instanceId}/hostPort",
            Integer.class, 
            containerIp, 
            kompositPort, 
            getHostname());

        EurekaInstanceConfigBean config = new EurekaInstanceConfigBean();
        config.setNonSecurePort(hostPort);
        config.setPreferIpAddress(true);
        config.setIpAddress(containerIp);
        config.getMetadataMap().put("instanceId", getHostname());
        return config;
    }

    private static String getHostname() {
        String hostname = null;
        try {
            hostname = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            logger.error("Cannot get host info", e);
        }
        return hostname;
    }

}

【问题讨论】:

  • @AutoConfigureBefore 在用户配置类中无效,除非您实际注册自动配置。那是你在做什么吗?如果是这样,那么您应该更新问题,因为它很重要。如果不是,那么您的解决方案很冗长,而且大多是不必要的。
  • @Dave 你能详细说明一下吗?我的第一次尝试(编辑前的来源)没有奏效。我的 Eureka 实例配置 bean 已创建但未使用。我对编辑后部分的意图是创建一个EurekaInstanceConfigBean 之前 spring-cloud 提供的bean 已创建。至少它现在可以工作了 - 那么,您能否给我一个提示,我的解决方案的哪一部分是不必要的,以便我可以改进它?
  • 您在使用快照吗?我认为史蒂夫在下面提到的变化是相关的。您的 bean 正在被使用,但端口在初始化后被重新绑定到它。
  • @DaveSyer 我正在使用 RC3。由于史蒂夫所指的改变或多或少是我在我的代码中所做的,我认为你是对的。我会试一试,然后再回来。
  • @DaveSyer 我已经尝试过 1.0.0.RELEASE。完美运行。感谢您的出色工作。

标签: java spring spring-cloud


【解决方案1】:

已修复 only 6 days ago。在此修复之前,您为 nonSecurePort 设置的任何内容都将被 ${server.port} 覆盖。我的建议,这有点老套,但是在使用预发布库时你可以做什么,是继承EurekaInstanceConfigBean 并实现InitializingBean,这样你就可以在afterPropertiesSet() 中设置端口。

【讨论】:

  • 我不确定这是否真的是这里的问题。正如您从我发布的代码中看到的那样,我已经在构建自己的EurekaInstanceConfigBean。问题似乎是我的 bean 没有在自动配置过程中被选中。 (旁注:我没有使用边车)。
  • 现在有点晚了,但原因是 @Value 是在从 @Bean 方法返回 bean 之后处理的。因此,无论您在创建 bean 时做什么,nonSecurePort 都会在后处理期间被覆盖。 afterPropertiesSet() 在后处理后被调用,这是我建议的解决方法所利用的。
猜你喜欢
  • 2015-04-07
  • 2017-06-18
  • 1970-01-01
  • 2015-09-20
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多