Java面试集锦(一)之SpringCloud

  • 作者: 凯哥Java(公众号:凯哥Java)
  • 面试宝典
  • 时间:2020-08-04 22:04
  • 4533人已阅读
简介 1.什么是微服务以前的模式是所有的代码在同一个工程中部署在同一个服务器中同一个项目的不同模块不同功能互相抢占资源微服务将工程根据不同的业务规则拆分成微服务微服务部署在不同的机器上服务之间进行相互调用Java微服务的框架有dubbo(只能用来做微服务),springcloud(提供了服务的发现,断路器等)微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提

🔔🔔🔔好消息!好消息!🔔🔔🔔

有需要的朋友👉:联系凯哥 微信号 kaigejava2022

1. 什么是微服务

  1. 以前的模式是 所有的代码在同一个工程中 部署在同一个服务器中 同一个项目的不同模块不同功能互相抢占资源

  2. 微服务 将工程根据不同的业务规则拆分成微服务 微服务部署在不同的机器上 服务之间进行相互调用

  3. Java微服务的框架有 dubbo(只能用来做微服务),spring cloud(提供了服务的发现,断路器等)

  4. 微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,

  5. 每一个微服务提供单个业务功能的服务,一个服务做一件事,

  6. 从技术角度看就是一种小而独立的处理过程,类似进程概念,能够自行单独启动或销毁

  7. 拥有自己独立的数据库

2. springcloud如何实现服务的注册和发现

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

3.Ribbon和Feign的区别

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

4.springcloud断路器的作用

当一个服务调用另一个服务由于网络原因或者自身原因出现问题时 调用者就会等待被调用者的响应 当更多的服务请求到这些资源时 导致更多的请求等待 这样就会发生连锁效应(雪崩效应) 断路器就是解决这一问题
断路器有完全打开状态
一定时间内 达到一定的次数无法调用 并且多次检测没有恢复的迹象 断路器完全打开,那么下次请求就不会请求到该服务
半开
短时间内 有恢复迹象 断路器会将部分请求发给该服务 当能正常调用时 断路器关闭
关闭
当服务一直处于正常状态 能正常调用 断路器关闭

5. 微服务之间是如何独立通讯的spring Cloud和 Dubbo有哪些区別?

a4b165b9e9c4152749d69402df6e2fae.png
本质区别:


dubbo 是 基于 RPC 远程 过程调用
cloud 是基于 http rest api 调用

最大区别: Spring Cloudi抛弃了 Dubbo的RPC通信,采用的是基于HTP的REST方式。

严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避兔了上面提到的原生RPC带来的问题。

而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更加合适

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

6.Spring Boot和 Spring Cloud,请你谈谈对他们的理解 什么是服务熔断?

spring boot 是一个快速整合第三方框架 关注的是 微观 具体关注快速方便的开发单个个体的 服务
spring cloud 关注的是 宏观 具体关注全局的微服务协调整理治理框架 将spring boot 开发的一个个单体服务整合 并管理起来
它为各个微服务之间提供 配置管理 服务发现 断路器路由 微代理 全局锁 分布式会话 等 集成服务
举个例子 : 一所医院 boot 是 一个一个科室 cloud 是把一个一个科室 组合起来 对外称之为 医院
存在依赖关系 cloud 离不开boot

7.hystrix 断路器

10da4f2afbe758a3883b90aff75f46f3.png

44f1c47f11a158300bddcfc6f5315ad2.png

服务熔断 是指 由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。

8. 什么是服务降级 微服务的优缺点分別是什么?

用 通俗易懂的来说 : 整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来

4ec4a636d10fa9374892cf33616ee63c.png

da243719a8c25e3a109ea31796f656ac.png

9. 说下你在项目开发中碰到的坑你所知道的微服务技术栈有哪些?

0202de4866ea07a384df2fd67fb9560f.png


微服务技术栈 : 多种技术的结合体

我们在讨论分布式的微服务架构的时候 它需要有哪些维度?

1 服务治理 2 服务注册 3 服务调用 4 负载均衡 5 服务监控

10.请说说eureka和 zookeeper,两个的区別?

首先 说CAP 是什么 所谓的CAP C强一致性 A可用性 P 分区容错性

著名的CAP理论指出,

一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。

zookeeper 遵守 CP

当向注册中心查询服务列表时, 我们可以容忍注册中心返回的是几分钟以前的注册信息, 但不能接受服务直接down掉不可用。

也就是说,服务注册功能对可用性的要求要高于一致性。

但是zookeeper 会出现这样一种情况, 当 master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行 leader选举。

问题在于,选举 leader的时间太长,30~120s,目选举期间整个zookeeper 集群都是不可用的,这就导致在选举期间注册服务瘫痪。

在云部署的环境下,因网络问题使得zookeeper 集群失去 master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

或许 这个回答太过于抽象 用一种其他说法来说 就是 :

当有一个zookeeper 挂了 那其他的zookeeper 会进行 一次选举 (强一致性 : 我一定要保持数据一致性) 而在此选举期间 zookeeper 是不可用的 而当前 有用户正在使用 用户就不爽了 。

eureka 遵守 AP
Eureka:看明白了这一点,因此在设计时就优先保证可用性。
Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。

而 Eureka的客户端在向某个 Eureka注册或时如果发现连接失败,则会自动切换至其它节点

只要有一台 Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的不保证强一致性)。

除此之外, Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么 Eurekas就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务

2. Ureka仍然能够接受新服务的注册和査询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)

3.当网络稳定时,当前实例新的注册信息会被同步到其它节点中

因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情況,而不会像 zookeeper那样使整个注册服务瘫痪。

11.SpringCloud核心组件

1)Spring Cloud核心组件:Eureka(Eureka是微服务架构中的注册中心,专门负责服务的注册与发现)

Eureka Client: 负责将这个服务的信息注册到Eureka Server中
Eureka Server: 注册中心,里面有一个注册表,保存了各个服务所在的机器和端口号

2)Spring Cloud核心组件:Feign( Feign的一个关键机制就是使用了动态代理)

没有底层的建立连接、构造请求、解析响应的代码,直接就是用注解定义一个 FeignClient接口,然后调用那个接口就可以了。人家Feign Client会在底层根据你的注解,跟你指定的服务建立连接、构造请求、发起靕求、获取响应、解析响应,等等。这一系列脏活累活,人家Feign全给你干了。

1.首先,如果你对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理
2.接着你要是调用那个接口,本质就是会调用 Feign创建的动态代理,这是核心中的核心
3.Feign的动态代理会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址
4.最后针对这个地址,发起请求、解析响应

3)Spring Cloud核心组件:Ribbon(它的作用是 负载均衡 ,会帮你在每次请求时选择一台机器,均匀的把请求分发到各个机器上)

Ribbon的负载均衡默认使用的最经典的 Round Robin轮询算法,还有随机算法

此外,Ribbon是和Feign以及Eureka紧密协作,完成工作的,具体如下:

首先Ribbon会从 Eureka Client里获取到对应的服务注册表,也就知道了所有的服务都部署在了哪些机器上,在监听哪些端口号。

然后Ribbon就可以使用默认的Round Robin算法,从中选择一台机器

Feign就会针对这台机器,构造并发起请求。

4)Spring Cloud核心组件:Hystrix( Hystrix是隔离、熔断以及降级的一个框架)

微服务架构中恐怖的服务雪崩问题

这么多服务互相调用,要是不做任何保护的话,某一个服务挂了,就会引起连锁反应,导致别的服务也挂。比如积分服务挂了,会导致订单服务的线程全部卡在请求积分服务这里,没有一个线程可以工作,瞬间导致订单服务也挂了,别人请求订单服务全部会卡住,无法响应。

隔离:Hystrix会搞很多个小小的线程池 ,比如订单服务请求库存服务是一个线程池,请求仓储服务是一个线程池,请求积分服务是一个线程池。每个线程池里的线程就仅仅用于请求那个服务。

熔断:但是如果积分服务都挂了,每次调用都要去卡住几秒钟干啥呢?有意义吗?当然没有! 所以我们直接对积分服务熔断不就得了,比如在5分钟内请求积分服务直接就返回了,不要去走网络请求卡住几秒钟, 这个过程,就是所谓的熔断

降级:没问题,咱们就来个降级:每次调用积分服务,你就在数据库里记录一条消息,说给某某用户增加了多少积分,因为积分服务挂了,导致没增加成功!这样等积分服务恢复了,你可以根据这些记录手工加一下积分。 这个过程,就是所谓的降级

5)Spring Cloud核心组件:Zuul(这个组件是负责网络路由的)

所以一般微服务架构中都必然会设计一个网关在里面,像android、ios、pc前端、微信小程序、H5等等,不用去关心后端有几百个服务,就知道有一个网关,所有请求都往网关走,网关会根据请求中的一些特征,将请求转发给后端的各个服务。

而且有一个网关之后,还有很多好处,比如可以做 统一的降级、限流、认证授权、安全 ,等等。


TopTop