|
最新稳定版请使用Spring Cloud Netflix 5.0.0! |
春云 Netflix 特色
服务发现:尤里卡客户端
服务发现是基于微服务架构的关键原则之一。 试图手动配置每个客户端或某种约定方式可能很难,而且很脆弱。 Eureka 是 Netflix 服务发现服务器和客户端。 服务器可以配置和部署为高度可用,每个服务器将注册服务的状态复制给其他服务器。
如何包含Eureka客户端
要在项目中包含 Eureka 客户端,使用带有组 ID 的起始码org.springframework.cloud以及一个伪影IDSpring-cloud-starter-Netflix-Eureka-client.
请参阅 Spring Cloud Project 页面,了解如何使用当前的 Spring Cloud 发布列车来设置你的构建系统。
在Eureka注册
当客户端注册 Eureka 时,它会提供关于自身的元数据——如主机、端口、健康指示网址、主页及其他详细信息。 Eureka 会从属于某个服务的每个实例接收心跳消息。 如果心跳在可配置的时间表内失败,该实例通常会从注册表中移除。
以下示例展示了一个最小的Eureka客户端应用:
@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
SpringApplication.run(CustomerServiceTestApplication.class, args);
}
}
请注意,前面的示例展示了一个普通的 Spring Boot 应用程序。
通过Spring-cloud-starter-Netflix-Eureka-client在类路径上,你的应用程序会自动向Eureka服务器注册。定位Eureka服务器需要配置,如下示例所示:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
在上述例子中,默认区域是一个神奇字符串的退回值,它为任何不表达偏好的客户端提供服务URL(换句话说,它是有用的默认值)。
这默认区域财产是大小写区分的,需要骆驼壳,因为服务网址性质是映射<字符串,字符串>.因此,默认区域属性不遵循正常的Spring靴蛇壳约定默认区域. |
默认应用名称(即服务ID)、虚拟主机和非安全端口(取自环境)是${spring.application.name},${spring.application.name}和${server.port}分别。
拥有Spring-cloud-starter-Netflix-Eureka-client在类路径上,应用既是Eureka的“实例”(即它自己注册)也是“客户端”(它可以查询注册表以定位其他服务)。
实例行为由以下因素驱动尤里卡.实例。*配置键,但如果你确保应用有一个值,默认作是可以的spring.application.name(这是尤里卡服务ID或VIP的默认设置)。
有关可配置选项的详细信息,请参见 EurekaInstanceConfigBean 和 EurekaClientConfigBean。
要禁用Eureka发现客户端,可以设置Eureka.client.enabled自false.Eureka Discovery客户端也会被禁用spring.cloud.discovery.enabled设置为false.
目前不支持将 Spring Cloud Netflix Eureka 服务器的版本作为路径参数。这意味着你不能在上下文路径中设置版本 (eurekaServerURLContext).相反,你可以在服务器URL中包含版本(例如,你可以设置defaultZone: localhost:8761/eureka/v2). |
与Eureka服务器进行认证
如果eureka.client.serviceUrl.defaultZoneURLs中嵌入了凭证(卷曲风格,如下:用户:password@localhost:8761/Eureka).
对于更复杂的需求,你可以创建一个@Bean类型DiscoveryClientOptionalArgs并注入客户端过滤器所有这些应用都应用于客户端到服务器的调用。
当Eureka服务器要求客户端证书进行认证时,客户端证书和信任存储可以通过属性配置,如下示例所示:
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需要为真才能启用 Eureka 客户端 TLS。 什么时候Eureka.client.tls.trust-store省略,则使用JVM默认信任存储。默认值为eureka.client.tls.key商店类型和Eureka.client.tls.trust-store-type是PKCS12。当密码属性被省略时,假设密码为空。
| 由于 Eureka 的限制,无法支持每服务器的基本认证凭证,因此只使用最先找到的那一组。 |
如果你想自定义 Eureka HTTP 客户端使用的 RestTemplate,可能需要创建一个EurekaClientHttpRequestFactorySupplier并提供你自己的逻辑来生成ClientHttpRequestFactory实例。
Eureka HTTP 客户端所用的所有与 RestTemplate 相关的默认超时属性都设置为 3 分钟(与 Apache HC5 默认相符RequestConfig和SocketConfig).因此,要指定超时值,必须直接用属性指定值Eureka.client.rest-template-timeout. (所有超时属性均以毫秒为单位。)
eureka:
client:
rest-template-timeout:
connect-timeout: 5000
connect-request-timeout: 8000
socket-timeout: 10000
状态页面和健康指示器
Eureka实例的状态页面和健康指示默认为/信息和/健康分别是 Spring Boot 执行器应用中有用端点的默认位置。即使是执行器应用,如果你使用非默认上下文路径或 servlet 路径(例如server.servletPath=/custom). 以下示例展示了两种设置的默认值:
eureka:
instance:
statusPageUrlPath: ${server.servletPath}/info
healthCheckUrlPath: ${server.servletPath}/health
这些链接会出现在客户端使用的元数据中,在某些情况下用来决定是否向你的应用发送请求,所以如果它们准确无误会很有帮助。
| 在 Dalston 中,更改管理上下文路径时还必须设置状态和健康检查 URL。该管理上下文路径。该要求从 Edgware 开始被取消。 |
注册安全应用
如果你的应用想通过HTTPS联系,你可以在EurekaInstanceConfigBean:
-
eureka.instance。[nonSecurePortEnabled]=[false] -
eureka.instance。[securePortEnabled]=[true]
这样做会使Eureka发布显示对安全通信偏好的实例信息。春云发现客户端总是返回一个以https对于以这种方式配置的服务。同样,当服务以这种方式配置时,Eureka(本地)实例信息会有一个安全的健康检查 URL。
由于 Eureka 内部的工作方式,除非你明确覆盖这些页面,否则它仍然会发布一个不安全的状态和首页 URL。你可以使用占位符来配置 Eureka 实例的 URL,如下示例所示:
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 或其他平台中作为服务运行),那么你需要确保代理“转发”的头部被应用程序拦截并处理。如果 Spring Boot 应用中嵌入的 Tomcat 容器对“X-Forwarded-\*”头有明确配置,这会自动发生。应用与自身之间的链接错误(主机、端口或协议错误)表明配置错误。 |
尤里卡的健康检查
默认情况下,Eureka 使用客户端心跳来判断客户端是否已开启。除非另有说明,发现客户端不会根据Spring Boot执行器传播应用程序当前健康检查状态。因此,在成功注册后,Eureka 总是会宣布应用程序处于“UP”状态。通过启用 Eureka 健康检查,可以改变这种行为,从而将应用状态传播到 Eureka。因此,其他所有应用程序不会向状态以外的应用程序发送流量。以下示例展示了如何为客户端启用健康检查:
eureka:
client:
healthcheck:
enabled: true
Eureka.client.healthcheck.enabled=true只应该设置在application.yml.将值设置在bootstrap.yml会引起不良副作用,例如在Eureka中注册未知地位。 |
如果你需要对健康检查有更多控制权,可以考虑自己实施com.netflix.appinfo.健康检查处理员.
实例和客户端的Eureka元数据
花点时间了解Eureka元数据的工作原理是值得的,这样你才能在自己的平台上以合理的方式使用它。
有标准元数据用于存储主机名、IP地址、端口号、状态页面和健康检查等信息。
这些数据会发布在服务登记册中,客户通过这些信息直接联系服务。
可以在实例注册中添加额外的元数据eureka.instance.metadataMap,且这些元数据可在远程客户端访问。
一般来说,除非客户端知道元数据的含义,否则额外的元数据不会改变客户端的行为。
在文档后面会描述几个特殊情况,Spring Cloud 已经为元数据映射赋予了意义。
在Cloud Foundry上使用 Eureka
Cloud Foundry 有一个全局路由器,使同一应用的所有实例拥有相同的主机名(其他架构相似的 PaaS 解决方案也有同样的配置)。
这并不一定是使用Eureka的障碍。
不过,如果你使用路由器(根据你的平台设置,推荐甚至强制使用),你需要明确设置主机名和端口号(安全或非安全),让他们使用路由器。
你可能还想使用实例元数据,以便区分客户端上的实例(例如自定义负载均衡器中)。
默认情况下,eureka.instance.instanceId是vcap.application.instance_id如下例所示:
eureka:
instance:
hostname: ${vcap.application.uris[0]}
nonSecurePort: 80
根据你Cloud Foundry实例中安全规则的设置方式,你可能可以注册并使用主机虚拟机的IP地址进行服务对服务的直接调用。 此功能尚未在Pivotal Web Services(PWS)上提供。
在AWS上使用 Eureka
如果应用计划部署到 AWS 云端,Eureka 实例必须配置为 AWS 支持。您可以通过以下方式自定义 EurekaInstanceConfigBean 来实现:
@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;
}
更改Eureka实例ID
一个普通的Netflix Eureka实例注册的ID与其主机名相等(即每个主机只有一个服务)。 春云尤里卡提供了一个合理的默认,定义如下:
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}
一个例子是我的主持人:我的应用名:8080.
通过使用 Spring Cloud,你可以通过在 中提供唯一标识符来覆盖该值eureka.instance.instanceId如下例所示:
eureka:
instance:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
在前述示例中显示的元数据以及多个服务实例部署于localhost时,插入随机值以使实例唯一。
在云铸造厂中,vcap.application.instance_id在 Spring Boot 应用中会自动填充,因此不需要随机值。
使用 EurekaClient
一旦你拥有了一个作为发现客户端的应用,就可以用它来发现Eureka服务器上的服务实例。
一种方法是使用原生com.netflix.discovery.Eureka客户端(与春云相对发现客户端),如下例所示:
@Autowired
private EurekaClient discoveryClient;
public String serviceUrl() {
InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
return instance.getHomePageUrl();
}
|
不要使用 |
底层 HTTP 客户端
尤里卡客户端用途如下Rest模板,Web客户端或Jersey客户端引擎盖下。为了使用尤里卡客户端你需要在类路径上安装一个支持的HTTP客户端。
使用Rest模板加Spring Boot启动网对你的依赖。使用Web客户端加Spring BootStarters网流对你的依赖。如果两者都有Rest模板和Web客户端当 在类路径上时,eureka.client.webclient.enabled设置为true,Web客户端被使用。否则Rest模板被使用。
如果你想用 Jersey,你需要把 Jersey 依赖添加到你的类路径中。 以下示例展示了你需要添加的依赖关系:
<dependencies>
<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>
</dependencies>
如果你有Jersey客户端在类路径上,但不想在你的EuerekaClient,确保设置eureka.client.jersey.enabled自false.
Netflix 原生 EurekaClient 的替代方案
你不必使用Netflix的原始版尤里卡客户端.
而且通常用包装纸更方便。
Spring Cloud 通过逻辑 Eureka 服务标识符(VIP)而非物理 URL,支持 Feign(一个 REST 客户端构建器)和 Spring Cloud 负载均衡器。
你也可以使用org.springframework.cloud.client.discovery.DiscoveryClient,该API为发现客户端提供一个简单的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;
}
为什么注册服务这么慢?
成为实例还涉及定期的心跳声进入登记处
(通过客户的服务网址)默认持续时间为30秒。
客户端在实例、服务器和客户端的本地元数据相同之前,服务才可供客户端发现
缓存(所以可能需要3个心跳)。
你可以通过设置来改变周期eureka.instance.leaseRenewalIntervalInSeconds.
将其设为小于30可以加快客户端连接其他服务的速度。
在生产环境中,最好还是坚持默认,因为服务器内部会对租约续期进行假设。
区
如果你将 Eureka 客户端部署到多个区域,你可能更倾向于让这些客户端先使用同一区域内的服务,再尝试在另一个区域的服务。 要设置好这些,你需要正确配置你的Eureka客户端。
首先,你需要确保每个区域都部署了Eureka服务器,并且 他们是彼此的同辈。 更多信息请参见分区和区域部分。
接下来,你需要告诉尤里卡你的服务所在的区域。
你可以通过使用元数据地图财产。
例如,如果第一线同时部署到两个平台第一区和第二区,你需要在 中设置以下尤里卡属性第一线:
1号线在1区
eureka.instance.metadataMap.zone = zone1
eureka.client.preferSameZoneEureka = true
第2区的1号线
eureka.instance.metadataMap.zone = zone2
eureka.client.preferSameZoneEureka = true
刷新尤里卡客户端
默认情况下,尤里卡客户端Bean 是可刷新的,这意味着 Eureka 客户端属性可以被更改和刷新。
刷新发生时,客户端会从Eureka服务器取消注册,可能会有短暂的等待时间
其中并非所有给定服务实例都可用。一种防止这种情况的方法是禁用
能够刷新Eureka客户端。要完成这个集合Eureka.client.refresh.enable=false.
使用 Eureka 配合 Spring Cloud LoadBalancer
我们支持Spring Cloud负载均衡器ZonePreferenceServiceInstanceListSupplier.
这区Eureka 实例元数据中的值(eureka.instance.metadataMap.zone)用于设置
值Spring-云-负载均衡区用于按区域过滤服务实例的属性。
如果缺少这个,且如果spring.cloud.loadbalancer.eureka.approximateZoneFromHostname旗帜设置为true,
它可以使用服务器主机名中的域名作为该区域的代理。
如果没有其他区域数据来源,则根据客户端配置(而非实例配置)进行猜测。
我们取eureka.client.availabilityZones,即从区域名称到区域列表的映射,并抽出实例自身区域的第一个区域(即Eureka.client.region,默认为“us-east-1”,以兼容原生Netflix)。
服务发现:Eureka 服务器
本节介绍如何搭建Eureka服务器。
如何包含Eureka服务器
要在项目中包含 Eureka Server,请使用组 ID 为 的起始文件org.springframework.cloud以及一个伪影IDSpring-cloud-starter-Netflix-Eureka-server.
请参阅 Spring Cloud Project 页面,了解如何使用当前的 Spring Cloud 发布列车来设置你的构建系统。
| 如果你的项目已经使用 Thymeleaf 作为模板引擎,Eureka 服务器的 Freemarker 模板可能加载不正确。此时需要手动配置模板加载器: |
spring:
freemarker:
template-loader-path: classpath:/templates/
prefer-file-system-access: false
如何运行Eureka服务器
以下示例展示了一个最小的Eureka服务器:
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceTestApplication.class, args);
}
}
服务器有一个主页,里面有UI和HTTP API端点,用于Eureka的正常功能。/尤里卡/*.
|
由于Gradle的依赖解析规则以及缺乏父BOM功能,这取决于 build.gradle
|
defaultOpenForTrafficCount以及它对EurekaServer预热时间的影响
Netflix 尤里卡的waitTimeInMsWhenSyncEmptySpring Cloud Eureka 服务器开头时不考虑设置。为了启用热身时间,设置eureka.server.defaultOpenForTrafficCount=0.
高可用性、区域与区域
Eureka服务器没有后端存储,但注册表中的服务实例都必须发送心跳以保持注册信息的更新(因此可以在内存中完成)。 客户端还拥有Eureka注册的内存缓存(因此不必每次请求服务都访问注册表)。
默认情况下,每个Eureka服务器也是Eureka客户端,并且需要(至少一个)服务URL来定位对等端。 如果你不提供,服务会运行并正常工作,但会在日志中充满无法注册的噪音。
独立模式
两个缓存(客户端和服务器)和心跳缓存的结合,使得独立的 Eureka 服务器在某种监控或弹性运行时(如 Cloud Foundry)的维护下,具有相当的故障韧性。 在独立模式下,你可能更愿意关闭客户端行为,这样它就不会一直尝试但无法连接到对等端。 以下示例展示了如何关闭客户端行为:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
注意服务网址指向与本地实例相同的主机。
同伴意识
通过运行多个实例并要求它们相互注册,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 文件,可以用来在两个主机上运行同一台服务器(对等1和Peer2通过在不同的 Spring 配置文件中运行。
你可以用这种配置测试单台主机上的对等感知(在生产环境中这样做没什么价值),通过作/等等/主持人用来解析主机名称。
事实上,Eureka.instance.hostname如果你运行在已知自身主机名的机器上(默认情况下,通过以下方式查找)则不需要java.net.Inet地址).
你可以向系统添加多个节点,只要它们至少通过一条边相互连接,它们就会同步 登记在彼此之间。 如果对等节点物理上分隔(在数据中心内或多个数据中心之间),那么系统原则上可以承受“分脑”类型的故障。 你可以向系统添加多个节点,只要它们都是 它们直接连接时会同步 登记在彼此之间。
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
何时优先选择IP地址
在某些情况下,Eureka更倾向于广告服务的IP地址而非主机名。
设置eureka.instance.preferIpAddress自true当应用程序向Eureka注册时,使用其IP地址而非主机名。
|
如果Java无法确定主机名,则将IP地址发送给Eureka。
唯一明确设置主机名的方法是 |
保护尤里卡服务器
你只需在你的 Eureka 服务器中添加 Spring Security 即可保护你的 Eureka 服务器
服务器的类路径通过Spring Boot启动.默认情况下,当 Spring Security 在类路径上时,它会要求
每次请求应用时都会发送有效的 CSRF Tokens。尤里卡客户通常不会拥有有效的
跨站请求伪造(CSRF)Tokens,你需要关闭该要求/尤里卡/**端点。
例如:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated())
.httpBasic(withDefaults());
http.csrf().ignoringRequestMatchers("/eureka/**");
return http.build();
}
有关CSRF的更多信息,请参阅Spring Security文档。
Spring Cloud Samples 仓库中有一个演示版的 Eureka 服务器。
JDK 11 支援
尤里卡服务器依赖的JAXB模块在JDK 11中被移除。如果你打算用JDK 11 运行Eureka服务器时,必须在POM或Gradle文件中包含这些依赖。
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
指标
EurekaInstanceMonitor监听与Eureka实例注册相关的事件并创建/更新Micrometer 'MeterRegistry' 中的 Eureka 实例信息量表.默认情况下,这种行为是被禁用的。如果你想启用它,你需要设置eureka.server.metrics.enabled自true.
默认情况下,计量表被命名为 'eureka.server.instances并具有以下标签:
-
应用: 应用名称 -
地位: 实例状态 (向上,下,开始,OUT_OF_SERVICE,未知看:com.netflix.appinfo.InstanceInfo.InstanceStatus)
你可以通过注入你自己的实现来添加额外的标签EurekaInstanceTagsProvider.
配置属性
要查看所有与 Spring Cloud Netflix 相关的配置属性列表,请查看附录页面。