# 什么是 Spring Cloud?
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便捷性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以利用 Spring Boot 的开发风格做到一键启动和部署。
# Spring Cloud 和 Dubbo 的区别
- Dubbo 关注的领域是 Spring Cloud 的一个子集,Dubbo 专注于服务治理,其在服务自理、灰度发布、流量发布方面比 Spring Cloud 更全面,Spring Cloud 覆盖整个微服务框架
- Doubbo 使用 RPC 调用效率更高一些,Spring CLoud 使用 HTTP 调用效率低,使用更简单
# SpringCloud 如何实现服务的注册和发现
- 服务在发布时指定对应的服务名(服务名包括了 IP 地址和端口)将服务注册到注册中心(eureka 或 zookeeper)
- 这一过程是 Spring Cloud 自动实现,只需要在 main 方法添加 @EnableDisscoveryClient,同一个服务器修改端口就可以启动多个实例
- 调用方法:传递服务名称通过注册中心获取所有可用实例,通过负载均衡策略调用(ribbon 和 feign)对应的服务
# ribbon 和 feign 区别
- 启动类使用的注解不同。
- ribbon 使用的是 @RibbonClient
- Feign 使用的是 @EnableFeignClients
- 指定的服务位置不同。
- Ribbon 是在 @RibbonClient 注解上声明
- Feign 则是在定义抽象方法的接口使用 @FeignClient 声明
- 调用方式不同。
- Ribbon 需要自己构建 http 请求,模拟 http 请求然后使用 RestTemplate 发送给其他服务,步骤相当繁琐
- Feign 则是在 Ribbon 的基础上进行了一次改进,采用了接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建 http 请求,不过要注意的是抽象方法的注解、方法签名和提供服务的方法完全一致
# ribbon 的负载均衡策略
- RoundRobinRule:轮询策略。Ribbon 以轮询的方式选择服务器,这个是默认值。
- RandomRule:随机策略。Ribbon 会随机从服务器列表选择一个进行访问。
- BestAvailableRule:最大可用策略。即先过滤出故障服务器后,选择一个当前并发数最小的。
- WeightedResponseRule:带加权的轮询策略。对各个服务器的响应时间进行加权处理,然后采用轮询的方式来获取相应的服务器。
- AvailablityFilteringRule:可用过滤策略。先过滤故障服务器或并发请求大于阈值的一部分服务器,然后在以线性轮询的方式从过滤的实例清单中选择一个。
- ZoneAvoidanceRule:区域感知策略。先使用主过滤条件(区域负载器,选择最优区域)对所有实例并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数(默认 1)和最小过滤百分比(默认 0),最后对满足条件的服务器则使用 RoundRobinRule (轮询方式) 选择一个服务器实例。
# Spring Cloud 断路器的作用是什么?
在分布式的架构中,断路器模式的作用也是类似的,当某个服务单元发生故障时之后,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待,这样就不会使得线程因故障服务被长时间占用不释放,避免故障在分布式系统中的蔓延。
# Spring Cloud 的核心组件有哪些
Eureka:服务注册与发现
Fegin:基于动态代理的机制,根据注解和选择的机器,拼接请求 url 地址,发起请求
Ribbon:实现负载均衡,从一个服务的多台机器中选择一台
Hystrix:提高线程池,不同的服务走不同的线程池,实现不同服务调用的隔离,避免服务雪崩的问题
Zuul:网关管理,由 Zuul 网关转发请求给对应的服务
# 什么是服务熔断和服务降级?
- 服务熔断是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可以或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回 “错误 “的响应信息。当检查到该节点微服务调用响应正常后恢复调用链路。在 Spring Cloud 框架中熔断机制通过 Hystrix 实现,Hystrix 会监控服务间调用状况,当失败的调用到一定阈值,缺省是 5 秒调用 20 次,如果失败就会启动熔断机制。
- 服务降级,一般是从整体负荷考虑。当某个服务器不在被调用,此时客户端可以准备一个本地的 fallback 回调,返回缺省值。这样做,虽然提供的是一个有损的服务,但却保证了整个服务器的稳定性和可用性。
# zuul 常用的功能
- 提供动态路由
- 提供安全、鉴权处理
- 跨域处理
- 全局动态的 hystrix(熔断、降级、限流)处理
# 服务网关的作用
- 简化客户端的调用复杂度,统一处理外部请求
- 数据裁剪以及聚合,根据不同的接口需求,对数据加工后对外
- 多渠道支持,针对不同的客户端提供不同的网关支持
- 遗留系统的微服务改造,可以作为新老系统的中转组件
- 统一处理调用过程中的安全问题、权限问题
# 简述什么是 CAP, 并说明 Eureka 包含 CAP 中的哪些?
CAP 理论:一个分布式系统不可能同时满足 C (一致性) A (可用性) P (分区容错性)。由于分区容错性 P 在分布式系统中是必须保证的,因此只能从 A 和 C 中进行权衡。
Eureka 遵守 AP
- Eureka 每个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务
- 而 Eureka 客户端在向某个 Eureka 注册或查询时如果发现连接失败,则会自动切换至其他节点,只要有一台 Eureka 还在,就能保证注册服务可用(保证可用性),只不过查的信息可能不是最新的(不保证强一致性)
# Eureka 和 zookeeper 都可以提供服务注册与发现的功能,请说说两个的区别?
- Zookeeper 保证了 CP
- Eureka 保证了 AP
- 当向注册中心查询服务列表时,我们可以容忍注册中心返回的时几分钟以前的信息,但是不能容忍直接 down 掉不可用,也就是说服务注册功能对高可用性能比较高,但 Zookeeper 会出现这种情况,当 master 节点因为网络故障与其他节点失去联系的时候,剩余节点会重新选取 leader。问题在于选育 leader 的时间过长,30~120s,且选取期间 Zookeeper 集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得 Zookeeper 集群失去 master 节点是较大概率会发生的事情,虽然服务器能够修复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。
- Eureka 保证了可用性,Eureka 各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而 Eureka 的客户端向某个 Eureka 注册或发现时发生连接失败,则会自动切换到其他节点。只要有一台 Eureka 还在,就能保证组注册服务可用,只是查询的信息可能不是最新的,除此之外,Eureka 还有自我保护机制,如果 15 分钟内超过 85%的节点没有正常心跳,那么就 Eureka 就认为客户端与注册中心发生了网络故障,此时会出现以下几种情况:
- Eureka 不在从注册列表中移除因为长时间没有收到心跳而应该过期的服务
- Eureka 仍然能够接收新服务的注册和查询请求,但是不会被同步到其他节点上(保证当前节点仍然可用)
- 当网络稳定时,当前实例新的注册信息会被同步到其他节点
因此,Eureka 可以很好的应对网络故障导致部分节点失去联系的情况,而不会向 Zookeeper 那样使整个微服务瘫