必须掌握的微服务常见面试题

我是「猿码天地」,一个热爱技术、热爱编程的IT猿。技术是开源的,知识是共享的!

写作是对自己学习的总结和记录,如果您对 Java、分布式、微服务、中间件、Spring Boot、Spring Cloud等技术感兴趣,可以关注我的动态,我们一起学习,一起成长!

用知识改变命运,让家人过上更好的生活,互联网人一家亲!

——猿人《猿码天地》

01 Spring Cloud是什么?

Spring Cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务注册与发现、负载均衡、声明式调用、熔断器、路由网关、配置中心、服务链路追踪、微服务监控等,都可以用 spring boot 的开发风格做到一键启动和部署。

02 Spring Cloud 的核心组件有哪些?

1、服务注册与发现 Eureka、Zookeeper组件

2、负载均衡 Ribbon组件

3、声明式调用 Feign组件

4、熔断器 Hystrix组件

5、路由网关组件 Spring Cloud Zuul组件

6、 配置中心 Spring Cloud Config、Diamond(阿里)、Disconf(百度)、Apollo(携程)组件

7、服务链路追踪 Spring Cloud Sleuth组件

8、微服务监控 Spring Boot Admin组件

03 Spring Cloud 和 Dubbo 比较

SpringCloud 和 Dubbo 都是现在主流的微服务架构

SpringCloud 是 Apache 旗下的 Spring 体系下的微服务解决方案

Dubbo 是阿里系的分布式服务治理框架

从技术维度上讲

Spring Cloud 远远超过 Dubbo,Dubbo 本身只是实现了服务治理功能, 对于SpringCloud 现在以及有 21 个子项目以后还会更多。

但是由于RPC以及注册中心元数据等原因,在技术选型的时候我们只能二者选其一,所以我们常常用它俩来对比。

服务的调用方式 Dubbo 使用的是 RPC 远程调用,而 SpringCloud 使用的是 Rest API,其实更符合微服务官方的定义。

服务的注册中心来看,Dubbo 使用了第三方的 ZooKeeper 作为其底层的注册中心,实现服务的注册和发现,SpringCloud 使用 Spring Cloud Netflix Eureka 实现注册中心,当然 SpringCloud 也可以使用 ZooKeeper 实现,但一般我们不会这样做。

服务网关,Dubbo 并没有本身的实现,只能通过其他第三方技术的整合,而 SpringCloud 有 Zuul 路由网关,作为路由服务器,进行消费者的请求分发,SpringCloud 还支持断路器,与git完美集成分布式配置文件支持版本控制等。

从技术选型上讲

目前国内的分布式系统选型主要还是 Dubbo,毕竟国产,而且国内工程师的技术熟练程度高, 并且 Dubbo 在其他维度上的缺陷可以由其他第三方框架进行集成进行弥补。

而 SpringCloud 目前是国外比较流行,当然我觉得国内的市场也会慢慢的偏向 SpringCloud,就连刘军作为Dubbo 重启的负责人也发表过观点,Dubbo 的发展方向是积极适应SpringCloud 生态,并不是起冲突。

Rest 和 RPC 对比

其实如果仔细阅读过微服务提出者马丁福勒的论文的话可以发现其定义的服务间通信机制     就是 Http Rest。

RPC 最主要的缺陷就是服务提供方和调用方式之间依赖太强,我们需要为每一个微服务进行接口的定义,并通过持续继承发布,需要严格的版本控制才不会出现服务提供和调用之间因为版本不同而产生的冲突。

而 REST 是轻量级的接口,服务的提供和调用不存在代码之间的耦合,只是通过一个约定进行规范,但也有可能出现文档和接口不一致而导致的服务集成问题,但可以通过 swagger 工具整合,是代码和文档一体化解决,所以 REST 在分布式环境下比 RPC 更加灵活。这也是为什么当当网的 DubboX 在对 Dubbo 的增强中增加了对 REST 的支持的原因。

文档质量和社区活跃度

SpringCloud 社区活跃度远高于 Dubbo,毕竟由于梁飞团队的原因导致 Dubbo 停止更新迭代五

年,而中小型公司无法承担技术开发的成本导致 Dubbo 社区严重低落,而 SpringCloud 异军突起,迅速占领了微服务的市场,背靠 Spring 混的风生水起。

Dubbo 也在经过多年的积累文档方面相当成熟,对于微服务的架构体系各个公司也有稳定的现状。

04 谈谈 Spring Boot 和 Spring Cloud 的区别和联系

SpringBoot 是 Spring 推出用于解决传统框架配置文件冗余,装配组件繁杂的基于 Maven 的解决方案,旨在快速搭建单个微服务。

而 SpringCloud 专注于解决各个微服务之间的协调与配置,服务之间的通信,熔断,负载均衡等技术维度, 并且 SpringCloud 是依赖于 SpringBoot 的, 而 SpringBoot 并不是依赖SpringCloud,甚至还可以和 Dubbo 进行优秀的整合开发。

总结如下:

1、 SpringBoot 专注于快速方便的开发单个个体的微服务。

2、SpringCloud 是关注全局的微服务协调整理治理框架,整合并管理各个微服务,为各个微服务之间提供服务注册与发现、负载均衡、声明式调用、熔断器、路由网关、配置中心、服务链路追踪、微服务监控等集成服务。

3、SpringBoot 不依赖于 SpringCloud,SpringCloud 依赖于 SpringBoot,属于依赖关系。

4、SpringBoot 专注于快速、方便的开发单个的微服务个体,SpringCloud 关注全局的服务治理框架。

05 Spring Cloud 如何实现服务注册和发现?

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

1、服务发布时,指定对应的服务名,将服务注册到注册中心(eureka或zookeeper)

2、 注册中心加@EnableEurekaServer,服务用@EnableDiscoveryClient,然后用 ribbon 或 feign 进行服务直接的调用发现。

06 什么是 Ribbon 组件?

负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。一种是独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上,例如 Ngnix。另一种是将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份服务提供者的信息列表,有了信息列表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到负载均衡的目的。

Ribbon 是 Netflix 公司开源的一个负载均衡的组件,它属于上述的第二种方式,是将负载均衡逻辑封装在客户端中,并且运行在客户端的进程里。Ribbon 是一个经过了云端测试的 IPC 库,司以很好地控制 HTTP 和 TCP 客户端的负载均衡行为。

在 Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器,有两种使用 方式,一种是和 RestTemplate 相结合,另一种是和 Feign 相结合。Feign 已经默认集成了 Ribbon。

Rbbon 有很多子模块,但很多模块没有用于生产环境,目前Netflix 公司用于生产环境的 Ribbon 子模块如下:

Rribbon-loadbalancer:可以独立使用或与其他模块一起使用的负载均衡器 API。

Ribbon-eureka:Rbbon 结合 Eureka 客户端的 API,为负载均衡器提供动态服务注册列表信息。Rribbon-core: Ribbon 的核心 API。

07 什么是声明式调用 Feign?

在微服务中,服务的消费可以通过 RestTemplate 来消费服务,可以结合 Ribbon 在消费服务时 做负载均衡。同时可通过 Feign 来远程调度其他服务。Feign 受 Retrofit、 JAXRS-2.0 和 WebSocket 的影响, 采用了声明式API接口 的风格,将Java Http客户端绑定到它的内部。Feign的首要目标是将 Java Http 客户端调用过程变得简单。

08 什么是熔断器 Hystrix?

在分布式系统中,服务与服务之间的依赖错综复杂, 一种不可避免的情况就是某些服务会出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞。Hystrix 是 Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了整个分布式系统的弹性。

09 路由网关组件Zuul作用是什么?

Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用,主要体现在以下 6 个方面:

1、Zuul、 Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例。

2、网关将所有服务的 API 接口统一聚合,并统一对外暴露。外界系统调用 API 接口时, 都是由网关对外暴露的 API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的 API 接口 , 防止其被外界直接调用,导致服务的敏感信息对外暴露。

3、网关服务可以做用户身份认证和权限认证,防止非法请求操作 API 接口,对服务器起到保护作用。

4、网关可以实现监控功能,实时日志输出,对请求进行记录。

5、网关可以用来实现流量监控, 在高流量的情况下,对服务进行降级。

6、API 接口从内部服务分离出来, 方便做测试。

10 Spring Cloud Config 组件

Spring Cloud Config 是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

常用的微服务统一配置框架有:Spring Cloud Config、Diamond(阿里)、Disconf(百度)、Apollo(携程)等。

11 Eureka 自我保护机制是什么?

当 Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式。

12 为什么需要 Spring Cloud Sleuth?

微服务架构是一个分布式架构,微服务系统按业务划分服务单元, 一个微服务系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性较高,如果出现了错误和异常,很难去定位。主要体现在一个请求可能需要调用很多个服务,而内部服务的调用复杂性决定了问题难以定位。所以在微服务架构中,必须实现分布式链路追踪, 去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题能够快速定位的目的。

比如:在微服务系统中, 一个来自用户的请求先到达前端 A (如前端界面),然后通过远程调用,到达系统的中间件 B、 C (如负载均衡、网关等),最后到达后端服务 D、 E, 后端经过一系列的业务逻辑计算, 最后将数据返回给用户。对于这样一个请求,经历了这么多个服务, 怎么样将它的请求过程用数据记录下来呢?这就需要用到服务链路追踪。

Google 开源了 Dapper 链路追踪组件,并在 2010 年发表了论文《Dapper, a La电e-Scale Distributed Systems Tracing Infrastructure》,这篇论文是业内实现链路追踪的标杆和理论基础, 具有很高的参考价值。

目前,常见的链路追踪组件有 Google 的 Dapper、 Twitter 的 Zipkin, 以及阿里的 Eagleeye (鹰眼)等,它们都是非常优秀的链路追踪开源组件。在 Spring Cloud Sleuth 中集成 Zipkin 非常简单,只需要引入相应的依赖并做相关的配置即可。

13 微服务监控 Spring Boot Admin 组件是什么?

Spring Boot Admin 用于管理和监控一个或者多个 Spring Boot 程序。Spring Boot Admin 分 为 Server 端和 Client 端, Client 端可以通过 Http 向 Server 端注册,也可以结合 Spring Cloud 的服务注册组件 Eureka 进行注册。Spring Boot Admin 提供了用 AngularJs 编写的 Ul界面,用于管理和监控。其中监控内容包括 Spring Boot 的监控组件 Actuator 的各个 Http 节点,也支持更高级的功能,包括 Turbine、 Jmx、 Loglevel 等。

我们可以使用 Spring Boot Admin 监控 Spring Cloud 微服务、可以使用Spring Boot Admin 集成 Turbine,聚合监控微服务系统中熔断器的状况、可以使用Spring Boot Admin 集成 Security 安全登录界面等。

14 什么是服务雪崩?

在微服务中,我们是服务与服务之间调用,当在微服务突然有大量的请求过来,一个服务瘫痪之后,后面的服务请求积压,这就造成了服务雪崩。一个服务瘫痪,另外调用这个服务的服务就会超时,导致整个服务群瘫痪。

15 微服务设计原则是什么?

软件设计就好比建筑设计。Architect 这个词在建筑学中是“建筑师”的意思,而在软件领域里则是“架构师”的意思,可见它们确实有相似之处。无论是建筑师还是架构师,他们都希望把作品设计出自己的特色,并且更愿意把创造出的东西被称为艺术品。然而现实却是,建筑设计和软件设计有非常大的区别。建筑师设计并建造出来的建筑往往很难有变化,除非拆了重建。而架构师设计出来的软件系统,为了满足产品的业务发展,在它的整个生命周期中,每一个版本都有很多的变化。

软件设计每一个版本都在变化,所以软件设计应该是渐进式发展。软件从一开始就不应该被设计成微服务架构,微服务架构固然有优势,但是它需要更多的资源,包括服务器资源、技术人员等。追求大公司所带来的技术解决方案,刻意地追求某个新技术,企图使用技术解决所有的问题,这些都是软件设计的误区。

技术应该是随着业务的发展而发展的,任何脱离业务的技术是不能产生价值的。在初创公司,业务很单一时,如果在 LAMP 单体构架够用的情况下,就应该用 LAMP,因为它开发速度快,性价比高。随着业务的发展,用户量的增加,可以考虑将数据库读写分离、加缓存、加负载均衡服务器、将应用程序集群化部署等。如果业务还在不断发展,这时可以考虑使用分布式系统,例如微服务架构的系统。不管使用什么样的架构,驱动架构的发展一定是业务的发展, 只有当前架构不再适合当前业务的发展,才考虑更换架构。

在微服务架构中,有三大难题,那就是服务故障的传播性、服务的划分和分布式事务。在微服务设计时, 一定要考虑清楚这三个难题,从而选择合适的框架。目前比较流行的微服务框 架有 Spring 社区的 Spring Cloud、Google 公司的 Kubemetes 等。不管使用哪一种框架或者工具, 都需要考虑这三大难题。为了解决服务故障的传播性, 一般的微服务框架都有熔断机制组件。另外,服务的划分没有具体的划分方法, 一般来说根据业务来划分服务, 领域驱动设计具有指导作用 。最后,分布式事务一般的解决办法就是两阶段提交或者三阶段提交,不管使用哪一种 都存在事务失败,导致数据不一致的情况,关键时刻还得人工去恢复数据。总之,微服务的设计一定是渐进式的,并且是随着业务的发展而发展的。

扫描二维码关注公众号 : 猿码天地

你多学一样本事,就少说一句求人的话,现在的努力,是为了以后的不求别人,实力是最强的底气。记住,活着不是靠泪水博得同情,而是靠汗水赢得掌声。

——《写给程序员朋友》

猜你喜欢

转载自blog.csdn.net/zbw125/article/details/107502907