Spring Cloud 是构建在 Spring Boot 基础之上,用于快速构建分布式系统的通用模式的工具集。或者说,换成大家更为熟知的,用于构建微服务的技术栈。
而后,不同厂商结合自身的中间件,提供自身的SpringCloud套件,例如:
当然SpringCloud还是提供了自身的一些组件的:
下面我们把 Spring Cloud 官方、Netflix、Alibaba 三者整理成如下表格:
SpringCloud 官方 | Netflix | Alibaba | |
---|---|---|---|
配置中心 | Spring Cloud Config、Spring Cloud Vault | Archaius | Nacos |
注册中心 | Eureka | Nacos | |
服务调用 | Spring Cloud OpenFeign、RestTemlete | Dubbo | |
负载均衡 | Spring Cloud Load Balancer | Ribbon | Dubbo |
服务容错 | Hystrix | Sentinel | |
API网关 | Spring Cloud Gateway | Zuul | |
消息驱动 | Spring Cloud Stream RabbiltMQ、Spring Cloud Stream Kafka | Spring Cloud Stream RecketMQ | |
事件总线 | Spring Cloud Bus | Spring Cloud Bus RecketMQ | |
链路跟踪 | Spring Cloud Sleuth | ||
分布式事物 | Seate | ||
分布式调度 | SchedulerX |
Spring Cloud Alibaba 套件,阿里开源组件、阿里云商业组件整合进 Spring Cloud 体系当中,同时对 Spring Cloud Gateway、OpenFeign、Ribbon 等等进行集成。
主要功能如下:
Spring Boot 专注于快速方便的开发单个个体微服务。
Spring Cloud 是关注全局的微服务协调整理治理框架以及一整套的落地解决方案,它将 Spring Boot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理,服务发现,断路器,路由,微代理,事件总线等的集成服务。
Spring Boot 可以离开 Spring Cloud 独立使用,但是 Spring Cloud 离不开 Spring Boot ,属于依赖的关系。
查看文献:什么是微服务?
优点
缺点
服务注册中心就是服务实现服务化的核心组件,类似于目录服务的作用,主要用来存储服务信息。服务注册中心是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理论 | 通信 | 配置中心 | |
---|---|---|---|
Zookerper | CP | RPC | 不支持 |
Nacos | AP | HTTP(2.0版本后为gRPC) | 支持 |
Eruka | AP | HTTP | 不支持 |
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中,客户端应用程序可以直接在另一台计算机上的服务器应用程序上调用方法,就好像它是本地对象一样,从而使您更轻松地创建分布式应用程序和服务。
适用场景:
简单来说,随着业务的发展,单台服务无法支撑访问的需要,于是搭建多个服务形成集群。那么随之要解决的是,每次请求,调用哪个服务,也就是需要进行负载均衡。
目前负载均衡有两种模式:客户端模式、服务端模式
在 Spring Cloud 中,我们使用前者,即客户端模式。
客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从Eureka服务注册中心获取的。
在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。
作用:主要提供客户侧的软件负载均衡算法。
简介:Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。
原理:Ribbo是一个基于HTTP和TCP的客户端负载均衡器,当我们将Ribbon和Eureka一起使用时,Ribbon会从Eureka注册中心去获取服务端列表,然后进行轮询访问以到达负载均衡的作用,客户端负载均衡中也需要心跳机制去维护服务端清单的有效性,当然这个过程需要配合服务注册中心一起完成。
参考文献
其中,默认的负载均衡算法是 Round Robin 算法,顺序向下轮询。
Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
Feign的一个关键机制就是使用了动态代理。咱们一起来看看下面的图,结合图来分析:
Ribbon 和 Feign 都是使用于调用用其余服务的,不过方式不同。
参考文献
在 Spring Cloud 中,能够使用的服务保证,如下:
spring-cloud-netflix-hystrix ,基于 Hystrix 实现。
Resilience4j
spring-cloud-alibaba-sentinel ,基于 Sentinel 实现。
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的 100% 可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累积,导致服务瘫痪,甚至导致服务“雪崩”。为了解决这个问题,就出现断路器模型。
作用:断路器,保护系统,控制故障范围。
简介:Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。
Hystrix 有两种隔离策略:线程池隔离、信号量隔离。
实际场景下,使用线程池隔离居多,因为支持超时功能。
详细的,可以参考文献
Hystrix 提供缓存功能,作用是:减少重复的请求数、在同一个用户请求的上下文中,相同依赖服务的返回数据始终保持一致。
Hystrix 断路器通过 HystrixCircuitBreaker 实现。
HystrixCircuitBreaker 有三种状态 :
CLOSED :关闭
OPEN :打开
HALF_OPEN :半开
其中,断路器处于 OPEN 状态时,链路处于非健康状态,命令执行时,直接调用回退逻辑,跳过正常逻辑。
在 Hystrix 断路器熔断时,可以调用一个降级方法,返回相应的结果。当然,降级方法需要配置和编码,如果不需要,也可以不写,也就是不会有服务降级的功能。
Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
Sentinel | Hystrix | |
---|---|---|
隔离级别 | 信号量隔离 | 线程池隔离/信号量隔离 |
熔断降级策略 | 基于响应时间或失败比例 | 基于失败比例 |
扩展性 | 多个SPI扩张点 | 插件扩展 |
限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 |
控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 |
适配 | Servlet、Spring Cloud、Dubbo、gRPC等 | Servlet、Spring Cloud Netfilx |
在 Spring Cloud 中,能够使用的网关服务,主要是两个,如下:
作用:API 网关,路由,负载均衡等多种作用。
简介:类似 Nginx ,反向代理的功能,不过 Netflix 自己增加了一些配合其他组件的特性。
在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个 API网关根据请求的 url ,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。Spring Cloud Gateway 底层使用了高性能的通信框架Netty。
特征
从以上的特征来说,和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/