SpringCloud 面试题之一

微服务

微服务的概述

微服务理论的提出者马丁。福勒(Martin Fowler) 在其博客中详细描述了什么是微服务。微服务强调的是服务的大小,它关注的是某一个点,是具体解决某一个问题 / 提供落地对应服务的一个服务应用;狭意的看,可以看作 Eclipse 里面的一个个微服务工程 / 或者 Module。

微服务架构的概述

微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分为一组小服务,每个服务运行在自己的独立进程中,服务间通信采用轻量级通信机制 (通常是基于 HTTP 的 RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应该尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的编程语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的编程语言来编写服务,也可以使用不同的数据存储技术。

微服务架构的优缺点

  • 优点:

    • 易于开发和维护:一个微服务只会关注一个特定的业务功能,所以它业务清晰,代码量较少
    • 单个微服务启动较快:单个微服务代码量较少,所以启动会比较快
    • 业务之间松耦合,无论是在开发阶段或者部署阶段,不同的服务都是互相独立的
    • 局部修改容易部署:单体应用只要有修改,就得重新部署整个应用,微服务解决了这样的问题
    • 技术栈不受限:在微服务架构中,可以结合项目业务及团队的特点,合理地选择技术栈
    • 按需伸缩:可根据需求,实现细粒度的扩展
    • 只有业务逻辑的代码,不会和 HTML、CSS 或者其他前端页面耦合,目前有两种开发模式:前后端分离、全栈开发
  • 缺点:

    • 运维要求高:更多的服务意味着更多的运维投入
    • 技术开发难度高:涉及到网络通信延迟、服务容错、数据一致性、系统集成测试、系统部署依赖、性能监控等
    • 分布式系统固有的复杂性:使用微服务架构的是分布式系统,对于一个分布式系统,系统容错,网络延迟,分布式事务等都会带来巨大的挑战
    • 接口调整成本高:微服务之间通过接口进行通信。如果修改某一个微服务的 API,可能所有使用了该接口的微服务都需要做调整
    • 重复劳动:很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复

SpringBoot 与 SpringCloud

SpringBoot 与 SpringCloud 的关系

  • SpringBoot 专注于快速、方便的开发单个微服务个体,SpringCloud 则关注全局的服务治理
  • SpringCloud 将 SpringBoot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等集成的服务
  • SpringBoot 可以离开 SpringCloud 独立使用开发项目,但是 SpringCloud 离不开 SpringBoot,属于依赖的关系

Dubbo 对比 SpringCloud

RPC 与 REST 的区别

微服务理论的提出者马丁。福勒(Martin Fowler),在其论文中可以发现其定义的服务间通信机制就是 HTTP REST。RPC 的性能比较出众,其最主要的缺陷就是服务提供方和调用方式之间依赖太强,毕竟需要为每一个微服务进行接口的定义,并通过持续集成发布,需要严格的版本控制才不会出现服务提供和调用之间因为版本不同而产生的冲突。而 REST 是轻量级的接口,服务的提供和调用不存在代码之间的耦合,只是通过一个约定进行规范,但也有可能出现文档和接口不一致而导致的服务集成问题,但可以通过 Swagger 工具整合,是代码和文档一体化解决,所以 REST 在分布式环境下比 RPC 更加灵活,这也是为什么当当网的 DubboX 在对 Dubbo 的增强中增加了对 REST 的支持的原因。

Dubbo 与 SpringCloud 的区别

功能 DubboSpringCloud
服务注册中心 Zookeeper、Nacos、RedisSpring Cloud Netfix Eureka
服务调用方式 RPCREST API
服务监控 Dubbo-MonitorSpring Boot Admin
熔断器 SentinelSpring Cloud Netflix Hystrix
服务网关 Spring Cloud Netflix Zuul
分布式配置 NacosSpring Cloud Config
服务跟踪 Spring Cloud Sleuth
数据流 Spring Cloud Stream
批量任务 Spring Cloud Task
信息总线 Spring Cloud Bus

最大区别:SpringCloud 抛弃了 Dubbo 的 RPC 通信,采用的是基于 HTTP 的 REST 方式。严格来说这两种技术方案各有优劣。虽然从一定程度上来说,SpringCloud 牺牲了服务调用的性能,但也避免了原生 RPC 带来的问题。而且 REST 相比 RPC 更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适。

定位区别:Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而 SpringCloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了 Spirng、SpirngBoot 的优势之上,两个框架在开始目标就不一致,Dubbo 定位为 RPC 框架、SpirngCloud 定位为微服务架构下的一站式解决方案(微服务生态)。作为重启 Dubbo 开源项目的负责人刘军也曾表示,如果非要类比的话,Dubbo 可以类比为 Netfix OSS 技术栈,而 SpringCloud 集成了 Netfix OSS 作为分布式服务治理解决方案,但除此之外 SpringCloud 还提供了包括 config、stream、security 等等分布式问题解决方案。当前由于 RPC 协议、注册中心元数据不匹配等问题,在面临微服务基础框架选型时,Dubbo 与 SpringCloud 只能二选一。Dubbo 日后可能会积极适配到 SpringCloud 生态,比如作为 SpringCloud 的二进制通讯方案来发挥 Dubbo 的性能优势,或者 Dubbo 通过模块化以及对 HTTP 的支持适配到 SpringCloud。

品牌机与组装机的区别:Spring Cloud 的功能很明显比 Dubbo 更加强大,涵盖面更广,而且作为 Spring 的旗舰项目,它也能够与 Spring Framework、Spring Boot、Spring Data、Spring Batch 等其他 Spring 项目完美融合,这些对于微服务而言是至关重要的。使用 Dubbo 构建的微服务架构就像组装电脑,各环节选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果使用者是一名高手,那这些都不是问题。而 Spring Cloud 就像品牌机,在 Spring Source 的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础原理有足够的了解。

社区支持与更新力度的区别:最为重要的是,Dubbo 停止了 5 年左右的更新,虽然 2017.9 重启了。对于技术发展的新需求,需要由开发者自行拓展升级(比如当当网自研了 Dubbox),这对于很多想要采用微服务架构的中小型软件公司,显然是不太合适的。中小型软件公司没有这么强大的技术能力去修改 Dubbo 源码 + 周边的一整套解决方案,并且不是每一个公司都有阿里的大牛 + 真实的线上生产环境测试经修改过源码的框架。

其他组件对比

Eureka 对比 ZooKeeper

  1. ZooKeeper 保证的是 CP,Eureka 保证的是 AP
  2. Eureka 本质上是一个工程,而 ZooKeeper 只是一个进程
  3. ZooKeeper 有 Leader 和 Follower 角色,Eureka 各个节点是平等关系
  4. ZooKeeper 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用;Eureka 只要有一实例就可以保证服务可用,但查询到的数据可能并不是最新的
  5. ZooKeeper 采用过半数存活原则,Eureka 采用自我保护机制解决分区问题
  6. Eureka 自我保护机制会导致:
  • Eureka 不再从注册列表移除因长时间没收到心跳而应该过期的服务
  • Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点(高可用)
  • Eureka 在网络稳定的时候,当前实例新的注册信息会被同步到其他节点中(最终一致性)
  • Eureka 可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像 ZooKeeper 一样使得整个注册中心瘫痪

多种主流注册中心的对比

register-center-vs

Zuul 对比 Spring Cloud Gateway

zuul-gateway

常见问答

什么是服务熔断、服务降级

在复杂的分布式系统中,微服务之间的相互调用,有可能出现各种各样的原因导致服务的阻塞;在高并发场景下,服务的阻塞意味着线程的阻塞,导致当前线程不可用,更严重的会让服务器线程全部阻塞,导致服务器崩溃。由于服务之间的调用关系是同步的,会对整个微服务系统造成服务雪崩。为了解决某个微服务的调用响应时间过长或者不可用进而占用越来越多的系统资源引起的雪崩效应,这就需要进行服务熔断和服务降级处理。服务熔断指的是某个服务出现故障或异常时,起到类似现实世界中的 “保险丝” 的作用,即当某个异常条件被触发就直接熔断整个服务,而不是一直等到此服务超时。简而言之,一旦发生服务雪崩就会熔断整个服务,通过维护一个线程池,当线程达到阈值的时候就启动服务降级,如果其他请求继续访问就直接返回 FallBack 的默认值。

什么是 API 网关

API 网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的 API,以降低管理成本和安全风险。其中包括:

  • 协议适配:当对外提供服务时使用 HTTP 协议、内部服务调用时使用 RPC,此时需要协议适配
  • 协议转发:将外部的 HTTP 请求转换为内部的 RPC 请求
  • 安全策略(WAF):恶意攻击、电商系统或者 O2O 系统的防刷单、Web 爬虫
  • 系统防刷:防刷单、Web 爬虫
  • 流量控制:限流、防 DDOS 攻击
  • 监控日志:API 调用日志