12. 服务发现:Eureka Server

本节介绍如何设置 Eureka 服务器。

12.1 如何包含 Eureka Server

要在项目中包含 Eureka Server,请使用 group ID 为org.springframework.cloud且 artifact ID 为spring-cloud-starter-netflix-eureka-server的 starter。有关使用当前 Spring Cloud Release Train 设置 build 系统的详细信息,请参阅Spring Cloud 项目页面

12.2 如何运行 Eureka 服务器

以下 example 显示了一个最小的 Eureka 服务器:

@SpringBootApplication
@EnableEurekaServer
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

服务器有一个主页,其中包含用于/eureka/*下常规 Eureka 功能的 UI 和 HTTP API endpoints。

以下链接有一些 Eureka 背景阅读:磁通电容器google group 讨论

由于 Gradle 的依赖关系解析规则和缺少 parent bom feature,取决于spring-cloud-starter-netflix-eureka-server可能会导致 application 启动失败。要解决此问题,请添加 Spring Boot Gradle 插件并 import Spring cloud starter parent bom,如下所示:

build.gradle.

buildscript {
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-docs-version}")
  }
}

apply plugin: "spring-boot"

dependencyManagement {
  imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:{spring-cloud-version}"
  }
}

12.3 高可用性,区域和区域

Eureka 服务器没有后端 store,但是注册表中的服务实例都必须发送心跳以使其注册达到 date(因此可以在 memory 中完成)。 Clients 还有一个_E缓存的 Eureka 注册(因此他们不必为每个服务请求转到注册表)。

默认情况下,每个 Eureka 服务器也是 Eureka client,并且需要(至少一个)服务 URL 来定位对等方。如果您不提供该服务,该服务将运行并正常运行,但它会在您的日志中填充很多关于无法向对等方注册的噪音。

另请参阅 client 侧的以下是 Ribbon 支持的详细信息以了解区域和区域。

12.4 独立模式

两个缓存(client 和服务器)和心跳的组合使得独立的 Eureka 服务器对故障具有相当的弹性,因为存在某种类型的监视器或 elastic 运行时(例如 Cloud Foundry)使其保持活动状态。在独立模式下,您可能更愿意关闭 client 端行为,以便它不会继续尝试并且无法访问其对等方。以下 example 显示了如何关闭 client-side 行为:

application.yml(独立 Eureka 服务器).

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

请注意,serviceUrl指向与本地实例相同的 host。

12.5 同侪意识

通过 running 多个实例并要求他们相互注册,Eureka 可以变得更有弹性和可用性。实际上,这是默认行为,因此要使其工作所需要做的就是向对等体添加有效的serviceUrl,如下面的示例所示:

application.yml(两个 Peer Aware Eureka 服务器).

---
spring:
  profiles: peer1
eureka:
  instance:
    hostname: peer1
  client:
    serviceUrl:
      defaultZone: http://peer2/eureka/

---
spring:
  profiles: peer2
eureka:
  instance:
    hostname: peer2
  client:
    serviceUrl:
      defaultZone: http://peer1/eureka/

在前面的 example 中,我们有一个 YAML 文件,可以通过在不同的 Spring profiles 中运行它来在两个主机(peer1peer2)上运行相同的服务器。您可以使用此 configuration 通过操作/etc/hosts来解析 host 名称来测试单个 host 上的对等感知(在 production 中执行该操作时没有太多 value)。实际上,如果您在知道自己的主机名的计算机上运行,则不需要eureka.instance.hostname(默认情况下,使用java.net.InetAddress进行查找)。

您可以将多个对等体添加到系统中,并且,由于它们通过至少一个边缘彼此连接,因此它们在它们之间同步注册。如果对等体在物理上是分开的(在数据中心内或在多个数据中心之间),那么系统原则上可以存在“split-brain”类型故障。您可以将多个对等体添加到系统中,并且由于它们彼此直接相连,因此它们将在它们之间同步注册。

application.yml(三个同行意识 Eureka 服务器).

eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/

---
spring:
  profiles: peer1
eureka:
  instance:
    hostname: peer1

---
spring:
  profiles: peer2
eureka:
  instance:
    hostname: peer2

---
spring:
  profiles: peer3
eureka:
  instance:
    hostname: peer3

12.6 何时首选 IP 地址

在某些情况下,Eureka 最好宣传服务的 IP 地址而不是主机名。将eureka.instance.preferIpAddress设置为true,当 application 向 eureka 注册时,它使用其 IP 地址而不是其主机名。

如果 Java 无法确定主机名,则将 IP 地址发送到 Eureka。只有设置主机名的明确方法是设置eureka.instance.hostname property。您可以使用环境变量在 run-time 设置主机名 - 对于 example,eureka.instance.hostname=${HOST_NAME}

12.7 保护 Eureka 服务器

只需将 Spring Security 通过spring-boot-starter-security添加到服务器的 classpath 即可保护 Eureka 服务器。默认情况下,当 Spring Security 位于 classpath 时,它将要求每次向应用程序发送请求时都会发送一个有效的 CSRF 令牌。 Eureka clients 通常不会拥有有效的跨站点请求伪造(CSRF)令牌,您需要为/eureka/** endpoints 禁用此要求。例如:

@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().ignoringAntMatchers("/eureka/**");
        super.configure(http);
    }
}

有关 CSRF 的更多信息,请参阅Spring Security 文档

可以在 Spring Cloud Samples repo中找到演示 Eureka 服务器。