阿里面试官问我SpringCloud,附答案

每日一句: To always face my adversity head on.面试

下面整理了一些面试的过程当中被问到的Spring相关的题目,只因简历上写了熟练使用SpringBoot,SpringCloud。但愿为即将准备面试的胖友提供一些帮助,平时仍是要多关注一些细节的地方!redis

SpringBoot的优点是什么? 自动配置/依赖的原理是什么?

SpringBoot能够快速一键搭建一个基于Spring的生产就绪的应用框架,简化Spring应用的初始搭建以及开发过程:算法

  • 最大的优点在于简化配置和简化编码方面,简化了以前开发Spring应用繁琐的配置,它内部集成了经常使用的第三方库配置,SpringBoot中这些第三方库几乎能够零配置的开箱即用,大部分SpringBoot应用都只须要很是少许的配置代码和极简的maven pom 文件的配置,使得开发者能够更专一于业务逻辑的开发。
  • 简化部署,SpringBoot内置了Tomcat, 咱们只须要把项目打成jar包就能够一键启动
  • 简化监控,咱们能够直接使用spring-boot-start-actuator对服务进行运行期性能和健康的监控

自动配置原理

SpringBoot自动配置自带了不少了配置类,自动配置创建在spring条件化配置基础之上的:spring

  1. 首先SpringBoot的主配置类上的@SpringBootApplication 开启了自动配置功能@EnableAutoConfiguration后端

  2. @EnableAutoConfiguration 利用AutoConfigurationImportSelector将META-INF/spring.factories里面配置的全部xxxAutoConfiguration的配置类都加入容器中,用他们来作自动配置。spring-boot-autoconfiguration的jar 文件里面包含了不少的配置类,好比jpa, mvc,redis,neo4j。用户能够本身选择是否在程序里面使用他们,这些配置类构成了Springboot的自动配置。缓存

    尽管这些配置存在与应用程序的ClassPath中,可是在知足某些条件以前应用会忽略这个配置,好比:安全

    Spring启动的时候会作几百次这样的检查,好比检查Jdbctemplate是否是在Classpath里面,若是是就会配置一个对应的jdbcTemplate的配置Bean。 全部的这些配置都是尽可能的不让开发者本身去写配置。网络

SpringCloud里你还对哪些组件比较熟悉?

服务注册中心Eureka

服务提供者向服务注册中心进行服务的注册,并周期性的发送心跳来更新服务信息,服务消费者拉取服务注册中心的服务列表并维护在本地,并从服务列表中拉取一个服务进行消费。架构

Eureka自己支持高可用,能够经过集群的方式部署,Eureka Server之间也能够相互注册,相互同步服务信息。并发

  • 失效服务的剔除: 好比超过30s没有心跳的服务,就会被Eureka标记为不可用

  • 自我保护机制:

    ​ 当Eureka 与其它服务之间的心跳大面积失败的时候,它会认为多是本身的问题,好比本身网络很差,就会把注册的信息保护起来。这时若是有消费者来访问,可能就会拿到真正过时的服务的状况。

Ribbon负载均衡器

  • Ribbon 是一个基于HTTP的客户端负载均衡器,能够在客户端负载均衡访问服务提供者列表提供的服务
  • Ribbon 提供了一系列完善的配置项如链接超时,重试等,Ribbon会自动的某种算法去链接机器

Fegin

  • 微服务之间声明式的调用,整合了Ribbon和Eureka,关键机制是使用了动态代理,让用户不用本身去写HTTP请求,让客户端以为调用本地接口就像调用其它服务同样。
    • 首先,对于某个接口定义了@FeginClient 注解,Fegin就会针对这个接口建立一个动态代理
    • 接着,调用接口的时候,本质上是调用Fegin建立的动态代理
    • Fegin 会根据接口上的@RequestMapping等注解,来动态构造要请求的服务的地址
    • 针对这个地址,发起请求,解析响应

Zuul

Zuul的原理: 经过一个统一的Servlet入口ZuulServlet拦截全部的请求,而后经过ZuulFilter链对请求作拦截和过滤处理。Zuul大部分功能都是经过过滤器来实现的,Zuul中定义了4种标准的过滤器,这些过滤器对应于请求的典型生命周期:

  1. PRE: 请求路由到某个服务以前调用,能够实现身份验证等

  2. ROUTING: 用于构建发送给微服务的请求,并经过HttpClient 或 Ribbon 请求微服务

  3. POST: 在请求路由到微服务之后执行,能够为响应结果添加Http Header, 将结果发送给客户端

  4. ERROR: 在其它阶段发生错误的时候执行该过滤器

  • 客户端只须要请求Zuul网关就能够了,无须要调用特定微服务,由Zuul网关负责转发请求,这样开发就能够获得简化,易于作监控,易于安全认证(好比不须要再每个微服务上都进行认证)负载均衡等。

Config

微服务数量比较多的时候,配置管理就比较复杂了,SpringCloud Config经过分布式配置中心来统一管理配置文件并能够实时更新。Config Server用于配置属性的存储,Config Client用于服务属性的读取。

Bus

当配置文件须要动态更新的时候,能够经过Bus在不关闭服务的状况下更新咱们的配置。

Hystrix 熔断限流降级

  • 防止因服务提供者的不可用致使服务调用者的不可用,并将不可用逐渐放大雪崩的过程。

Hystrix熔断过程讲一下? Hystrix实现原理讲一下? 线程池和信号量熔断区别?

  • 熔断过程:当用户请求量大或者缓存击穿,会照成后端服务提供者的瞬间超负荷容许,引发服务不可用,当Hystrix检查到超时或者出现异常的时候,就会执行fallback方法而不是让client一直等待或重试。
  • 服务降级过程: 当服务压力剧增时,能够根据流量状况对一些服务的页面作降级,好比返回一个默认值或者返回一个提示,让用户稍后重试之类。若是目标服务状况好转则恢复正常调用。

Hystrix的实现能够基于线程池或信号量的方式:

  • 基于线程池: 在服务和请求之间增长了一个线程池,用户的请求将再也不直接访问服务,而是先通过熔断器,而后经过线程池中空闲线程来访问服务,若是这个时候熔断器是打开的,说明已经熔断了,直接进行降级处理。 当线程池饱和而且请求队列阻塞的时候,能够提早拒绝服务。
  • 基于信号量:当请求进入熔断器时,会有一个计数的信号量,每来一个请求数,计数器加1,结果大于最大请求的时候,就返回false,发生信号量拒绝事件,执行降级逻辑。当请求离开熔断器时,执行release(),计数器减1。信号量模式下,接收请求和执行下游依赖在同一个线程内完成,不存在线程上下文切换带来的性能开销。

线程池和信号量熔断区别?

  • 资源消耗方面,信号量只是个计数器,资源消耗小,若是有数百个服务实例,线程池作隔离的开销过大,会有上下文的切换开销
  • 信号量的调用时同步的,每次调用都会阻塞调用方的线程直到结果返回,不支持异步,不支持超时,线程池支持超时返回
  • 信号量是达到最大请求量阈值时熔断,线程池时达到最大线程数熔断

Hystrix/Feign/Ribbon之间如何配合的, 代码上架构是怎样的?

Fegin 经过代理模式自动将全部的方法用Hystrix进行了包装,目的是在调用方实施针对被调用微服务的熔断逻辑,针对被调用服务设置超时时间,一旦超时就会进入熔断逻辑,而这个故障指标信息也会返回给Hystrix组件,hystrix根据故障信息打开断路器,以后全部针对该微服务的请求都会直接进入熔断逻辑,直到故障恢复关闭断路器为止。

  • 首先Ribbon从Eureka Client 里面获取对应的服务注册表,好比服务的ip 和 端口
  • 而后Ribbon使用默认的的Round Robin算法,从中选择一台机器
  • Fegin就会针对这台机器,构造代理并发起http请求

总结

SpringCloud SpringBoot 这套技术栈,你们平时本身使用的过程,可能以为比较简单,不过了解其底层实现细节,对咱们写出高性能的服务架构确定大有裨益。好比在了解原理后,咱们知道Hystrix在有大量的请求时,若是默认使用线程池可能会频繁的线程切换,更加剧系统性能,这时候能够考虑切换了。

最后欢迎你们关注“开发运维技术圈”公众号,群里有阿里云,蚂蚁,口碑,字节的同窗,也有各类岗位内推哦!

相关文章
相关标签/搜索