服务发现是基于微服务体系结构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能很难做到,而且可能很脆弱。Eureka 是 Netflix 服务发现服务器和客户端。可以将服务器配置和部署为高可用,每个服务器都将注册服务的状态复制到其他服务器。
要在项目中包含 Eureka 客户端,请使用 group ID 为 当客户端注册到 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 应用程序。通过让 application.yml. eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ 在前面的示例中,"defaultZone" 是一个神奇的字符串回退值,它为任何不表示首选项的客户端提供服务 URL(换句话说,它是一个有用的默认值)。
默认应用程序名(即服务 ID)、虚拟主机和非安全端口(取自
将 配置可选项的更多细节请参阅 EurekaInstanceConfigBean 和 EurekaClientConfigBean。
要禁用 Eureka Discovery 客户端,可以将
如果其中一个
Eureka 实例的状态页和健康指示器分别默认为 application.yml. eureka: instance: statusPageUrlPath: ${server.servletPath}/info healthCheckUrlPath: ${server.servletPath}/health 这些链接显示在客户端使用的元数据中,并在某些场景中用于决定是否向应用程序发送请求,因此,如果它们是准确的,则很有帮助。
如果你的应用程序希望通过 HTTPS 联系,可以在
这样做会使 Eureka 发布实例信息,显示对安全通信的明确偏好。对于以这种方式配置的服务,Spring Cloud 由于 Eureka 在内部的工作方式,它仍然为状态和主页发布一个不安全的 URL,除非你也明确地覆盖这些 URL。可以使用占位符配置 Eureka 实例 URL,如下例所示: application.yml. eureka: instance: statusPageUrl: https://${eureka.hostname}/info healthCheckUrl: https://${eureka.hostname}/health homePageUrl: https://${eureka.hostname}/
(注意,
默认情况下,Eureka 使用客户端心跳来确定客户端是否启动。除非另有规定,否则发现客户端不会根据 Spring Boot 执行器传播应用程序的当前健康检查状态。因此,注册成功后,Eureka 总是宣布应用程序处于 'UP' 状态。通过启用 Eureka 健康检查可以更改此行为,这将导致向 Eureka 传播应用程序状态。因此,每个其他应用程序都不会将流量发送到除 'UP' 之外的其他状态的应用程序。以下示例显示如何为客户端启用健康检查: application.yml. eureka: client: healthcheck: enabled: true
如果你需要对健康检查进行更多控制,请考虑实现自己的
花点时间了解 Eureka 元数据的工作原理是值得的,因此你可以以一种在你的平台中有意义的方式使用它。对于主机名、IP 地址、端口号、状态页和健康检查等信息,有标准的元数据。它们在服务注册中心发布,客户端使用它们直接联系服务。可以将其他元数据添加到
Cloud Foundry 具有全局路由器,因此同一应用程序的所有实例都具有相同的主机名(具有类似架构的其他 PaaS 解决方案具有相同的安排)。这不一定是使用 Eureka 的障碍。但是,如果使用路由器(根据平台的设置方式,建议甚至是强制使用),则需要显式设置主机名和端口号(安全或不安全),以便它们使用路由器。你可能还希望使用实例元数据,以便能够区分客户端上的实例(例如,在自定义负载平衡器中)。默认情况下, application.yml. eureka: instance: hostname: ${vcap.application.uris[0]} nonSecurePort: 80 根据在你的 Cloud Foundry 实例中设置安全规则的方式,你可能能够注册并使用主机 VM 的 IP 地址进行直接服务到服务的调用。此功能在 Pivotal Web Services(PWS)上尚不可用。 如果计划将应用程序部署到 AWS 云,则必须将 Eureka 实例配置为支持 AWS。你可以通过以下方式自定义 EurekaInstanceConfigBean 来完成此操作: @Bean @Profile("!default") public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) { EurekaInstanceConfigBean b = new EurekaInstanceConfigBean(inetUtils); AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka"); b.setDataCenterInfo(info); return b; } 普通的 Netflix Eureka 实例的注册 ID 等于其主机名(即,每个主机只有一个服务)。Spring Cloud Eureka 提供了一个合理的默认值,其定义如下:
一个例子是
通过使用 Spring Cloud,你可以通过在 application.yml. eureka: instance: instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
使用前面示例中展示的元数据和部署在本地主机上的多个服务实例,将在其中插入随机值以使实例唯一。在 Cloud Foundry 中,
一旦你有了一个作为发现客户端的应用程序,你就可以使用它从 Eureka Server 发现服务实例。一种方法是使用本地 @Autowired private EurekaClient discoveryClient; public String serviceUrl() { InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false); return instance.getHomePageUrl(); }
默认情况下,EurekaClient 使用 Jersey 进行 HTTP 通信。如果你希望避免依赖 Jersey,可以将其从依赖项中排除。Spring Cloud 基于 Spring <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <exclusions> <exclusion> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> </exclusion> <exclusion> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> </exclusion> <exclusion> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-apache-client4</artifactId> </exclusion> </exclusions> </dependency>
你不需要使用原始的 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; }
作为一个实例,还需要定期向注册表发送心跳(通过客户端的 如果你已经将 Eureka 客户端部署到多个区域,那么你可能更希望这些客户端在尝试在另一个区域中的服务之前使用同一区域中的服务。要设置它,你需要正确配置 Eureka 客户端。 首先,你需要确保将 Eureka 服务器部署到每个区域,并且它们彼此是对等的。有关的更多详细信息,请参阅有关区域和区域的部分。
接下来,你需要告诉 Eureka 你的服务在哪个区域。你可以使用 Service 1 in Zone 1 eureka.instance.metadataMap.zone = zone1 eureka.client.preferSameZoneEureka = true Service 1 in Zone 2 eureka.instance.metadataMap.zone = zone2 eureka.client.preferSameZoneEureka = true |