Spring Cloud Eureka 服务器没有相互复制,显示警告

Posted

技术标签:

【中文标题】Spring Cloud Eureka 服务器没有相互复制,显示警告【英文标题】:Spring cloud Eureka server is NOT replicating each other, displaying warning 【发布时间】:2015-11-25 02:14:54 【问题描述】:

我在spring cloud中使用两台Eureka服务器互相复制,当我打开http://localhost:8761的页面时,看到了这样的信息:

续订低于阈值。自我保护模式已关闭。这可能无法在网络/其他问题的情况下保护实例到期。

eureka application.xml 是这样的:

server:
  port: $server.instance.port:5678
spring:
  application:
    name: nodeservice

sidecar:
  port: $nodeserver.instance.port:3000
  health-uri: http://localhost:$nodeserver.instance.port:3000/health.json

eureka:
  instance:
    hostname: $nodeserver.instance.name:localhost
    preferIpAddress: $preferipaddress:false
    leaseRenewalIntervalInSeconds: 5 #default is 30, recommended to keep default
    metadataMap:
      instanceId: $spring.application.name:$spring.application.instance_id:$random.value
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

所以如果我去http://localhost:8761,我会看到所有注册的服务,但如果我去http://localhost:8762,我会看到没有注册微服务。

知道为什么吗?

【问题讨论】:

警告与eureka注册的服务实例数量有关,与eureka复制无关。 查看这个 SO 问题以了解如何设置对等复制:***.com/questions/30288959/… 【参考方案1】:

Eureka:只注册第一个成功的url。在您的情况下,第一个成功 url 是 http://localhost:8761/eureka/ 所以它不会继续注册下一个 url http://localhost:8762/eureka/。

您可以通过以下方式覆盖它:

Application.yml

 eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
      additionalZones: http://localhost:8762/eureka

你的 Application.java

@SpringBootApplication
@EnableEurekaClient
public class Application implements ApplicationContextAware 


    @Value("$eureka.client.serviceUrl.additionalZones:")
    String additionalZones;

    ConfigurableApplicationContext applicationContext;

    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
    

    @Bean
    public Map<String, EurekaClient> additionalEurekaClients(ApplicationInfoManager manager,
                                                             @Autowired(required = false) HealthCheckHandler healthCheckHandler) 
        HashMap clients = new HashMap<>();

        if(Text.isEmpty(additionalZones))
            return clients;

        String[] hosts = additionalZones.split(",");
        for(int i=0; i < hosts.length; i++)
        
            EurekaClient client = new CloudEurekaClient(manager, new SimpleEurekaClientConfig(hosts[i].trim(),"defaultZone"), null,
                    this.applicationContext);
            client.registerHealthCheck(healthCheckHandler);
            String clientName = "client_"+ (i+1);
            clients.put(clientName, client);
        

        return clients;
    


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
    


    @PreDestroy
    public void unRegisterInAllConfiguredDiscovery() 
        Map<String, EurekaClient> additionalEurekaClients = this.applicationContext.getBean("additionalEurekaClients", Map.class);
        additionalEurekaClients.forEach((k, v) -> v.shutdown());
    

SimpleEurekaClient.java

package com.netflix.eureka;

import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import java.util.Arrays;
import java.util.List;

public class SimpleEurekaClientConfig extends EurekaClientConfigBean 

    private String eurekaUrl;
    private String zone;
    private String region = "us-east-1";

    public SimpleEurekaClientConfig(String eurekaUrl, String zone, String region) 
        this.eurekaUrl = eurekaUrl;
        this.zone = zone;
        this.region = region;
    

    public SimpleEurekaClientConfig(String eurekaUrl, String zone) 
        this.eurekaUrl = eurekaUrl;
        this.zone = zone;
    


    @Override
    public String getRegion() 
        return region;
    

    @Override
    public String[] getAvailabilityZones(String s) 
        return new String[] zone;
    

    @Override
    public List<String> getEurekaServerServiceUrls(String s) 
        return Arrays.asList(eurekaUrl);
    

    @Override
    public boolean shouldEnforceRegistrationAtInit() 
        return true;
    

    @Override
    public boolean shouldRegisterWithEureka() 
        return true;
    

【讨论】:

请问SimpleEurekaClientConfig是什么?您是创建了配置接口的实现还是位于另一个依赖项中? @Nenad 是的,这是我的实现。我更新了回复以包含 SimpleEurekaClientConfig 的代码。谢谢 @mostafacs 感谢您的示例,它的工作原理,但是当关闭客户端时,它只对defaultZone 起作用,而不是additionalZones,它仍然显示 UP 实例。 @Yougesh 你能创建一个有同样问题的演示项目吗?那我可以帮忙。谢谢。 @mostafacs 我在 repo 中创建了示例,并添加了 README.md 来运行项目。 github.com/ypkkhatri/sb-eureka-multi-zone-example【参考方案2】:

这不是 XML,您需要将其重命名为“application.YML”

https://en.wikipedia.org/wiki/YAML

【讨论】:

以上是关于Spring Cloud Eureka 服务器没有相互复制,显示警告的主要内容,如果未能解决你的问题,请参考以下文章

Spring-cloud微服务实战:eureka注册中心(下)

spring cloud eureka高可用

spring cloud 之eureka配置

Spring Cloud Eureka - 集群间数据同步

spring cloud 之 Eureka

spring cloud深入学习-----服务消费