Spring Cloud 面试题

165 阅读10分钟

Spring Cloud 面试题

##(1)什么是 Spring Cloud?

  • Spring Cloud 基于 Spring Boot 使得整体的开发、配置、部署都非常方便,可快速搭建基于微服务的分布式应用,Spring Cloud 相当于微服务各组件的集大成者。
  • Spring Boot 和 Spring Cloud 的关系可大致理解为,Spring Boot 快速搭建基础系统,Spring Cloud 在此基础上实现分布式系统中的公共组件,如服务注册、服务发现、配置管理、熔断器、控制总线等,服务调用方式是基于 REST API,整合了各种成熟的产品和架构。

(2)Spring Cloud 和 Spring 之间有什么关联关系?

Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发。服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。为了解决微服务架构中服务治理而提供的具备一系列功能的开发框架,并且 Spring Cloud 是完全基于 Spring Boot 进行开发的,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。

(3)Spring Cloud 实现服务注册和发现的原理是什么?

  • 服务在发布时指定对应的服务名(服务名包括了 IP 地址和端口)将服务注册到注册中心(Eureka 或者 Zookeeper)这一过程是 Spring Cloud 自动实现的,只需要在 main 方法添加 @EnableDisscoveryClient 即可,同一个服务修改端口就可以启动多个实例。
  • 调用方法:传递服务名称通过注册中心获取所有的可用实例,通过负载均衡策略调用(Ribbon 和 Feign)对应的服务。

(4)Ribbon 和 Feign 有什么区别?

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

  • 启动类使用的注解不同,Ribbon 使用的是 @RibbonClient,Feign 用的是 @EnableFeignClients。
    服务的指定位置不同,Ribbon 是在 @RibbonClient 注解上声明,Feign 则是在定义抽象方法的接口上使用 @FeignClient 声明。
  • 调用方式不同,Ribbon 需要自己构建 HTTP 请求,模拟 HTTP 请求然后使用 RestTemplate 发送给其他服务,步骤相当繁琐。
  • Feign 则是在 Ribbon 的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可。不需要自己构建 HTTP 请求,不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。

(5)为什么要使用 Spring Cloud 熔断器,它的作用是什么?

当一个服务调用另一个服务,由于网络原因或者自身原因出现问题时 ,调用者就会等待被调者的响应,当更多的服务请求到这些资源时,导致更多的请求等待,这样就会发生连锁效应,断路器就是解决这一问题的。

断路器的状态有以下几种:

  • 完全打开:一定时间内,达到一定的次数无法调用,并且多次检测没有恢复的迹象,断路器完全打开,那么下次的请求不会请求到该服务。
  • 半开:短时间内有恢复迹象,断路器会将部分请求发送给服务,当能正常调用时,断路器关闭。
  • 关闭:服务一直处于正常状态,能正常调用,断路器关闭。

(6)什么是 Hystrix?

Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。通常对于使用微服务架构开发的系统,涉及到许多微服务,这些微服务彼此协作, 随着微服务数量的增加,这个问题变得更加复杂。我们将使用 Hystrix 的 Fallback 方法来处理,假设由于某种原因,公开的服务接口抛出异常,我们在这种情况下使用 Hystrix 定义一个回退方法。这种后备方法应该具有与公开服务相同的返回类型,如果暴露服务中出现异常,回退方法将返回对应信息。

(7)Eureka 和 ZooKeeper 有哪些区别?

  • Eureka 不再从注册列表移除因长时间没收到心跳而应该过期的服务;Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点(高可用);当网络稳定时,当前实例新的注册信息会被同步到其他节点中(最终一致性);Eureka 可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像 ZooKeeper 一样使得整个注册系统瘫痪。
  • ZooKeeper 有 Leader 和 Follower 角色,Eureka 各个节点平等。ZooKeeper 采用过半数存活原则,Eureka 采用自我保护机制解决分区问题。

(8)为什么要使用负载均衡?

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

(9)Spring Cloud 实现服务注册和发现的具体流程是什么?

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

(10)为什么要使用 Spring Cloud ,它有哪些优势?

  • 解决与分布式系统相关的复杂性问题,这种开销包括网络问题、延迟开销、带宽问题、安全问题。
  • 服务发现—服务发现工具管理群集中的流程和服务如何查找和互相交谈,它涉及一个服务目录,在该目录中-注册服务,然后能够查找并连接到该目录中的服务。
  • 解决分布式系统中的冗余问题。
  • 负载平衡改善跨多个计算资源的工作负荷,诸如计算机、计算机集群、网络链路、中央处理单元或磁盘驱动器的分布。

(11)Feign 和 Ribbon + RestTemplate 的区别是什么?

Ribbon + RestTemplate 实现了服务调用的负载均衡,相比较于这种方式,使用 Feign 可以直接通过声明式接口的形式来调用服务,非常方便,比 Ribbon 使用起来要更加简便,只需要创建接口并添加相关注解配置,即可实现服务消费的负载均衡。

Feign 的特点

  • Feign 是一个声明式 Web Service 客户端
  • 支持 Feign 注解、JAX-RS 注解、Spring MVC 注解
  • Feign 基于 Ribbon 实现,使用起来更加简单
  • Feign 集成了 Hystrix,具备服务熔断功能

(12)微服务架构的拆分都有哪些原则?

  • 基于业务逻辑拆分
    将系统中的业务模块按照职责范围识别出来,每个单独的业务模块拆分为一个独立的服务。

      例如,做一个电商系统,可以划分为商品、交易、用户 3 个服务,也可以划分为商品、订单、支付、发货、买家、卖家 6 个服务。
    
  • -基于可扩展拆分
    将系统中的业务模块按照稳定性排序,将已经成熟和改动不大的服务拆分为稳定服务,将经常变化和迭代的服务拆分为变动服务。稳定服务的粒度可以粗一些,即使逻辑上关联不强的也可以放在一个服务中,例如日志服务、升级服务放在一个子系统中。变动服务的粒度可以细一些,但要注意服务的数量。这种拆分方式是为了提升项目快速迭代的效率,避免变动服务的改动升级影响了成熟的功能。

  • 基于可靠性拆分
    将系统中可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。

  • 基于性能拆分
    将性能压力大的模块拆出来,避免影响其他服务,同时对其做性能提升、高可用等优化都更简单高效。例如电商的抢购,排队功能的性能压力很大,就可以将其独立为一个服务。

(13)Spring Boot 和 Spring Cloud 有哪些区别?

  • Spring Boot 专注于快速方便地开发单个个体微服务。
  • Spring Cloud 是关注全局的微服务协调、整理、治理的框架,它将 Spring Boot 开发的单体整合并管理起来。
  • Spring Boot 可以脱离 Spring Cloud 独立使用开发项目,但是 Spring Cloud 离不开 Spring Boot,属于依赖关系。

(14)谈谈微服务之间是如何实现通信的。

远程过程调用(Remote Procedure Invocation)也就是我们常说的服务的注册与发现,直接通过远程过程调用来访问别的 service。

  • 优点:简单,因为没有中间件代理,系统更简单。
  • 缺点:只支持请求/响应的模式,不支持其他类型,比如通知、请求/异步响应、发布/订阅、发布/异步响应降低了可用性,因为客户端和服务端在请求过程中必须都是可用的。
    使用异步消息来做服务间通信,服务间通过消息管道来交换消息,从而通信。

(15)谈谈你对微服务的理解。

  • 简单来说,微服务就是将一个单体应用拆分成若干个小型的服务,协同完成系统功能的一种架构模式,在系统架构层面进行解耦合,将一个复杂问题拆分成若干个简单问题。这样的好处是对于每一个简单问题,开发、维护、部署的难度就降低了很多,可以实现自治,可自主选择最合适的技术框架,提高了项目开发的灵活性。
  • 微服务架构不仅是单纯的拆分,拆分之后的各个微服务之间还要进行通信,否则就无法协同完成需求,也就失去了拆分的意义。不同的微服务之间可以通过某种协议进行通信,相互调用、协同完成功能,并且各服务之间只需要制定统一的协议即可,至于每个微服务是用什么技术框架来实现的,统统不需要关心。这种松耦合的方式使得开发、部署都变得更加灵活,同时系统更容易扩展,降低了开发、运维的难度。