本文参考了CSDN博主 ThinkWon 整理发布的 《Spring Cloud面试题(2020最新版)》,在该文的基础上并汇总整理了网络相关资源,在整理的过程中对原文进行了验证和补充、以及多处的修正和解读等,旨在能更好的服务于广大读者。

具体参考文章,会再文末注明出处。

阅读文章的过程中如果有任何疑问,欢迎添加笔者为好友,拉您进【七日书摘】微信交流群,一起交流技术,一起打造高质量的职场技术交流圈子,抱团取暖,共同进步。
七日书摘官方群.jpg

为什么需要学习 Spring Cloud

任何应用在业务初期都很简单,通常会把它实现为单体架构。但是随着业务逐渐发展,产品会变得越来越复杂,单体架构的应用也会越来越复杂甚至到不堪重负。通常会有如下问题:

  • 代码结构混乱:业务复杂,导致代码量较大,管理会越来越困难。同时,这也会给业务的快速迭代带来巨大挑战;
  • 开发效率变低:开发人员同时在一套代码库上进行开发,很难避免代码冲突。开发过程中也会伴随着不断解决冲突的过程,这会严重的影响开发效率;
  • 排查解决问题成本高:线上业务出现 bug,修复 bug 的过程可能很简单。但是,由于只有一套代码,需要重新编译、打包、上线,成本很高。

由于单体架构的应用随着系统复杂度的增高,会暴露出各种各样的问题。因此随着近些年来微服务架构的发展,有了逐渐取代单体架构的趋势,且这种趋势将会越来越流行。

Spring Cloud 是目前最常用的微服务开发框架,已经在企业级开发中大量的应用。

什么是 Spring Cloud

Spring Cloud 是一系列框架的有序集合。它充分利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

同时Spring Cloud 并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

Spring Cloud 设计目标与优缺点

Spring Cloud 设计目标

协调各个微服务,简化分布式系统开发。

Spring Cloud 优缺点

微服务的框架那么多比如:dubbo、Kubernetes,为什么就要使用 Spring Cloud 的呢?

Spring Cloud 优点:
  • 产出于 Spring 大家族,Spring 在企业级开发框架中无人能敌,来头很大,可以保证后续的更新、完善;
  • 组件丰富,功能齐全。Spring Cloud 为微服务架构提供了非常完整的支持。例如、配置管理、服务发现、断路器、微服务网关等;
  • Spring Cloud 社区活跃度很高,教程很丰富,遇到问题很容易找到解决方案;
  • 服务拆分粒度更细,耦合度比较低,有利于资源重复利用,有利于提高开发效率;
  • 可以更精准的制定优化服务方案,提高系统的可维护性;
  • 减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发;
  • 微服务可以是跨平台的,可以用任何一种语言开发;
  • 适于互联网时代,产品迭代周期更短;
Spring Cloud 缺点:
  • 微服务过多,治理成本高,不利于系统维护;
  • 分布式系统开发的成本高(容错,分布式事务等)对团队挑战大;

总的来说优点大过于缺点,目前看来 Spring Cloud 是一套非常完善的分布式框架,目前很多企业开始使用采用微服务进行架构,而 Spring Cloud 的优势是显而易见的。因此对于想研究微服务架构的同学来说,学习 Spring Cloud 是一个不错的选择。

Spring Cloud 发展前景

Spring Cloud 对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用 Spring Cloud 一站式解决方案能在从容应对业务发展的同时大大减少开发成本。
同时,随着近几年微服务架构和 Docker 容器概念的火爆,也会让 Spring Cloud 在未来越来越 “云” 化的软件开发风格中立有一席之地,尤其是在五花八门的分布式解决方案中提供了标准化的、全站式的技术解决方案,意义可能会堪比当年 Servlet 规范的诞生,有效推进服务端软件系统技术水平的进步。

整体架构

Spring Cloud architecture diagram.png

主要项目

Spring Cloud 的子项目,大致可分成两类,一类是对现有成熟框架 Spring Boot 化的封装和抽象,也是数量最多的项目;第二类是开发了一部分分布式系统的基础设施的实现,如 Spring Cloud Stream 扮演的就是kafka, ActiveMQ 这样的角色。

Spring Cloud Config

集中配置管理工具,分布式系统中统一的外部配置管理,默认使用 Git 来存储配置,可以支持客户端配置的刷新及加密、解密操作。

Spring Cloud Netflix

Netflix OSS 开源组件集成,包括Eureka、Hystrix、Ribbon、Feign、Zuul 等核心组件。

  • Eureka:服务治理组件,包括服务端的注册中心和客户端的服务发现机制;
  • Ribbon:负载均衡的服务调用组件,具有多种负载均衡调用策略;
  • Hystrix:服务容错组件,实现了断路器模式,为依赖服务的出错和延迟提供了容错能力;
  • Feign:基于 Ribbon 和 Hystrix 的声明式服务调用组件;
  • Zuul:API 网关组件,对请求提供路由及过滤功能。

Spring Cloud Bus

用于传播集群状态变化的消息总线,使用轻量级消息代理链接分布式系统中的节点,可以用来动态刷新集群中的服务配置。

Spring Cloud Consul

基于 Hashicorp Consul 的服务治理组件。

Spring Cloud Security

安全工具包,对 Zuul 代理中的负载均衡、 OAuth2 客户端及登录认证进行支持。

Spring Cloud Sleuth

Spring Cloud 应用程序的分布式请求链路跟踪,支持使用Zipkin、HTrace 和基于日志(例如ELK)的跟踪。

Spring Cloud Stream

轻量级事件驱动微服务框架,可以使用简单的声明式模型来发送及接收消息,主要实现为 Apache Kafka 及RabbitMQ。

Spring Cloud Task

用于快速构建短暂、有限数据处理任务的微服务框架,用于向应用中添加功能性和非功能性的特性。

Spring Cloud Zookeeper

基于 Apache Zookeeper 的服务治理组件。

Spring Cloud Gateway

API 网关组件,对请求提供路由及过滤功能。

Spring Cloud OpenFeign

基于 Ribbon 和 Hystrix 的声明式服务调用组件,可以动态创建基于 Spring MVC 注解的接口实现用于服务调用,在 Spring Cloud 2.0 中已经取代 Feign 成为了一等公民。

Spring Cloud 的版本关系

Spring Cloud 是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管理 Spring Cloud 与各子项目的版本依赖关系,Spring Cloud 版本发布时会同步发布了一个组件版本依赖清单,会包括某个 Spring Cloud 版本对应的各子项目版本。
为了避免 Spring Cloud 版本号与子项目版本号混淆,Spring Cloud 版本采用了名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序,例如 Angel 是第一个版本,Brixton 是第二个版本。当 Spring Cloud 发布内容积累到临界点或者一个重大 BUG 被解决后,会发布一个 service releases 版本,简称 SRX 版本,比如 Greenwich.SR2 就是 Spring Cloud 发布的 Greenwich 版本的第 2 个 SRX 版本。目前 Spring Cloud 的最新版本是 Hoxton。

Spring Cloud 和 SpringBoot 版本对应关系

Spring Cloud Release Train VersionSpring Boot Version
Hoxton2.2.x
Greenwich2.1.x
Finchley2.0.x
Edgware1.5.x
Dalston1.5.x

Spring Cloud 和各子项目版本对应关系

ComponentEdgware.SR6Greenwich.SR5Hoxton.SR3
spring-cloud-bus1.3.4.RELEASE2.1.4.RELEASE2.2.1.RELEASE
spring-cloud-commons1.3.6.RELEASE2.1.5.RELEASE2.2.2.RELEASE
spring-cloud-config1.4.7.RELEASE2.1.6.RELEASE2.2.2.RELEASE
spring-cloud-netflix1.4.7.RELEASE2.1.5.RELEASE2.2.2.RELEASE
spring-cloud-security1.2.4.RELEASE2.1.5.RELEASE2.2.1.RELEASE
spring-cloud-consul1.3.6.RELEASE2.1.5.RELEASE2.2.2.RELEASE
spring-cloud-sleuth1.3.6.RELEASE2.1.7.RELEASE2.2.2.RELEASE
spring-cloud-streamDitmars.SR5Fishtown.SR42.2.1.RELEASE
spring-cloud-zookeeper1.2.3.RELEASE2.1.4.RELEASE2.2.2.RELEASE
spring-boot1.5.21.RELEASE2.1.x.RELEASE2.2.x.RELEASE
spring-cloud-task1.2.4.RELEASE2.1.4.RELEASE2.2.3.RELEASE
spring-cloud-gateway1.0.3.RELEASE2.1.5.RELEASE2.2.2.RELEASE
spring-cloud-openfeign暂无2.1.5.RELEASE2.2.2.RELEASE

注意:Hoxton 版本是基于 Spring Boot 2.2.x 版本构建的,不适用于 1.5.x 版本。随着2019年8月Spring Boot 1.5.x 版本停止维护,Edgware 版本也将停止维护。

Spring Boot 和 Spring Cloud 的区别?

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

Spring Cloud 是关注全局的微服务协调治理框架,它将Spring Boot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务。

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

使用 Spring Boot 开发分布式微服务时,我们面临以下问题:

  1. 与分布式系统相关的复杂性 -这种开销包括网络延迟开销,带宽问题,安全问题等。
  2. 服务发现 -服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
  3. 冗余-分布式系统中的冗余问题。
  4. 负载平衡 -负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。
  5. 性能 -问题,由于各种运营开销导致的性能问题。
  6. 部署复杂性 -Devops 技能的要求。

服务注册和发现是什么意思?Spring Cloud 如何实现?

通常在开发一个项目时会在属性文件中进行所有的配置,但随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂,有些服务可能会下线,而某些位置可能会发生变化,手动更改属性可能会产生各类问题。此时
Eureka 服务注册和发现可以在这种情况下提供帮助,由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。

Spring Cloud 和 Dubbo 区别?

服务调用方式: Dubbo 是 RPC,Spring Cloud 是 Rest API。
注册中心:Dubbo 使用 Zookeeper、Nacos 等, Spring Cloud 是 eureka,也可以是 Zookeeper等。
服务网关:截至目前 Dubbo 本身没有实现,只能通过其他第三方技术整合,Spring Cloud 有 Zuul、Gateway 等路由网关,作为路由服务器,进行消费者的请求分发,Spring Cloud 支持断路器,与 git 完美集成配置文件支持版本控制,事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。

负载均衡的意义什么?

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

什么是 Hystrix?它如何实现容错?

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

通常对于使用微服务架构开发的系统,涉及到许多微服务,这些微服务彼此协作。

思考如下微服务调用:
微服务调用.png

假设如果上图中的 Microservices 7 失败了,那么使用传统方法我们将传播一个异常,但这仍会导致整个系统崩溃。

同时随着微服务数量的增加,这个问题也会变得愈发复杂。针对此类情况可以使用 Hystrix 在这种情况下的 Fallback 方法功能进行优雅的解决。

假设我们有两个服务, employee-producer 使用由 employee-consumer 公开的服务,如下图:
employee-service.png

什么是 Hystrix 断路器?我们需要它吗?

现在假设由于某种原因,employee-consumer 公开的服务会抛出异常,在这种情况下使用 Hystrix 定义了一个 Fallback 回退方法,这种回退方法具有与公开服务相同的返回类型,可以在回退方法中返回一些值。
Fallback method.png

如果 firstPage method() 中的异常继续发生,则 Hystrix 将中断,并且员工使用者将一起跳过 firtsPage 方法,并直接调用回退方法。 断路器的目的是给第一页方法或第一页方法可能调用的其他方法留出时间,并直到异常恢复。可能发生的情况是,在负载较小的情况下,导致异常的问题有更好的恢复机会。
Circuit breakers.png

什么是 Netflix Feign?它的优点是什么?什么是 Netflix Feign?它的优点是什么?

Feign 是受到 Retrofit,JAXRS-2.0 和 WebSocket 启发的 java 客户端联编程序。

Feign 的第一个目标是将约束分母的复杂性统一到 http apis,而不考虑其稳定性。

在 employee-consumer 的例子中,employee-producer 使用 REST 模板公开 REST 服务。

但是我们必须编写大量代码才能执行以下步骤

  1. 使用功能区进行负载平衡。
  2. 获取服务实例,然后获取基本 URL。
  3. 利用 REST 模板来使用服务。

代码如下:

@Controller
public class ConsumerControllerClient {
@Autowired
private LoadBalancerClient loadBalancer;
public void getEmployee() throws RestClientException, IOException {
    ServiceInstance serviceInstance=loadBalancer.choose("employee-producer");
    System.out.println(serviceInstance.getUri());
    String baseUrl=serviceInstance.getUri().toString();
    baseUrl=baseUrl+"/employee";
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> response=null;
    try{
        response=restTemplate.exchange(baseUrl,
                    HttpMethod.GET, getHeaders(),String.class);
    }
    catch (Exception ex)
        {
        System.out.println(ex);
    }
    System.out.println(response.getBody());
}

可以看到使用 Netflix Feign 使服务请求变得更加轻松和简洁,如果 Netflix Ribbon 依赖关系也在类路径中,那么 Feign 默认也会负责负载平衡。

什么是 Spring Cloud Bus?我们需要它吗?

考虑以下情况:我们有多个应用程序使用 Spring Cloud Config 读取属性,而 Spring Cloud Config 从 GIT 读取这些属性。

下面的例子中多个 employee Producer 模块从 Employee Config Module 获取 Eureka 注册的属性。
consumer-properties.jpg

如果假设 git 中的 Eureka 注册属性更改为指向另一台 Eureka 服务器,会发生什么情况?在这种情况下,我们将不得不重新启动服务以获取更新的属性。

还有另一种使用执行器端点/刷新(ControllerEndpoint/actuator/refresh)的方式,但这不得不为每个模块单配置独调用这个执行器端点/刷新 Url。例如,如果 Employee Producer1 部署在端口 8080 上,调用 http://localhost:8080/actuator/refresh
同样对于 Employee Producer2 也需要调用 http://localhost:8080/actuator/refresh 等等,这会很麻烦。此时 Spring Cloud Bus 就是它该发挥作用的地方了。
spring-cloud-bus.jpg

如图 Spring Cloud Bus 提供了跨多个实例刷新配置的功能。
因此,在上面的示例中,如果我们刷新 Employee Producer1,则会自动刷新所有其他必需的模块。如果我们有多个微服务启动并运行,这将会特别有用。这是通过将所有微服务连接到单个消息代理来实现的,无论何时刷新实例,此事件都会订阅到侦听此代理的所有微服务,并且它们也会刷新,可以通过使用端点/总线/刷新来实现对任何单个实例的刷新。

Spring Cloud 断路器的作用

当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)

断路器有完全打开状态:一段时间内达到一定的次数无法调用时,并且多次监测没有恢复的迹象,此时断路器完全打开,那么下次请求就不会请求到该服务。

半开:短时间内有恢复迹象,断路器会将部分请求发给该服务,正常调用时断路器关闭。

关闭:当服务一直处于正常状态能正常调用。

什么是 Spring Cloud Config?

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理、实时更新,所以需要分布式配置中心组件。
在 Spring Cloud 中,有分布式配置中心组件 Spring Cloud Config ,它支持配置文件放在配置服务的内存中(即本地),也支持放在远程 Git 仓库中。在 Spring Cloud Config 组件中,分两个角色,一是 Config Server,二是 Config Client。

Spring Cloud Config使用:

  • 添加pom依赖
  • 配置文件添加相关配置
  • 启动类添加注解 @EnableConfigServer

什么是Spring Cloud Gateway?

Spring Cloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,用于取代 Zuul 网关(因为 Zuul 网关闭源已经性能原因)。网关作为流量入口在微服务系统中有着非常重要的作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

使用了一个 RouteLocatorBuilderbean 去创建路由,除了创建路由 RouteLocatorBuilder 可以让你添加各种 predicatesfilterspredicates 是断言的意思,顾名思义就是根据具体的请求的规则由具体的 route 去处理,filters 是各种过滤器,用来对请求做各种判断和修改。

------完------

推荐阅读:

Java基础知识面试题篇(2020年2月最新版)")

Spring Boot 面试题集(2020年2月最新版)

Spring MVC面试题集(2020年2月最新版)

更多面试题集,欢迎进入面试题集专栏

更多面试题集欢迎进入七日书摘官方群: 七日书摘官方群

七日书摘官方群群聊二维码.png

原文链接:https://thinkwon.blog.csdn.net/article/details/104397367

参考资源:
https://spring.io/cloud
https://cloud.spring.io/spring-cloud-static/Hoxton.SR3/reference/html/spring-cloud.html