转载自:http://www.itmuch.com/spring-cloud-1/
http://blog.didispace.com/springcloud1/
https://blog.youkuaiyun.com/xiao_jun_0820/article/details/77991963
Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务。Spring Cloud将它集成在其子项目spring-cloud-netflix中,以实现Spring Cloud的服务发现功能。
Eureka的Github:https://github.com/Netflix/Eureka
Region、Zone解析
Eureka的官方文档对regin、zone几乎没有提及,由于概念抽象,新手很难理解。因此,在分析Eureka原理之前,先来了解一下region、zone、Eureka集群三者的关系,如图:

region和zone(或者Availability Zone)均是AWS的概念。在非AWS环境下,可以简单地将region理解为Eureka集群,zone理解成机房。这样就很好理解了,一个Eureka集群被部署在了zone1机房和zone2机房中。
Spring Cloud中默认的region是us-east-1 。
Eureka架构

上图来自Eureka官方的架构图,大致描述了Eureka集群的工作过程。
Application Service相当于服务提供者,Application Client相当于服务消费者;Make Remote Call可以简单理解为调用RESTful API;us-east-1c、us-east-1d等都是zone,它们都属于us-east-1这个region。
Eureka包含两个组件:Eureka Server 和 Eureka Client,可以理解成,服务都注册在哪里,哪里就可称为Eureka Server,注册中心的意思。注册在注册中心可以是服务的提供者(Applicaton Service)或者服务的消费者(Application Client),这两类都被称为Eureka client。
微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息,Eureka Server会存储该服务的信息;启动后,Eureka Client会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)。
每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册表的同步;Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者。
综上,Eureka通过心跳检测、健康检查和客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性。
示例
创建注册中心
@SpringBootApplication
@EnableEurekaServer // 启动一个服务注册中心
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
配置文件
server.port=9000
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
eureka.client.registerWithEureka: 表示是否将自己注册到Eureka Server,默认为true。由于当前这个应用就是Eureka Server,故而设为false。
eureka.client.fetchRegistry: 表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,故而设为false。
eureka.client.serviceUrl.defaultZone: 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。多个地址可使用”,”分隔。
启动工程后,访问:http://localhost:9000/ 。会发现此时还没有服务注册到Eureka上面。

创建服务提供方
在启动类中通过加上@EnableDiscoveryClient注解,该注解能激活Eureka中的DiscoveryClient实现,才能实现Controller中对服务信息的输出。
@SpringBootApplication
@EnableDiscoveryClient
@PropertySource(value = {"classpath:application.properties"})
public class ComputeServiceApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args);
}
}
@RestController
public class ComputeController {
@RequestMapping(value = "/add" ,method = RequestMethod.GET)
public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
Integer r = a + b;
return r;
}
}
spring.application.name=compute-service
server.port=2222
eureka.client.serviceUrl.defaultZone=http://localhost:9000/eureka/
spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name
启动该工程后,再次访问:http://localhost:9000/, 可以看到,我们定义的服务被注册了。

默认情况下注册到eureka server的服务是通过心跳来告知自己是UP还是DOWN,并不是通过spring-boot-actuator模块的/health端点来实现的,这样其实不是很合理。
默认的心跳实现方式可以有效的检查eureka客户端进程是否正常运作,但是无法保证客户端应用能够正常提供服务。由于大多数微服务应用都会有一些其他的外部资源依赖,比如数据库,REDIS缓存等,如果我们的应用与这些外部资源无法连通的时候,实际上已经不能提供正常的对外服务了,但因为客户端心跳依然在运行,所以它还是会被服务消费者调用,而这样的调用实际上并不能获得预期的后果。
可以通过在eureka客户端配置:eureka.client.healthcheck.enabled=true,来改变eureka server对客户端健康检测的方式,改用actuator的/health端点来检测,因此要引入spring-boot-starter-actuator。
添加一个自定义的HealthIndicator:
public class CustomHealthChecker implements HealthIndicator {
private boolean up = true;
@Override
public Health health() {
if (up) {
return new Health.Builder().withDetail("aaa_cnt", 10) //自定义监控内容
.withDetail("bbb_status", "up").up().build();
} else {
return new Health.Builder().withDetail("error", "client is down").down().build();
}
}
public boolean isUp() {
return up;
}
public void setUp(boolean up) {
this.up = up;
}
}
配置文件需要加上:
eureka.client.healthcheck.enabled=true
在某些情况下,使用服务的IP地址比主机名好。通过如下配置:
eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.ip-address}:${server.port}/eureka/
这样,应用在注册eureka时就会使用IP地址而不是主机名。
注册到Eureka Server上的appname,spring.application.name的优先级比eureka.instance.appname高。
eureka配置心跳和剔除下线的服务的时间
在默认的springCloud中eureka注册中心在服务下线时表现的非常不灵敏,eureka设计的本意是在服务不会频繁上下线和网络稳定的内网,这种设计在生产环境是没什么问题的,但在开发和测试环境却会导致经常调用到已经下线的服务提供者,可以加上如下配置来解决(建议配合profile)
1、eureka server中的application.properties
#此配置建议只试用开发和测试环境
#驱逐下线的服务,间隔,5秒,默认是60
#org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean.evictionIntervalTimerInMs
eureka.server.evictionIntervalTimerInMs=5000
2、服务提供者的application.properties
#此配置建议只试用开发和测试环境
#Eureka Client发送续约心跳的时间参数,默认是30秒
#org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.leaseRenewalIntervalInSeconds
eureka.instance.leaseRenewalIntervalInSeconds=2
#Eureka Server在多长时间内没有收到心跳将实例剔除的时间参数,默认90秒
#org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.leaseExpirationDurationInSeconds
eureka.instance.leaseExpirationDurationInSeconds=6
为已有的Eureka Server增加高可用HA,参考:https://blog.youkuaiyun.com/gobitan/article/details/76548929
Spring Cloud中,Eureka常见问题总结:
http://www.itmuch.com/spring-cloud-sum-eureka/
Eureka Client一启动(不是启动完成),不是立即向Eureka Server注册,它有一个延迟向服务端注册的时间,默认的延迟时间为40秒
Eureka Server维护每30秒更新的响应缓存,可通过更改配置eureka.server.responseCacheUpdateIntervalMs来修改。 所以即使实例刚刚注册,它也不会出现在调用/eureka/apps的结果中。
Eureka客户端保留注册表信息的缓存。 该缓存每30秒更新一次。因此,客户端决定刷新其本地缓存并发现其他新注册的实例可能需要30秒。
Ribbon的负载平衡器从本地的Eureka Client获取服务注册列表信息。Ribbon本身还维护本地缓存,以避免为每个请求调用本地客户端。 此缓存每30秒刷新一次(可由ribbon.ServerListRefreshInterval配置)。所以,可能需要30多秒才能使用新注册的实例。
一个新注册的实例,特别是启动较快的实例(默认延迟40秒注册),不能马上被Eureka Server发现。另外,刚注册的Eureka Client也不能立即被其他服务调用,因为调用方因为各种缓存没有及时的获取到新的注册列表。
Eureka 的自我保护模式
当一个新的Eureka Server出现时,它尝试从相邻节点获取所有实例注册表信息。如果从Peer节点获取信息时出现问题,Eureka Serve会尝试其他的Peer节点。如果服务器能够成功获取所有实例,则根据该信息设置应该接收的更新阈值。如果有任何时间,Eureka Serve接收到的续约低于为该值配置的百分比(默认为15分钟内低于85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。
这样做的好处就是,如果是Eureka Server自身的网络问题,导致Eureka Client的续约不上,Eureka Client的注册列表信息不再被删除,也就是Eureka Client还可以被其他服务消费。
服务注册信息不会被二次传播,比如如果Eureka A的peer指向了B, B的peer指向了C,那么当服务向A注册时,B中会有该服务的注册信息,但是C中没有。那么如果希望只要向一台Eureka注册其它所有实例都能得到注册信息,就必须把其它所有节点都配置到当前Eureka的peer属性中。
本文深入解析Eureka服务发现组件在SpringCloud生态系统中的角色,包括其架构、配置要点及如何构建高可用集群。探讨了region、zone概念,EurekaServer与EurekaClient交互流程,以及如何调整心跳和健康检查策略提升开发效率。
1811

被折叠的 条评论
为什么被折叠?



