Java 面试-分布式、Spring Cloud

1.什么是 SOA?

    SOA:面向服务的架构,它是一种设计方法,其中包含多个服务,服务之间通过相互依赖最终提供一系列的功能。

    一个服务通常以独立的形式存在与操作系统进程中,各个服务之间可通过网络调用。

2.SOA 和微服务架构有什么区别?
  • 组件大小:SOA 大块业务逻辑,微服务 单独任务或小块业务逻辑;
  • 耦合:SOA 通常松耦合,微服务 总是松耦合;
  • 公司架构:SOA 任何类型,微服务 小型、专注于功能交叉的团队;
  • 管理:SOA 着重中央管理,微服务 着重分散管理;
  • 目标:SOA 确保应用能够交互操作,微服务 执行新功能,快速拓展开发团队;
3.什么是 CAP 原则?

    CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾

  • 一致性(Consistency) :所有节点在同一时间具有相同的数据
  • 可用性(Availability) :保证每个请求不管成功或者失败都有响应
  • 分区容错性(Partition tolerance) :系统中任意信息的丢失或失败不会影响系统的继续运作
4.什么是 BASE 原则?

    BASE 是基本可用(Basically Available)、软状态(Soft State)和最终一致性(Eventually Consistent)三个短语的缩写。

    BASE 理论是对 CAP 中一致性和可用性权衡的结果,它的理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性

5.什么是 RMI?

    RMI,全称:Remote Method Invocation,即“远程方法调用”,是 JDK 1.2 中实现的,它大大增强了 Java 开发分布式应用的能力,RMI 是用来开发纯 Java 分布式应用系统的核心解决方案之一,其实它可以被看作是 RPC 的纯 Java 版本。

6.什么是 RPC?

    RPC,全称:Remote Procedure Call,即:“远程过程调用”,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络通信的规范或协议,可以理解为一台计算机程序远程调用另外一台计算机的子程序,而不用关心底层网络通信。

    一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。

7.RMI 和 RPC 有什么区别?
  • 方法调用方式不同
    RMI 中是通过在客户端的 stub 对象作为远程接口进行远程方法的调用。RPC 中是通过网络服务协议向远程主机发送请求,请求包含一个参数集和一个文本值。
  • 适用语言范围不同
    RMI 只用于 Java;RPC 是网络服务协议,与操作系统和语言无关。
  • 调用结果的返回形式不同
    Java 是面向对象的,所以 RMI 的调用结果可以是对象类型或基本数据类型。
    RPC 的结果统一由外部数据表示(External Data Representation, XFR) 语言表示,这种语言抽象了字节序类和数据类型结构之间的差异。
8.分布式系统下会遇到哪些问题?
  • 分布式锁
  • 分布式唯一 ID
  • 分布式事务
  • 分布式 Session 共享
  • 分布式任务调度
  • 分布式日志收集
9.分布式 Session 共享怎么实现?

    Session 是服务器用来保存用户操作的一系列会话信息,由 Web 容器进行管理。单机情况下,不存在 Session 共享的情况,分布式情况下,如果不进行 Session 共享会出现请求落到不同机器要重复登录的情况,一般来说解决 Session 共享有以下几种方案。

  • session 复制
    session 复制是早期的企业级的使用比较多的一种服务器集群 session 管理机制。应用服务器开启 web 容器的 session 复制功能,在集群中的几台服务器之间同步 session 对象,使得每台服务器都保存所有的 session 信息,这样任何一台宕机都不会导致 session 的数据丢失,服务器使用 session时,直接从本地获取。
    这种方式在应用集群达到数千台的时候,就会出现瓶颈,每台都需要备份 session,出现内存不够用的情况。
  • session 绑定
    利用 hash 算法,比如 nginx 的 pi_hash,使得同一个 IP 的请求分发到同一台服务器上。
    这种方式不符合对系统的高可用请求,因为一旦某台服务器宕机,那么该机器上的 session 也就不复存在了,用户请求切换到其他机器后没有 session,无法完成业务处理。
  • 利用 cookie 记录 session
    session 记录在客户端,每次请求服务器的时候,将 session 放在请求中发送给服务器,服务器处理完请求后再将修改后的 session 响应给客户端。这里的客户端就是 cookie。
    利用 cookie 记录 session 的也有缺点,比如受 cookie 大小的限制,能记录的信息有限;每次请求响应都需要传递 cookie,影响性能,如果用户关闭 cookie,访问就不正常。但是由于 cookie 的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分要记录的 session 信息比较小,因此事实上,许多网站或多或少的在使用 cookie 记录 session。
  • session 服务器
    session 服务器可以解决上面的所有的问题,利用独立部署的 session 服务器(集群)统一管理 session,服务器每次读写 session 时,都访问 session 服务器。
    这种解决方案事实上是应用服务器的状态分离,分为无状态的应用服务器和有状态的 session 服务器,然后针对这两种服务器的不同特性分别设计架构。
    对于有状态的 session 服务器,一种比较简单的方法是利用分布式缓存(memcached),数据库等。在这些产品的基础上进行包装,使其符合 session 的存储和访问要求。
    如果业务场景对 session 管理有比较高的要求,比如利用 session 服务基层单点登录(sso),用户服务器等功能,需要开发专门的 session 服务管理平台。
10.分布式唯一 ID 怎么实现?

    一个 ID 一般来说有下面几种要素:

  • 唯一性:确保生成的 ID 是全网唯一的。
  • 有序递增性:确保生成的 ID 是对于某个用户或者业务是按一定的数字有序递增的。
  • 高可用性:确保任何时候都能正确的生成 ID。
  • 带时间:ID 里面包含时间,一眼扫过去就知道哪天的交易。

    实现方案:

  • 系统时间毫秒数
    缺点是 ID 的有序性难以保证,要保证有序性就要依赖数据库或者其他中间存储媒介。
  • UUID
    缺点是它不包含时间、业务数据可读性差,而且也不能 ID 的有序递增。
  • 数据库自增 ID
    缺点是依赖数据库本身,增加了数据库的访问压力和依赖,对单库进行分库分表或者数据迁移将很难操作。
  • 批量生成 ID
    一次按需批量生成多个 ID,每次生成都需要访问数据库,将数据库修改为最大的 ID 值,并在内存中记录当前值及最大值。这样就避免了每次生成 ID 都要访问数据库并带来压力。
    这种方案服务就是单点了,如果服务重启势必会造成 ID 丢失不连续的情况,而且这种方式也不利于水平扩展。
  • 中间件
    Redis 的所有命令操作都是单线程的,本身提供像 incr 这样的自增命令,所以能保证生成的 ID 肯定是唯一有序的。
    这种方式不依赖关系数据库,而且速度快。但系统要引入 Redis 这一中间件,增加维护成本,而且编码和配置工作量比较大。即使已经有了 Redis 组件,但生成 ID 的高频率访问对单线程的 Redis 性能势必也会造成影响。
11.什么是分布式事务?

    分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
    即事务的每个操作步骤都位于不同的节点上,需要保证事务的 AICD 特性。

12.分布式事务的解决方案有哪些?

    一、两阶段提交(2PC)
    两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。

  1. 运行过程
    • 准备阶段
      协调者询问参与者事务是否执行成功,参与者发回事务执行接口。
    • 提交阶段
      如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则协调者发送通知让参与者回滚事务。
      需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。
  2. 存在的问题
    • 同步阻塞 所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,无法进行其他操作。
    • 单点问题 协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。特别是在阶段二发生故障,所有参与者会一直等待状态,无法完成其他操作。
    • 数据不一致 在阶段二,如果协调者只发送了一部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
    • 太过保守 任意一个节点失败就会导致整个事务失败,没有完善的容错机制。

    二、补偿事务(TCC)
    TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作,它分为三个阶段:

  • Try 阶段主要是对业务系统做检测及资源预留
  • Confirm 阶段主要是对业务系统做确认提交,Try 阶段执行成功并开始执行 Confirm 阶段时,默认 Confirm 阶段是不会出错的。即:只要 Try 成功,Confirm 一定成功。
  • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

    举个例子,假如 Bob 要向 Smith 转账,思路大概是:我们有一个本地方法,里面依次调用

  1. 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
  2. 在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。
  3. 如果第 2 步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解冻方法(Cancel)。

    优点:跟 2PC 比起来,实现以及流程相对简单了一些,但数据的一致性比 2PC 也要差一些。
    缺点:缺点还是比较明显的,在 2,3 步中都有可能失败。TCC 属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用 TCC 不太好定义及处理。

    三、本地消息表(异步确保)
    本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性。

  1. 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
  2. 之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
  3. 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。

    优点:一种非常经典的实现,避免了分布式事务,实现了最终一致性。
    缺点:消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

    三、MQ 事务消息
    有一些第三方的 MQ 是支持事务消息的,比如 RocketMQ,它们支持事务消息的方式也是类似于采用的二阶段提交,但是市面上一些主流的 MQ 都是不支持事务消息的,比如 RabbitMQ 和 Kafka 都不支持。
    以阿里的 RocketMQ 中间件为例,其思路大致为:

  1. 第一阶段 Prepared 消息,会拿到消息的地址。第二阶段执行本地事务,第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。
  2. 也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了 RocketMQ 会定期扫描消息集群中的事务消息,这时候发现了 Prepared 消息,它会向消息发送者确认,所以生产方需要实现一个 check 接口,RocketMQ 会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

    优点:实现了最终一致性,不需要依赖本地数据库事务。
    缺点:实现难度大,主流 MQ 不支持,RocketMQ 事务消息部分代码也未开源。

13.什么是微服务?

    微服务是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行在其独立的自己的环境中,可以单独构建和部署,服务之间互相协调,互相配合,各项服务在工作(和出现故障)时不会相互影响。

    服务之间采用轻量级的通信机制互相沟通,通常是基于 HTTP 的 RESTFUL API。

14.微服务架构有什么优势?
  • 可扩展性
  • 容错性
  • 技术选型灵活
  • 开发运维效率更高
15.微服务架构有什么缺点?
  • 开发人员要处理分布式系统的复杂性
  • 多服务运行难度,随着服务的增加,运维的压力也在增大
  • 系统部署依赖
  • 服务间通信成本
  • 数据一致性
  • 系统集成测试
  • 性能监控
16.什么是服务治理?

    服务治理主要用于对分布式系统中大量微服务进行有效管理。

17.什么是服务降级?

    就是对不怎么重要的服务进行低优先级处理。

    说白了,就是尽可能的把系统资源让给优先级高的服务。资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证网站核心功能服务的可用性,都要对某些服务降级处理。

18.服务降级的方案有哪些?
  • 拒绝服务
    判断应用来源,高峰时段拒绝低优先级应用的服务请求,保证核心应用正常工作。也可以随机拒绝请求,直接返回服务器繁忙,避免同时涌入过多的请求,这在电商秒杀时用的特别多。
  • 关闭服务
    既然是高峰期,那么可以关闭一些冷门的或者边缘不重要的服务,给核心服务让出资源。如淘宝每年双十一时候都会关闭如评价、确认收货等一些与下单核心业务无关的服务,以保证用户下单支付正常,当然肯定也会使用拒绝服务,0 点高峰期很多用户看到的基本是服务器繁忙。
19.什么是服务雪崩?

    多个微服务之间调用的时候,假设微服务 A 调用 微服务 B 和 微服务 C,微服务 B 和 微服务 C 有调用其他的微服务,这就是所谓的“扇出”,如扇出的链路上某个微服务的调用响应时间过长或不可用,对微服务 A 的调用就会占用越来越多的系统资源,进而引起系统雪崩,所谓的“雪崩效应”。

20.什么是服务熔断?

     服务熔断的作用类似于我们家用的保险丝,当某个服务出现不可用或响应超时的情况时,为了防止某个系统出现雪崩,暂时停止对该服务的调用。

    熔断机制是应对服务雪崩效应的一种微服务链路保护机制,扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息,当检测到该节点微服务响应正常后回复调用链路。

21.Spring Cloud 是什么?

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

22.Spring Cloud 和 Spring Boot 的关系?

     Spring Boot 是一套快速配置脚手架 Web 框架,Spring Cloud 是一个基于 Spring Boot 实现的微服务框架。

     Spring Boot 专注于快速、方便集成的单个微服务个体,Spring Cloud 关注全局的服务治理框架。

23.Spring Cloud 和 Dubbo 的区别?
  • 初始定位不同:SpringCloud定位为微服务架构下的一站式解决方案;Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用和治理
  • 生态环境不同:SpringCloud依托于Spring平台,具备更加完善的生态体系;而Dubbo一开始只是做RPC远程调用,生态相对匮乏,现在逐渐丰富起来。
  • 调用方式:SpringCloud是采用Http协议做远程调用,接口一般是Rest风格,比较灵活;Dubbo是采用Dubbo协议,接口一般是Java的Service接口,格式固定。但调用时采用Netty的NIO方式,性能较好。
  • 组件差异比较多,例如SpringCloud注册中心一般用Eureka,而Dubbo用的是Zookeeper
24.Spring Cloud 的核心组件有哪些?
  • Eureka:服务注册于发现。
  • Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。
  • Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。
  • Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。
  • Zuul:网关管理,由 Zuul 网关转发请求给对应的服务。
25.Spring Cloud Eureka 保护机制是什么?

     简单的说,就是在某一时刻,某一个微服务突然不可用了,eureka server不会立刻清理,而是依旧对该微服务的信息进行保存。属于CAP理论的AP分支。

26.Spring Cloud 注册中心有哪些实现方案?
  • Eureka(官方)
  • Nacos
  • Consul
  • CoreDNS
  • Zookeeper
27.Spring Cloud 配置中心有哪些实现方案?
  • Spring Cloud Config(官方)
  • Apollo(携程开源的)
  • Nacos(阿里开源的)
28.Spring Cloud 如何保证微服务调用安全性?
  • 使用 OAUTH2;
  • 使用 JWT(JSON WEB TOKEN)
29.Spring Cloud 中的 Ribbon 是什么?

     Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它是基于 Netflix 的 Riboon 实现的,可以让我们轻松地将面对服务的 REST 模块请求自动转换成客户端负载均衡的服务调用。

30.Spring Cloud 中的 Feign 是什么?

     Feign 是声明式、模板化的 web service 客户端,它让微服务之间的调用变得更简单了,类似 controller 调用 service。

     Spring Cloud 集成了 Ribbon 和 Eureka,可在使用 Feign 时提供负载均衡的 http 客户端,使用 HTTP 请求远程服务,就像调用本地方法一样。

31.Spring Cloud Feign 和 Ribbon 的区别?

     Feign 是在 Ribbon 的基础上进行了一次改进和封装,是一个使用起来更加方便的 HTTP 客户端,实际开发过程中一般推荐使用 Feign,而且采用 Feign 的调用方式更优雅。

32.Spring Cloud 断路器的作用是什么?

    在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

33.dubbo和Feign远程调用的差异

    Feign是SpringCloud中的远程调用方式,基于成熟Http协议,所有接口都采用Rest风格。因此接口规范更统一,而且只要符合规范,实现接口的微服务可以采用任意语言或技术开发。但受限于http协议本身的特点,请求和响应格式臃肿,其通信效率相对会差一些。

    Dubbo框架默认采用Dubbo自定义通信协议,与Http协议一样底层都是TCP通信。但是Dubbo协议自定义了Java数据序列化和反序列化方式、数据传输格式,因此Dubbo在数据传输性能上会比Http协议要好一些。

34.Eureka和Zookeeper注册中心的区别

    SpringCloud和Dubbo都支持多种注册中心,不过目前主流来看SpringCloud用Eureka较多,Dubbo则以Zookeeper为主。两者存在较大的差异:

  • 从集群设计来看:Eureka集群各节点平等,没有主从关系,因此可能出现数据不一致情况;ZK为了满足一致性,必须包含主从关系,一主多从。集群无主时,不对外提供服务
  • CAP原则来看:Eureka满足AP原则,为了保证整个服务可用性,牺牲了集群数据的一致性;而Zookeeper满足CP原则,为了保证各节点数据一致性,牺牲了整个服务的可用性。
  • 服务拉取方式来看:Eureka采用的是服务主动拉取策略,消费者按照固定频率(默认30秒)去Eureka拉取服务并缓存在本地;ZK中的消费者首次启动到ZK订阅自己需要的服务信息,并缓存在本地。然后监听服务列表变化,以后服务变更ZK会推送给消费者。
35.微服务调用关系复杂,如何做监控和错误排查?

    企业中对于微服务监控有一套东西,叫做APM。比如:SpringCloudSeluth+Zipkin,Pinpoint、Skywalking,可以实现性能监控、链路跟踪(精确到某个代码,某条sql)、CPU运行情况,链路运行耗时。

    当然, 还可以借助于分布式日志管理系统。把项目运行的日志收集,形成统计报表,放入elasticsearch,便于搜索查看。比如:ELK技术栈、GrayLog

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值