springCloud是基于springboot的微服务,包括服务的注册,负载均衡,熔断器,服务网关,配置中心,链路追踪等组件
springcloud服务调用的方式基于HTTP的REST方式,dubbo是RPC通信
1、Eureka
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
@EnableEurekaServer
<!-- 将微服务provider侧注册进eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
启动类需要注解
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里
Eureka服务端:注册中心,支持配置高可用,如果Eureka以集群的方式部署,当集群中的分片出现故障,Eureka会进入自我保护模式。
它允许在服务出现故障期间继续提供服务的注册发现,当故障恢复运行时,其他的分片会把它们的状态再次同步回来。
- 失效剔除:Eureka server在启动的时候会创建定时任务,默认每隔一段时间(默认60s)将当前清单里超时(默认90s)没有续约的服务剔除出去
- 自我保护机制:Eureka server在运行期间,会统计失败心跳的比例在15分钟内是否超过85%,超过会将当前实例注册信息保护起来(网络问题短时间内大部分心跳失败)
网络恢复会退出自我保护机制
# 关闭保护机制,以确保注册中心可以将不用的实例正确剔除(本地调试可以使用,线上不推荐)
eureka.server.enable-self-preservation=false
Eureka客户端:主要处理注册发现,客户端通过注解、配置参数的形式嵌入到应用程序的代码中,程序运行时,客户端会向注册中心注册提供自身的服务
并周期性的心跳更新服务租约,同时它可以从服务端查询当前的服务列表并缓存到本地周期性的刷新服务状态。
- 服务注册:服务提供者在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自己服务的一些元数据信息。
Eureka Server接收到这个REST请求之后,将元数据信息存储在一个双层结构Map中,其中第一层的key是服务名,第二层的key是具体服务的实例名
- 服务续约:服务注册完成后,会提供一个心跳告诉Eureka server,以防止Eureka的定时剔除任务会把服务删除掉
# 定义服务续约任务的调用间隔时间,默认30秒
eureka.instance.lease-renewal-interval-in-seconds=30
# 定义服务失效的时间,默认90秒
eureka.instance.lease-expiration-duration-in-seconds=90
- 获取服务:服务消费者启动,发送rest请求到注册中心,获取服务注册的列表,Eureka会维护一个只读的清单返回给客户端,同时该缓存清单30会更新一次
# 缓存清单的更新时间,默认30秒
eureka.client.registry-fetch-interval-seconds=30
- 服务调用:服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。
在Ribbon中会默认采用轮询的方式进行调用,从而实现客户端的负载均衡
- 服务下线:当服务实例进行正常的关闭时,它会向Eureka server发送服务下线的rest请求,服务端接受到请求后,会将服务的状态置为下线(down)
Eureka server高可用实际上就是将自己作为服务向其他的注册中心注册自己,这样就可以形成一组互相注册的服务注册中心。
Eureka与Zookeeper的区别
CAP:C(一致性),A(可用性),P(分区容错性)
分区容错性是分布式系统必须要保证的,zk保证cp,Eureka保证ap
- zk保证cp,当master节点因网络故障与其他的节点失去联系,剩余节点重新进行leader选举,选举时间太长,30-120s
且选举期间整个zk集群是不可用的,导致拂去瘫痪,注册是不可用的。
- Eureka保证可用性,各个节点都是平等的,几个节点挂了不会影响正常节点的工作,剩余节点依然可以提供服务的注册发现,
在Eureka客户端向server注册时发现失败会自动切换到其他节点,只要有一台可用,就能保证服务的注册发现,只不过查过的信息可能不是最新的
除此之外,Eureka还有一种自我保护机制,15分钟内超过85%的心跳失败,Eureka就认为客户端与注册中心出现网络故障,会出现以下几种情况:
- Eureka不会从注册列表删除长时间没接收到心跳的服务
- Eureka仍然可以接受注册发现的请求,但不会同步到其他的节
- 网络稳定后,新的注册信息会同步到其他的节点上
- 因此:Eureka可以应对网络故障部分节点不可用的问题,不像zk网络故障会导致整个注册服务瘫痪。
2、Ribbon
Ribbon 作为服务消费者的负载均衡器,有两种使用方式,一种是和 RestTemplate相结合,另一种是和Feign相结合,Feign 已经默认集成了Ribbon
负载均衡策略:随机,轮询
默认是轮询策略:按照顺序执行
注解:@LoadBalanced
3、Fegin
采用的是基于接口的注解;feign整合了Ribbon,具有负载均衡的能力;整合Hystrix,具有熔断的能力
4、Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
注解:EnableHystrix
Hystrix保证一个依赖失败,不会导致整个服务的失败,避免级联故障,提高分布式系统的弹性。
- Hystrix断路器机制:当Hystrix Command请求后端服务失败数量超过一定的比例(默认50%),断路器会切换到开路的状态open,这时所有的请求会直接返回失败而不会发送到后端,断路器保持开路一段时间(默认5s)后,自动切换到半开路状态(HALF-OPEN),这时会判断下一次请求返回的情况,如果请求成功,断路器会切换为闭路状态(CLOSE),否则切换到开路状态(OPEN),断路器像保险丝,一旦后端不可用直接切断请求链,避免发送大量无效的请求。
- 服务熔断:注解:@HystrixCommand,主启动类上的注解:@EnableCircuitBreaker当服务出现不可用或响应时间超时,为了防止整个服务的出现雪崩,暂时停止对该服务的调用。
- 服务降级:当前服务器请求数量过大,服务器压力剧增,采取降级方案,fallback方法处理降级的逻辑(es降级查询数据库)比如服务出现异常超时首先会处理降级逻辑,当请求数量超过50%时,会直接关闭服务不可再访问。
5、zuul
springcloud zuul包含了对请求的路由和过滤两个功能,路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础
过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础
下面是4种过滤器:
- pre: 可以在请求被路由之前调用,用于实现身份验证、在集群中选择请求的微服务、记录调试信息等
- routing: 在路由请求时候被调用,用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务
- post: 在route和error过滤器之后被调用,可用来为响应添加标准的http header、收集统计信息和指标、将响应从微服务发送给客户端。
- error: 在其他阶段发送错误时执行该过滤器。
6、Config
<!-- springCloud Config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 避免Config的Git插件报错:org/eclipse/jgit/api/TransportConfigCallback -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.10.0.201712302008-r</version>
</dependency>
SpringCloud Config为微服务架构中得微服务提供集中化得外部配置支持,配置服务器为各个不同微服务应用得所有环境提供了一个中心化得外部配置。
**注:使用bootstrap.yml,其优先级高于application.yml**
Spring Cloud Config分为服务端和客户端两部分:
- 服务端也成为分布式配置中心,它是一个独立的微服务应用,用来链接配置服务器并未客户端提供获取配置信息,加密/解密信息等访问接口
- 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认,采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容
7、总结
- Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里
- Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台
- Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
- Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题
- Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务