# Spring Cloud Netflix

**3.1.1**

该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法，为 Spring 引导应用程序提供 Netflix OSS 集成。通过一些简单的注释，你可以快速启用和配置应用程序中的常见模式，并使用经过战斗测试的 Netflix 组件构建大型分布式系统。提供的模式包括服务发现。

## [](#service-discovery-eureka-clients)[1.服务发现：尤里卡客户](#service-discovery-eureka-clients)

服务发现是基于微服务的体系结构的关键原则之一。尝试手动配置每个客户机或某种形式的约定可能很难做到，并且可能很脆弱。Eureka 是 Netflix 的服务发现服务器和客户端。可以将服务器配置和部署为高度可用，每个服务器都将有关已注册服务的状态复制到其他服务器。

### [](#netflix-eureka-client-starter)[1.1.如何包含 Eureka 客户端](#netflix-eureka-client-starter)

要在项目中包含 Eureka 客户机，请使用组 ID 为`org.springframework.cloud`和工件 ID 为`spring-cloud-starter-netflix-eureka-client`的 starter。请参阅[Spring Cloud Project page](https://projects.spring.io/spring-cloud/)，以获取有关使用当前 Spring Cloud发布系列设置构建系统的详细信息。

### [](#registering-with-eureka)[1.2.在尤里卡注册](#registering-with-eureka)

当客户机向 Eureka 注册时，它会提供有关自身的元数据——例如主机、端口、健康指示器 URL、主页和其他详细信息。Eureka 从属于某个服务的每个实例接收心跳消息。如果心跳在可配置的时间表上失败，那么实例通常会从注册表中删除。

下面的示例展示了一个最小的 Eureka 客户机应用程序：

```
@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }

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

}
```

请注意，前面的示例显示了一个正常的[Spring Boot](https://projects.spring.io/spring-boot/)应用程序。通过在 Classpath 上具有`spring-cloud-starter-netflix-eureka-client`，你的应用程序将自动向 Eureka 服务器注册。需要配置来定位 Eureka 服务器，如以下示例所示：

应用程序.yml

```
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
```

在前面的示例中，`defaultZone`是一个 magic string fallback 值，它为不表示偏好的任何客户机提供服务 URL（换句话说，它是一个有用的默认值）。

|   |`defaultZone`属性是区分大小写的，并且需要大小写，因为`serviceUrl`属性是`Map<String, String>`。因此，`defaultZone`属性不遵循正常的 Spring 引导 snake-case 约定`default-zone`。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

默认的应用程序名称（即服务 ID）、虚拟主机和非安全端口（取自`Environment`）分别为`${spring.application.name}`、`${spring.application.name}`和`${server.port}`。

在 Classpath 上有`spring-cloud-starter-netflix-eureka-client`使应用程序既成为一个 Eureka“实例”（即它自己注册），也成为一个“客户端”（它可以查询注册中心以找到其他服务）。实例行为是由`eureka.instance.*`配置键驱动的，但是如果你确保应用程序的值为`spring.application.name`（这是 Eureka 服务 ID 或 VIP 的默认值），那么默认值就可以了。

有关可配置选项的更多详细信息，请参见[Eurekainstanconfigbean](https://github.com/spring-cloud/spring-cloud-netflix/tree/main/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java)和[EurekaclientConfigBean](https://github.com/spring-cloud/spring-cloud-netflix/tree/main/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java)。

要禁用 Eureka 发现客户端，可以将`eureka.client.enabled`设置为`false`。当`spring.cloud.discovery.enabled`被设置为`false`时，Eureka 发现客户端也将被禁用。

### [](#authenticating-with-the-eureka-server)[1.3.使用 Eureka 服务器进行身份验证](#authenticating-with-the-eureka-server)

如果`eureka.client.serviceUrl.defaultZone`URL 中有一个内嵌凭据（curl 样式，如下所示：`[user:[email protected]:8761/eureka](https://user:password@localhost:8761/eureka)`），则 HTTP Basic 身份验证将自动添加到 Eureka 客户机。对于更复杂的需求，可以创建`@Bean`类型的`DiscoveryClientOptionalArgs`，并将`ClientFilter`实例注入其中，所有这些都应用于从客户机到服务器的调用。

当 Eureka 服务器需要客户端证书来进行身份验证时，可以通过属性来配置客户端证书和信任存储区，如以下示例所示：

应用程序.yml

```
eureka:
  client:
    tls:
      enabled: true
      key-store: <path-of-key-store>
      key-store-type: PKCS12
      key-store-password: <key-store-password>
      key-password: <key-password>
      trust-store: <path-of-trust-store>
      trust-store-type: PKCS12
      trust-store-password: <trust-store-password>
```

`eureka.client.tls.enabled`需要为 true 才能启用 Eureka 客户端 TLS。当省略`eureka.client.tls.trust-store`时，将使用一个 JVM 默认信任存储区。`eureka.client.tls.key-store-type`和`eureka.client.tls.trust-store-type`的默认值是 pkcs12。如果省略了密码属性，则假定密码为空。

|   |由于 Eureka 中的限制，不可能支持每个服务器的基本身份验证凭据，因此只使用找到的第一组。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------|

如果你想定制 Eureka HTTP 客户端使用的 RESTTemplate，那么你可能想要创建`EurekaClientHttpRequestFactorySupplier`的 Bean，并为生成`ClientHttpRequestFactory`实例提供你自己的逻辑。

### [](#status-page-and-health-indicator)[1.4.状态页和健康指标](#status-page-and-health-indicator)

Eureka 实例的状态页和健康指示器分别默认为`/info`和`/health`，这是 Spring 引导执行器应用程序中有用端点的默认位置。你需要更改这些，即使对于执行器应用程序，如果你使用非默认的上下文路径或 Servlet 路径（例如`server.servletPath=/custom`），也需要更改这些内容。下面的示例显示了这两个设置的默认值：

应用程序.yml

```
eureka:
  instance:
    statusPageUrlPath: ${server.servletPath}/info
    healthCheckUrlPath: ${server.servletPath}/health
```

这些链接会显示在客户使用的元数据中，并在某些场景中用于决定是否将请求发送到应用程序，因此如果它们是准确的，则会很有帮助。

|   |在 Dalston 中，当更改<br/>管理上下文路径时，还需要设置状态和健康检查 URL。这一要求从 Edgware 开始就被删除了。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### [](#registering-a-secure-application)[1.5.注册安全应用程序](#registering-a-secure-application)

如果你的应用程序希望通过 HTTPS 进行联系，则可以在`EurekaInstanceConfigBean`中设置两个标志：

* `eureka.instance.[nonSecurePortEnabled]=[false]`

* `eureka.instance.[securePortEnabled]=[true]`

这样做使得 Eureka 发布实例信息，显示出对安全通信的明确偏好。 Spring 对于以这种方式配置的服务，云`DiscoveryClient`总是返回一个以`https`开头的 URI。类似地，当以这种方式配置服务时，Eureka（本地）实例信息具有安全的健康检查 URL。

由于 Eureka 的内部工作方式，它仍然为状态和主页发布一个非安全的 URL，除非你也显式地覆盖这些 URL。你可以使用占位符来配置 Eureka 实例 URL，如下例所示：

应用程序.yml

```
eureka:
  instance:
    statusPageUrl: https://${eureka.hostname}/info
    healthCheckUrl: https://${eureka.hostname}/health
    homePageUrl: https://${eureka.hostname}/
```

（请注意，`${eureka.hostname}`是一个本机占位符，仅在 Eureka 的后续版本中可用。你也可以使用 Spring 占位符实现同样的功能——例如，通过使用`${eureka.instance.hostName}`。

|   |如果你的应用程序运行在代理之后，并且 SSL 终止在代理中（例如，如果你在 Cloud Foundry 或其他平台即服务中运行），然后，你需要确保代理“转发”头文件被应用程序拦截并处理。<br/>如果嵌入在 Spring 启动应用程序中的 Tomcat 容器对“X-forwarded-\\*”头文件有明确的配置，则会自动发生这种情况。<br/>应用程序向自身呈现的链接是错误的（错误的主机，Port 或 Protocol）是你错误配置的标志。|
|---| |

### [](#eurekas-health-checks)[1.6.尤里卡的健康检查](#eurekas-health-checks)

默认情况下，Eureka 使用客户端心跳来确定客户端是否启动。除非另有指定，否则发现客户端不会根据 Spring 引导执行器传播应用程序的当前健康检查状态。因此，在成功注册之后，Eureka 总是宣布该应用程序处于“启动”状态。可以通过启用 Eureka 健康检查来改变此行为，从而将应用程序状态传播到 Eureka。因此，其他所有应用程序都不会将流量发送到其他“向上”状态的应用程序。下面的示例展示了如何为客户机启用健康检查：

应用程序.yml

```
eureka:
  client:
    healthcheck:
      enabled: true
```

|   |`eureka.client.healthcheck.enabled=true`应该只设置在`应用程序.yml`中。在`bootstrap.yml`中设置该值会导致不良的副作用，例如在 Eureka 中使用`UNKNOWN`状态注册。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

如果你需要对健康检查进行更多的控制，请考虑实现你自己的`com.netflix.appinfo.HealthCheckHandler`。

### [](#eureka-metadata-for-instances-and-clients)[1.7.用于实例和客户机的 Eureka 元数据](#eureka-metadata-for-instances-and-clients)

值得花一些时间来了解 Eureka 元数据是如何工作的，这样你就可以以一种在你的平台中有意义的方式使用它。对于诸如主机名、IP 地址、端口号、状态页和健康检查等信息，有标准的元数据。它们发布在服务注册中心中，并由客户机使用，以一种简单的方式与服务联系。可以在`eureka.instance.metadataMap`中将其他元数据添加到实例注册中，并且可以在远程客户端中访问此元数据。通常，附加的元数据不会改变客户机的行为，除非使客户机意识到元数据的含义。有几个特殊情况（在本文后面描述），其中 Spring Cloud 已经为元数据映射分配了含义。

#### [](#using-eureka-on-cloud-foundry)[1.7.1.在 Cloud Foundry 上使用 Eureka](#using-eureka-on-cloud-foundry)

Cloud Foundry 有一个全球路由器，因此同一应用程序的所有实例都具有相同的主机名（具有类似架构的其他 PaaS 解决方案具有相同的安排）。这不一定是使用 Eureka 的障碍。但是，如果你使用路由器（根据你的平台设置方式，推荐甚至强制使用），则需要显式地设置主机名和端口号（安全或非安全），以便它们使用路由器。你可能还希望使用实例元数据，以便能够区分客户机上的实例（例如，在自定义负载均衡器中）。默认情况下，`eureka.instance.instanceId`是`vcap.application.instance_id`，如下例所示：

应用程序.yml

```
eureka:
  instance:
    hostname: ${vcap.application.uris[0]}
    nonSecurePort: 80
```

根据在 Cloud Foundry 实例中设置安全规则的方式，你可能能够注册并使用主机 VM 的 IP 地址进行直接的服务到服务调用。此功能在 Pivotal Web 服务上还不可用（[PWS](https://run.pivotal.io)）。

#### [](#using-eureka-on-aws)[1.7.2.在 AWS 上使用 Eureka](#using-eureka-on-aws)

如果计划将应用程序部署到 AWS 云中，那么必须将 Eureka 实例配置为 AWS 感知的。你可以通过如下方式定制[Eurekainstanconfigbean](https://github.com/spring-cloud/spring-cloud-netflix/tree/main/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java)来实现此目的：

```
@Bean
@Profile("!default")
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) {
  EurekaInstanceConfigBean bean = new EurekaInstanceConfigBean(inetUtils);
  AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");
  bean.setDataCenterInfo(info);
  return bean;
}
```

#### [](#changing-the-eureka-instance-id)[1.7.3.更改 Eureka 实例 ID](#changing-the-eureka-instance-id)

一个普通的 Netflix Eureka 实例注册的 ID 等于其主机名（也就是说，每个主机只有一个服务）。 Spring Cloud Eureka 提供了一个合理的默认值，其定义如下：

`${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}`

一个例子是`myhost:myappname:8080`。

通过使用 Spring Cloud，你可以通过在`eureka.instance.instanceId`中提供唯一的标识符来覆盖该值，如下例所示：

应用程序.yml

```
eureka:
  instance:
    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
```

使用前面示例中显示的元数据和在 LocalHost 上部署的多个服务实例，将在其中插入随机值，以使实例是唯一的。在 Cloud Foundry 中，`vcap.application.instance_id`在 Spring 引导应用程序中自动填充，因此不需要随机值。

### [](#using-the-eurekaclient)[1.8.使用 Eurekaclient](#using-the-eurekaclient)

一旦你拥有了一个作为发现客户机的应用程序，就可以使用它从[尤里卡服务器](#spring-cloud-eureka-server)中发现服务实例。这样做的一种方法是使用本机`com.netflix.discovery.EurekaClient`（而不是 Spring Cloud`DiscoveryClient`），如以下示例所示：

```
@Autowired
private EurekaClient discoveryClient;

public String serviceUrl() {
    InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
    return instance.getHomePageUrl();
}
```

|   |不要在`@PostConstruct`方法或`@Scheduled`方法（或尚未启动`ApplicationContext`的任何地方）中使用`EurekaClient`。<br/>它是在`SmartLifecycle`中初始化的（带有`phase=0`），因此，最早可以依赖它的是在另一个具有更高相位的`SmartLifecycle`中。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### [](#eurekaclient-with-jersey)[1.8.1.穿着球衣的 Eurekaclient](#eurekaclient-with-jersey)

默认情况下，Eurekaclient 使用 Spring 的`RestTemplate`进行 HTTP 通信。如果希望使用 Jersey，则需要将 Jersey 依赖项添加到 Classpath 中。下面的示例显示了你需要添加的依赖关系：

```
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
</dependency>
<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-apache-client4</artifactId>
</dependency>
```

### [](#alternatives-to-the-native-netflix-eurekaclient)[1.9.原生 Netflix Eurekaclient 的替代品](#alternatives-to-the-native-netflix-eurekaclient)

你不需要使用原始的 Netflix`EurekaClient`。而且，通常在某种包装纸后面使用它会更方便。 Spring Cloud通过逻辑 Eureka 服务标识符（VIPS）而不是物理 URL 支持（REST 客户端构建器）和[[[ Spring ]（# Spring-cloud-ribbon）。

你也可以使用`org.springframework.cloud.client.discovery.DiscoveryClient`，它为 Discovery 客户端提供了一个简单的 API（不特定于 Netflix），如以下示例所示：

```
@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
    if (list != null && list.size() > 0 ) {
        return list.get(0).getUri();
    }
    return null;
}
```

### [](#why-is-it-so-slow-to-register-a-service)[1.10.为什么注册服务这么慢？](#why-is-it-so-slow-to-register-a-service)

作为一个实例，注册中心还需要一个周期性的心跳（通过客户机的`serviceUrl`），默认持续时间为 30 秒。在实例、服务器和客户机的本地缓存中都有相同的元数据（因此可能需要 3 次心跳）之前，客户端无法发现服务。你可以通过设置`eureka.instance.leaseRenewalIntervalInSeconds`来更改句号。将它设置为小于 30 的值可以加快客户连接到其他服务的过程。在生产中，最好坚持使用默认值，因为服务器中的内部计算对租赁续约期进行了假设。

### [](#zones)[1.11.区域](#zones)

如果你已经将 Eureka 客户机部署到多个区域，那么你可能希望这些客户机在尝试另一个区域中的服务之前，先在同一个区域中使用服务。要设置它，你需要正确配置你的 Eureka 客户机。

首先，你需要确保每个区域都部署了 Eureka 服务器，并且它们是彼此的对等服务器。有关更多信息，请参见[区域和区域](#spring-cloud-eureka-server-zones-and-regions)一节。

接下来，你需要告诉尤里卡你的服务在哪个区域。你可以通过使用`metadataMap`属性来实现这一点。例如，如果`service 1`被部署到`zone 1`和`zone 2`，则需要在`service 1`中设置以下 Eureka 属性：

**1 区服务 1**

```
eureka.instance.metadataMap.zone = zone1
eureka.client.preferSameZoneEureka = true
```

**2 区服务 1**

```
eureka.instance.metadataMap.zone = zone2
eureka.client.preferSameZoneEureka = true
```

### [](#refreshing-eureka-clients)[1.12.刷新 Eureka 客户端](#refreshing-eureka-clients)

默认情况下，`EurekaClient` Bean 是可刷新的，这意味着可以更改和刷新 Eureka 客户机属性。当刷新发生时，客户端将从 Eureka 服务器上被取消注册，并且可能会有一个短暂的时刻，其中给定服务的所有实例都不可用。避免这种情况发生的一种方法是禁用刷新 Eureka 客户机的功能。要执行此设置`eureka.client.refresh.enable=false`。

### [](#using-eureka-with-spring-cloud-loadbalancer)[1.13. Using Eureka with Spring Cloud LoadBalancer](#using-eureka-with-spring-cloud-loadbalancer)

我们为 Spring Cloud LoadBalancer`ZonePreferenceServiceInstanceListSupplier`提供支持。来自 Eureka 实例元数据（`eureka.instance.metadataMap.zone`）的`zone`值用于设置`spring-cloud-loadbalancer-zone`属性的值，该属性用于按区域筛选服务实例。

如果缺少此项，并且如果`spring.cloud.loadbalancer.eureka.approximateZoneFromHostname`标志设置为`true`，则可以使用来自服务器主机名的域名作为该区域的代理。

如果没有其他区域数据源，则根据客户机配置（而不是实例配置）进行猜测。我们使用`eureka.client.availabilityZones`，这是从区域名称到区域列表的映射，并为实例自己的区域（即`eureka.client.region`，默认为“US-East-1”，以兼容原生 Netflix）拉出第一个区域。

## [](#spring-cloud-eureka-server)[2.服务发现：Eureka 服务器](#spring-cloud-eureka-server)

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

### [](#netflix-eureka-server-starter)[2.1.如何包含 Eureka 服务器](#netflix-eureka-server-starter)

要在项目中包含 Eureka 服务器，请使用组 ID 为`org.springframework.cloud`和工件 ID 为`spring-cloud-starter-netflix-eureka-server`的 starter。请参阅[Spring Cloud Project page](https://projects.spring.io/spring-cloud/)以获取有关使用当前 Spring Cloud发布列设置构建系统的详细信息。

|   |如果你的项目已经使用 ThymeLeaf 作为其模板引擎，那么 Eureka 服务器的 Freemarker 模板可能无法正确加载。在这种情况下，需要手动配置模板加载器：|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

application.yml

```
spring:
  freemarker:
    template-loader-path: classpath:/templates/
    prefer-file-system-access: false
```

### [](#spring-cloud-running-eureka-server)[2.2.如何运行 Eureka 服务器](#spring-cloud-running-eureka-server)

下面的示例展示了一个最小的 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 端点。

以下链接有一些 Eureka 背景读数：[磁通电容器](https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer)和[谷歌小组讨论](https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0)。

|   |由于 Gradle 的依赖关系解析规则和缺乏父 BOM 功能，依赖于`spring-cloud-starter-netflix-eureka-server`可能会导致应用程序启动失败。<br/>要解决此问题，请添加 Spring boot Gradle 插件并按以下方式导入 Spring Cloud启动父 BOM:<br/><br/>build. Gradle <br/><br/>```<br/>buildscript {<br/>  dependencies {<br/>    classpath("org.springframework.boot:spring-boot-gradle-plugin:{spring-boot-docs-version}")<br/>  }<br/>}<br/><br/>apply plugin: "spring-boot"<br/><br/>dependencyManagement {<br/>  imports {<br/>    mavenBom "org.springframework.cloud:spring-cloud-dependencies:{spring-cloud-version}"<br/>  }<br/>}<br/>```|
|---| |

### [](#spring-cloud-eureka-server-zones-and-regions)[2.3.高可用性、区域和区域](#spring-cloud-eureka-server-zones-and-regions)

Eureka 服务器没有后端存储，但是注册表中的服务实例都必须发送心跳以保持其注册的最新状态（因此可以在内存中完成）。客户机还具有 Eureka 注册的内存缓存（因此，对于服务的每一个请求，客户机都不需要访问注册表）。

默认情况下，每个 Eureka 服务器也是一个 Eureka 客户机，并且需要（至少一个）服务 URL 来定位对等方。如果你不提供它，那么该服务就会运行并正常工作，但是它会在你的日志中充满大量关于无法向对等方注册的噪音。

### [](#spring-cloud-eureka-server-standalone-mode)[2.4.独立模式](#spring-cloud-eureka-server-standalone-mode)

这两个缓存（客户机和服务器）和心跳的结合，使得独立的 Eureka 服务器能够很好地抵御故障，只要有某种监视器或弹性运行时（例如 Cloud Foundry）来保持它的活力。在独立模式下，你可能更喜欢关闭客户端行为，这样它就不会继续尝试而无法与其对等方联系。下面的示例展示了如何关闭客户端行为：

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`指向与本地实例相同的主机。

### [](#spring-cloud-eureka-server-peer-awareness)[2.5.同伴意识](#spring-cloud-eureka-server-peer-awareness)

通过运行多个实例并要求它们彼此注册，可以使 Eureka 更具弹性和可用性。实际上，这是默认的行为，因此要使其工作，你所需要做的就是向对等方添加一个有效的`serviceUrl`，如下面的示例所示：

application.yml（两个对等的 Eureka 服务器）

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

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

在前面的示例中，我们有一个 YAML 文件，通过在不同的 Spring 配置文件中运行它，可以使用该文件在两个主机上运行相同的服务器（`peer1`和`peer2`）。通过操纵`/etc/hosts`来解析主机名，你可以使用此配置来测试单个主机上的对等感知（在生产中这样做没有太大价值）。实际上，如果你在知道自己的主机名的机器上运行`eureka.instance.hostname`，则不需要`eureka.instance.hostname`（默认情况下，通过使用`java.net.InetAddress`来查找它）。

你可以向系统中添加多个对等节点，并且，只要它们都通过至少一个边缘彼此连接，它们就会在它们之间同步注册。如果对等点在物理上是分开的（在一个数据中心内部或多个数据中心之间），那么原则上，系统可以经受住“分裂大脑”式的故障。你可以向系统中添加多个对等节点，并且只要它们都直接相互连接，它们就会在它们之间同步注册。

应用程序.yml（三个对等的 Eureka 服务器）

```
eureka:
  client:
    serviceUrl:
      defaultZone: https://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
```

### [](#spring-cloud-eureka-server-prefer-ip-address)[2.6.何时选择 IP 地址](#spring-cloud-eureka-server-prefer-ip-address)

在某些情况下，对 Eureka 来说，更好的方法是宣传服务的 IP 地址，而不是主机名。将`eureka.instance.preferIpAddress`设置为`true`，并且，当应用程序向 Eureka 注册时，它使用其 IP 地址而不是其主机名。

|   |如果主机名不能由 Java 确定，则将 IP 地址发送到 Eureka。<br/>设置主机名的唯一方法是通过设置`eureka.instance.hostname`属性。<br/>你可以在运行时使用环境变量设置你的主机名——例如，`eureka.instance.hostname=${HOST_NAME}`。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### [](#securing-the-eureka-server)[2.7.保护 Eureka 服务器](#securing-the-eureka-server)

你只需通过`spring-boot-starter-security`将 Spring 安全性添加到你的服务器的 Classpath，就可以保护你的 Eureka 服务器。默认情况下，当 Spring 安全性在 Classpath 上时，它将要求在向应用程序发送每个请求时都发送一个有效的 CSRF 令牌。Eureka 客户机通常不会拥有有效的跨站点请求伪造令牌，你将需要为`/eureka/**`端点禁用此要求。例如：

```
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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

有关 CSRF 的更多信息，请参见[Spring Security documentation](https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf)。

可以在 Spring Cloud样本[repo](https://github.com/spring-cloud-samples/eureka/tree/Eureka-With-Security)中找到演示 Eureka 服务器。

### [](#jdk-11-support)[2.8.JDK11 支援](#jdk-11-support)

在 JDK11 中删除了 Eureka 服务器所依赖的 JAXB 模块。如果打算在运行 Eureka 服务器时使用 JDK11，则必须在 POM 或 Gradle 文件中包含这些依赖关系。

```
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
</dependency>
```

## [](#configuration-properties)[3.配置属性](#configuration-properties)

要查看所有 Spring Cloud Netflix 相关配置属性的列表，请检查[附录页](appendix.html)。

如果{{{i[’GoogleAnalyticsObject’]=r；i[r]=i[r]|function（）{q=i[r].push（参数）}，i[r].l=1\*new date（）；a=s.createElement（o），m=s.getelementsbyName（0）；a.parentsName（1）；a.A.SRC=g；m.M.analytnode（gua，m.com.com）；（google=document=’，’，’’’’’’’’），’documents’，’’.’’’’’’’’’’’，’’’’’’