Spring 启动时 Netflix Eureka 发现的云配置服务器循环依赖

Spring Cloud Config Server Circular Dependency With Netflix Eureka Discovery on Startup

我正在关注此 tutorial,但我在确定服务的正确启动顺序以确保没有错误时遇到了一些问题(我需要对我的 Docker 蜂群正确初始化)。

我启动服务的顺序是:

  1. 配置服务:8081(spring 云)<- 尝试注册下一个
  2. 发现服务:8082 (eureka) <- 从之前的
  3. 获取其配置
  4. API 网关服务:8080 (Zuul)
  5. 图书服务:8083(示例教程应用程序)

如果我按照所写的教程完成教程,我将无法通过步骤 3.5,因为配置服务器从未注册到发现服务。我做了一些挖掘,发现配置服务器需要将其主要 class 注释为 @EnableEurekaClient 以便它定期 ping 发现服务以注册自己。

然后我在代码中添加了这个注解如下:

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient /* this line was missing */
public class ConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

application.properties 配置服务:

...
spring.application.name=config
# the following line was missing
spring.cloud.config.name=config
...

这样做之后我能够重新启动配置服务器并且一切都按预期工作,因为它在发现服务 中注册了自己,当我重新启动时它已经 运行使用我更新的代码的配置。

当我关闭所有服务,然后尝试使用我在开头列出的相同启动顺序时,我注意到配置服务器每次尝试注册发现服务时都会抛出一个连接错误。这对我来说非常有意义,因为发现服务还没有 运行。尽管如此,配置服务器似乎 运行 没问题,所以当我继续执行其余服务时,应用程序运行正常,一旦发现服务存在,配置服务器就会停止抛出错误。

所以我的问题分为 3 个部分:

  1. 我的假设是否正确,教程作者在省略 @EnableEurekaClient 注释和 spring.cloud.config.name 注册时犯了错误来自教程?
  2. 我是否应该忽略配置启动时的这个错误,因为它会在发现服务备份后自行解决并且微服务架构允许服务启动和关闭?
  3. 有没有办法打破发现服务依赖于发现服务的配置服务的循环依赖?我通过增加 eureka 的刷新间隔来减少配置错误的数量,这将第二个 ping 延迟到 eureka 启动之后,但我仍然在启动时遇到 1 个错误。

在教程中,他们启动了一个配置服务器,该服务器以静态 ip/port 存在并且不尝试查找发现。 然后他们启动发现服务。这允许发现服务使用来自静态配置服务器的配置。

在该场景中,虽然发现服务是 运行 - 配置服务器使用步骤 3.4 中引入的新 Eureka 配置重新启动。重新启动的配置服务器将自己注册到 Eureka(你是对的,这一步需要 @EnableEurekaClient 注释)。这允许其他服务通过其服务器 ID 而不是静态 ip/port.

来发现配置服务器

在这种情况下不会出现错误,因为配置服务器是作为静态服务启动的,它没有尝试最初注册发现。

您遇到的问题是您试图在没有完成创建静态配置服务器的第一步的情况下启动所有内容,因此您总是会收到带有尤里卡错误的初始注册。

如果你绝对必须避免这种情况,那么你可以做一些事情:
您可以将配置服务器保持在静态 ip/port 上并且不使用 eureka 注册它。这将要求您从服务配置中删除以下内容:

spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

并将它们替换为

spring.cloud.config.uri=http://static_ip:port

另一种选择是让 Eureka 保持静态 ip/port 并在其自己的 application.properties(或 yml)中定义配置并删除 spring 配置依赖从它的 pom。那么您的启动顺序将是 Eureka > 配置 > 其他服务。这将允许其他服务通过 id 识别配置服务器,eureka 将不会在外部查找配置。

另一种选择是按照教程稍作调整。 在名为 eureka.enabled=true

的服务器配置应用程序属性中有一个 属性

使用注解@ConditionalOnProperty(name="eureka.enabled")

创建一个 EurekaConfig class
@Configuration
@EnableEurekaClient
@ConditionalOnProperty(name="eureka.enabled")
public class EurekaConfig {
}

现在,当第一次启动您的应用程序时,请使用命令。

java -jar -Deureka.enabled=false path/to/config/server.jar

然后在 eureka 启动后,可以使用

终止配置服务器并再次启动

java -jar path/to/config/server.jar

第一个命令将在不查找 eureka 的情况下启动配置服务器,第二个命令将启动向 eureka 注册的配置服务器

如果使用 @ConditionalOnProperty 注释不起作用,您可以尝试另一种类似的方法(我使用的是 Spring Boot 2.0.1):

您可以通过在 application.properties 中将 属性 spring.cloud.service-registry.auto-registration.enabled 设置为 false 来禁用发现客户端自动注册,这样配置服务器就不会费心注册到Eureka 一上来。您 运行 以这种方式 .jar 文件(指定 属性 是可选的,因为您已经在属性文件中完成了):

java -jar -Dspring.cloud.service-registry.auto-registration.enabled=false config-server.jar

现在启动 Eureka 服务器,以便它获取配置。完成后,杀死配置服务器并重新运行它:

java -jar -Dspring.cloud.service-registry.auto-registration.enabled=true config-server.jar

这一次,config-server 会自动在 Eureka 中注册。