SpringCloud Netflix & Sprin gCloud Alibaba

什么是 Spring Cloud ?

Spring Cloud 是构建在 Spring Boot 基础之上,用于快速构建分布式系统的通用模式的工具集。或者说,换成大家更为熟知的,用于构建微服务的技术栈。

而后,不同厂商结合自身的中间件,提供自身的SpringCloud套件,例如:

  • Netflix 结合自己的 Eureka、Ribbon、Hystrix 等开源中间件,实现了 spring-cloud-netflix
  • Kubernetes 结合自己的 apiserver、configmap 等功能,实现了 spring-cloud-kubernetes
  • Alibaba 结合自己的 Nacos、Dubbo、Sentinel 等开源中间件,实现了 spring-cloud-alibaba

当然SpringCloud还是提供了自身的一些组件的:

  • API 网关:Spring Cloud Gateway
  • 配置中心:Spring Cloud Config、Spring Cloud Vault
  • 链路追踪:Spring Cloud Sleuth
  • 消息驱动:Spring Cloud Stream
  • 事件总线:Spring Cloud Bus
  • 服务调用:Spring Cloud OpenFeign、RestTemlete
  • 负载均衡:Spring Cloud Load Balancer

下面我们把 Spring Cloud 官方、Netflix、Alibaba 三者整理成如下表格:

SpringCloud 官方NetflixAlibaba
配置中心Spring Cloud Config、Spring Cloud VaultArchaiusNacos
注册中心EurekaNacos
服务调用Spring Cloud OpenFeign、RestTemleteDubbo
负载均衡Spring Cloud Load BalancerRibbonDubbo
服务容错HystrixSentinel
API网关Spring Cloud GatewayZuul
消息驱动Spring Cloud Stream RabbiltMQ、Spring Cloud Stream KafkaSpring Cloud Stream RecketMQ
事件总线Spring Cloud BusSpring Cloud Bus RecketMQ
链路跟踪Spring Cloud Sleuth
分布式事物Seate
分布式调度SchedulerX

Spring Cloud Alibaba 套件

Spring Cloud Alibaba 套件,阿里开源组件、阿里云商业组件整合进 Spring Cloud 体系当中,同时对 Spring Cloud Gateway、OpenFeign、Ribbon 等等进行集成。
主要功能如下:

  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。

Spring Cloud 和 Spring Boot 的区别和关系?

Spring Boot 专注于快速方便的开发单个个体微服务。

Spring Cloud 是关注全局的微服务协调整理治理框架以及一整套的落地解决方案,它将 Spring Boot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理,服务发现,断路器,路由,微代理,事件总线等的集成服务。

Spring Boot 可以离开 Spring Cloud 独立使用,但是 Spring Cloud 离不开 Spring Boot ,属于依赖的关系。

什么是微服务?

查看文献:什么是微服务?

微服务的优缺点分别是什么?

优点

  • 每一个服务足够内聚,代码容易理解
  • 开发效率提高,一个服务只做一件事
  • 微服务能够被小团队单独开发
  • 微服务是松耦合的,是有功能意义的服务
  • 可以用不同的语言开发,面向接口编程
  • 易于与第三方集成
  • 微服务只是业务逻辑的代码,不会和 HTML、CSS 或者其他界面组合
  • 可以灵活搭配,连接公共库/连接独立库

缺点

  • 分布式系统的负责性
  • 多服务运维难度,随着服务的增加,运维的压力也在增大
  • 系统部署依赖
  • 服务间通信成本
  • 数据一致性
  • 系统集成测试
  • 性能监控

注册中心

什么是服务注册中心?

服务注册中心就是服务实现服务化的核心组件,类似于目录服务的作用,主要用来存储服务信息。服务注册中心是SOA架构中最基础的设施之一。

服务注册中心的作用

服务注册

服务注册就是将开发好的调用方(Consumer)获得服务方(Provider)服务进行注册进注册中心,通过注册中心,存储调用方(Consumer)获得服务方(Provider)的地址,从而能够调用。

例如:服务注册中心是一栋写字楼的物业,注册入这栋写字楼的公司都是服务方/调用方,当我们需要找到这栋写字楼的某一个公司,就可以直接去物业找到具体的地址。

服务发现

调用方(Consumer)根据服务方提供的入口在服务注册中心寻找相对应的函数,可进行远程调用。调用方(Consumer)/服务方(Provider)可以是任意注册中心中的服务。

服务注册中心组件

Eruka

Eureka 是 Netflix 出品的用于实现服务注册和发现的工具。 Spring Cloud 集成了 Eureka,并提供了开箱即用的支持。其中, Eureka 又可细分为 Eureka Server 和 Eureka Client。

Eureka的自我保护机制:在默认配置中,Eureka Server在默认90s没有得到客户端的心跳,则注销该实例,但是往往因为微服务跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,但是因为网络分区故障时,Eureka Server注销服务实例则会让大部分微服务不可用,这很危险,因为服务明明没有问题。为了解决这个问题,Eureka 有自我保护机制,它的原理是,当Eureka Server节点在短时间内丢失过多的客户端时(可能发送了网络故障),那么这个节点将进入自我保护模式,不再注销任何微服务,当网络故障回复后,该节点会自动退出自我保护模式。

自我保护模式的架构哲学是宁可放过一个,决不可错杀一千

Consul

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。
Consul 使用 Go 语言编写,因此具有天然可移植性(支持 Linux、Windows 和 Mac OS X)。
Consul 内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。
Consul 遵循 CAP 原理中的 CP 原则,保证了强一致性和分区容错性,且使用的是 Raft 算法,比 ZooKeeper 使用的 Paxos 算法更加简单。
虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 Raft 协议要求必须过半数的节点都写入成功才认为注册成功。
在 Leader 挂掉了之后,重新选举出 Leader 之前会导致 Consul 服务不可用。

Zookeeper

Zookeeper实际上是yahoo开发的,用于分布式中一致性处理的框架。最初其作为研发Hadoop时的副产品。由于分布式系统中一致性处理较为困难,其他的分布式系统没有必要费劲重复造轮子,故随后的分布式系统中大量应用了zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之重要,可想而知。著名的hadoop、kafka、dubbo 都是基于zookeeper而构建。 ZooKeeper 使用的 Paxos 算法,当 Master 节点因为网络故障与其他节点失去联系时,剩余节点会重新进行 Leader 选举。

从 ZooKeeper 的实际应用情况来看,在使用 ZooKeeper 获取服务列表时,如果此时的 ZooKeeper 集群中的 Leader 宕机了,该集群就要进行 Leader 的选举。

问题在于,选举 Leader 的时间太长,30~120s,而且选举期间整个 ZooKeeper 集群都是不可用的,这就导致在选举期间注册服务瘫痪。

在云部署环境下, 因为网络问题使得 ZooKeeper 集群失去 Master 节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。

Nacos

Nacos 是阿里开源的,Nacos 支持基于 DNS 和基于 RPC 的服务发现。在 Spring Cloud 中使用 Nacos,只需要先下载 Nacos 并启动 Nacos server,Nacos 只需要简单的配置就可以完成服务的注册发现。

Nacos 除了服务的注册发现之外,还支持动态配置服务。动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

注册中心原理:服务注册方法:以Java nacos client v1.0.1 为例子,服务注册的策略的是每5秒向nacos server发送一次心跳,心跳带上了服务名,服务ip,服务端口等信息。同时 nacos server也会向client 主动发起健康检查,支持tcp/http检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。

Eruka、Zookeeper和Nacos的区别

CAP理论

一致性(Consistency),所有节点在同一时间具有相同的数据。

可用性(Availability),这个比较好理解,就是说,只要我对服务器,发送请求,服务器必须对我进行相应,保证服务器一直是可用的。

分隔容忍(Partition tolerance),一般来说,分布式系统是分布在多个位置的。比如我们的一台服务器在北京,一台在上海。可能由于天气等原因的影响。造成了两条服务器直接不能互相通信,数据不能进行同步。这就是分区容错。我们认为,分区容错是不可避免的。也就是说 P 是必然存在的。

CAP只能达到CP或者AP,如果我们保证了CP,即一致性与分布容错。当我们通过一个服务器修改数据后,该服务器会向另一个服务器发送请求,将数据进行同步,但此时,该数据应处于锁定状态,不可再次修改,这样,如果此时我们想服务器发送请求,则得不到相应,这样就不能A,高可用。如果我们保证了AP,那么我们不能对服务器进行锁定,任何时候都要得到相应,那么数据的一致性就不好说了。

区别

以上三种注册中心都是实际开发中常用的,下面就以表格的形式来将它们的区别表示出来:

CAP理论通信配置中心
ZookerperCPRPC不支持
NacosAPHTTP(2.0版本后为gRPC)支持
ErukaAPHTTP不支持

gRPC

对RPC不了解的人,或许会纠结其与TCP、HTTP等的关系。后者是网络传输中的协议,而RPC是一种设计、实现框架,通讯协议只是其中一部分,RPC不仅要解决协议通讯的问题,还有序列化与反序列化,以及消息通知。

一个完整的RPC架构里面包含了四个核心的组件,分别是Client ,Server,ClientOptions以及ServerOptions,这个Options就是RPC需要设计实现的东西。

客户端(Client):服务的调用方。

服务端(Server):真正的服务提供方。

客户端存根(ClientOption):socket管理,网络收发包的序列化。

服务端存根(ServerOption):socket管理,提醒server层rpc方法调用,以及网络收发包的序列化。

gRPC是RPC的一种,它使用Protocol Buffer(简称Protobuf)作为序列化格式,Protocol Buffer是来自google的序列化框架,比Json更加轻便高效,同时基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特性。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。用protoc就能使用proto文件帮助我们生成上面的option层代码。

在gRPC中,客户端应用程序可以直接在另一台计算机上的服务器应用程序上调用方法,就好像它是本地对象一样,从而使您更轻松地创建分布式应用程序和服务。

适用场景:

  • 分布式场景 :gRPC设计为低延迟和高吞吐量通信,非常适用于效率至关重要的轻型微服务。
  • 点对点实时通信: gRPC对双向流媒体提供出色的支持,可以实时推送消息而无需轮询。
  • 多语言混合开发 :支持主流的开发语言,使gRPC成为多语言开发环境的理想选择。
  • 网络受限环境 : 使用Protobuf(一种轻量级消息格式)序列化gRPC消息。gRPC消息始终小于等效的JSON消息。

负载均衡

为什么要负载均衡?

简单来说,随着业务的发展,单台服务无法支撑访问的需要,于是搭建多个服务形成集群。那么随之要解决的是,每次请求,调用哪个服务,也就是需要进行负载均衡。

目前负载均衡有两种模式:客户端模式、服务端模式

在 Spring Cloud 中,我们使用前者,即客户端模式。

客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从Eureka服务注册中心获取的。

负载平衡的意义什么?

在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。

Ribbon

作用:主要提供客户侧的软件负载均衡算法。

简介:Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。

原理:Ribbo是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,客户端负载均衡中也需要心跳机制去维护服务端清单的有效性,当然这个过程需要配合服务注册中心一起完成。

Ribbon 有哪些负载均衡算法?

参考文献

其中,默认的负载均衡算法是 Round Robin 算法,顺序向下轮询。

Feign

Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

Feign 实现原理?

Feign的一个关键机制就是使用了动态代理。咱们一起来看看下面的图,结合图来分析:

  • 首先,如果你对某个接口定义了 @FeignClient 注解,Feign 就会针对这个接口创建一个动态代理。
  • 接着你要是调用那个接口,本质就是会调用 Feign 创建的动态代理,这是核心中的核心。
  • Feign的动态代理会根据你在接口上的 @RequestMapping 等注解,来动态构造出你要请求的服务的地址。
  • 最后针对这个地址,发起请求、解析响应。

Feign 和 Ribbon 的区别?

Ribbon 和 Feign 都是使用于调用用其余服务的,不过方式不同。

  • 启动类用的注解不同:Ribbon 使用的是 @RibbonClient ,Feign 使用的是 @EnableFeignClients 。
  • 服务的指定位置不同:Ribbon 是在 @RibbonClient 注解上设置,Feign 则是在定义声明方法的接口中用 @FeignClient 注解上设置。
  • 调使用方式不同:Ribbon 需要自己构建 Http 请求,模拟 Http 请求而后用 RestTemplate 发送给其余服务,步骤相当繁琐。Feign 采使用接口的方式,将需要调使用的其余服务的方法定义成声明方法就可,不需要自己构建 Http 请求。不过要注意的是声明方法的注解、方法签名要和提供服务的方法完全一致。

重试机制?

参考文献

服务保障

在 Spring Cloud 中,能够使用的服务保证,如下:

spring-cloud-netflix-hystrix ,基于 Hystrix 实现。

Resilience4j

spring-cloud-alibaba-sentinel ,基于 Sentinel 实现。

为什么要使用服务保障?

在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的 100% 可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累积,导致服务瘫痪,甚至导致服务“雪崩”。为了解决这个问题,就出现断路器模型。

Hystrix

作用:断路器,保护系统,控制故障范围。

简介:Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。

Hystrix 隔离策略?

Hystrix 有两种隔离策略:线程池隔离、信号量隔离。

实际场景下,使用线程池隔离居多,因为支持超时功能。

详细的,可以参考文献

Hystrix 缓存机制?

Hystrix 提供缓存功能,作用是:减少重复的请求数、在同一个用户请求的上下文中,相同依赖服务的返回数据始终保持一致。

什么是 Hystrix 断路器?

Hystrix 断路器通过 HystrixCircuitBreaker 实现。

HystrixCircuitBreaker 有三种状态 :

CLOSED :关闭

OPEN :打开

HALF_OPEN :半开

其中,断路器处于 OPEN 状态时,链路处于非健康状态,命令执行时,直接调用回退逻辑,跳过正常逻辑。

  • 初始时,断路器处于 CLOSED 状态,链路处于健康状态。当满足如下条件,断路器从 CLOSED 变成 OPEN 状态:周期内,总请求数超过一定量(可配置)。错误请求占总请求数超过一定比例(可配置)
  • 断路器处于 OPEN 状态,命令执行时,若当前时间超过断路器开启时间一定时间,断路器变成 HALF_OPEN 状态,尝试调用正常逻辑,根据执行是否成功,打开或关闭熔断器。

什么是 Hystrix 服务降级?

在 Hystrix 断路器熔断时,可以调用一个降级方法,返回相应的结果。当然,降级方法需要配置和编码,如果不需要,也可以不写,也就是不会有服务降级的功能。

什么是Sentinel?

Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。

Sentinel 的特征

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
  • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel和Hystrix的区别

SentinelHystrix
隔离级别信号量隔离线程池隔离/信号量隔离
熔断降级策略基于响应时间或失败比例基于失败比例
扩展性多个SPI扩张点插件扩展
限流基于QPS,支持基于调用关系的限流有限的支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
适配Servlet、Spring Cloud、Dubbo、gRPC等Servlet、Spring Cloud Netfilx
  • Hystrix 最核心的一项功能就是资源隔离,支持线程池隔离和信号量隔离;Sentinel支持信号量隔离。
  • Sentinel与Hystrix都支持基于失败比率的熔断降级,在调用超过指定的数量并且失败比率达到设定阀值时触发熔断,并在下个时间窗口自动恢复。Sentinel也支持按失败总数熔断降级,但按失败总数的熔断降级固定时间窗口为1分钟,当1分钟内调用失败总数达到设定的阀值就会触发熔断。此外,Sentinel还支持基于平均响应时间的熔断降级,平均响应时间越长,说明服务的性能在持续下降,在响应时间持续飙高时自动熔断,可以防止调用慢造成级联阻塞。
  • Sentinel 提供数据源接口可实现动态加载规则配置,结合 loadRules API 可灵活的运行时修改规则配置,并且随时修改随时生效。Hystrix 的资源模型设计上采用了命令模式,在创建 Command 时就需要指定隔离策略是线程池隔离还是信号量隔离,一但指定了隔离策略,运行期间便不能修改隔离策略,而在 Sentinel 中资源定义和规则配置是分离的,因此在配置的灵活性上 Sentinel 更具有优势。
  • Sentinel 支持系统自适应限流,Hystrix 所不支持的。当系统负载较高的时候,如果仍持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,负载均衡把本应这台机器承载的流量转发到其它的机器上去,如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器崩溃,最后导致整个集群不可用。针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
  • 黑白名单限流和热点参数限流也是 Sentinel 的一大特色,黑白名单限流,可根据请求来源判断来源是否在黑名单中,如果在黑名单中则拒绝请求,否则放行,结合 Sentinel 的灵活动态配置,黑白名单可用于高峰期间对某些服务限流。

网关服务

在 Spring Cloud 中,能够使用的网关服务,主要是两个,如下:

  • spring-cloud-netflix-zuul ,基于 Zuul1 实现、Netflix 最新开源的网关服务是 Zuul2 ,基于响应式的网关服务。
  • spring-cloud-gateway ,基于 Spring Webflux 实现。

为什么要网关服务?

  • 动态路由、灰度发布、健康检查
  • 限流、熔断
  • 认证: 如数支持 HMAC, JWT, Basic, OAuth 2.0 等常用协议
  • 鉴权: 权限控制,IP 黑白名单,同样是 OpenResty 的特性
  • 可用性、高性能

Zuul

作用:API 网关,路由,负载均衡等多种作用。

简介:类似 Nginx ,反向代理的功能,不过 Netflix 自己增加了一些配合其他组件的特性。

在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个 API网关根据请求的 url ,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。

Spring Cloud Gateway

SpringCloud Gateway 是 Spring Cloud 的一个全新项目,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。Spring Cloud Gateway 底层使用了高性能的通信框架Netty。

特征

  • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  • 集成 Hystrix 断路器
  • 集成 Spring Cloud DiscoveryClient
  • Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
  • 具备一些网关的高级功能:动态路由、限流、路径重写

从以上的特征来说,和Zuul的特征差别不大。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。

Filter(过滤器):和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。

Route(路由):网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。

Predicate(断言):这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。

个人博客:https://wei.itart.icu/

更多推荐

精选SpringCloud面试题