当前位置:   article > 正文

找工作再也不愁之面试题全覆盖-微服务篇

找工作再也不愁之面试题全覆盖-微服务篇

Config:分布式配置中心,用来统一管理配置所有微服务的配置文件,

Bus:消息总线,用来给各个微服务广播消息,可以实现各个微服务配置的自动刷新,

Sleuth:链路追踪,用来实时监控各个微服务建的调用关系,快速定位故障节点

Spring Cloud的优缺点?

微服务相对单体应用来说

优点

  • 服务之间无耦合,代码简单方便开发维护,服务之间升级维护互不影响

  • 轻量级HTTP通信机制,不同的服务可以采用不同的编程语言

  • 有极强的扩展能力,业务量大的服务可以再次拆分服务,或者也可以集群部署

  • 支持时下流行的敏捷开发并做了优化

缺点

  • 分布式事务繁琐

  • 部署麻烦,开发人员的学习成本高

  • 技术成本高,开发人员需要花更多的时间学习相关技术

  • 微服务间的通信存在对性能的损耗问题

什么是服务注册

Eureka是一个服务组测与发现的组件,翻译成人话就是管理所有微服务的通讯录的组件。它包含注册中心,客户端两部分组成。客户端在启动的时候会向注册中心发送一条自我介绍信息,比如端口,ip等等,在注册中心就会保存一张所有微服务的通讯录。这就叫服务注册

什么是服务发现

微服务会定期的从客户端拉取一份微服务通讯录,到本地缓存起来,默认是30s一次。当一个微服务向另一个微服务发起调用,直接根据本地的通讯录找到对方的服务名,发送HTTP请求。这个就叫服务发现

什么是服务续约

微服务会定时(默认30s)发送心跳请求,告诉注册中心,自己还处于存活状态,那么服务中心就不会将其从清单中删除,否则,当微服务宕机或者网络故障等因素,没有在规定时间(默认90s)内提交心跳请求,注册中心就会将它从通讯录中删除。

如果服务挂了,注册中心要等到90s后剔除,那么在剔除前的这段时间内,挂掉的服务有可能还是会被调用,怎么处理?

第一,可以修改注册中心剔除服务时间,同时加快服务续约心跳请求的频率

第二,可以使用Hystrix的熔断降级机制,当某个服务不可访问,快速失败,并返回托底数据

第三。重试,提供者集群

你知道EurekaClient服务发现和服务续约每隔30s做一次请求是用什么技术实现的吗?

使用了ScheduledThreadPoolExecutor线程池定时任务来实现

服务发现是先判断是否开启了服务发现功能(默认是开启的),获取定时任务的间隔时间(默认是30s),然后初始化服务发现的定时任务,间隔时间可以在yml中修改

服务续约是先判断是否开启服务注册功能(默认是开启的),获取定时任务间隔时间(默认是30s),然后初始化心跳请求的定时任务,间隔时间可以在yml中修改

Ribbon是什么,Ribbon的工作原理讲一下

Ribbon是一个客户端负债均衡器,它可以按照负债均衡算法,向多个服务发起调用。当一个微服务有多个集群时,就可以使用它做请求负载均衡,通常结合RestTemplate来使用

说一下 Ribbon的工作原理

消费者会30/次注册中心拉取服务注册清单缓存到本地,当消费者需要调用一组提供者集群服务时,Ribbon会根据提供者服务名,在本地缓存的服务地址清单里找到这一组服务的通讯地址,然后按照负债均衡算法(默认是轮询),选择其中的一个通讯地址,发起http调用服务。

Ribobn内部通过LoadBalancerInterceptor拦截RestTemplate发起的请求,然后交给RibbonLoadBalancerClient负载均衡客户端做负载均衡,RibbonLoadBalancerClient把选择服务的工作交给ILoadBalancer负载均衡器 ,ILoadBalancer会调用 IRule负载均衡算法类来选择服务。之后RibbonLoadBalancerClient把选择好的服务交给LoadBalancerRequest去发请求。

Ribbon有哪些负载均衡算法,怎么配置

RoundRobinRule:简单轮询,ribbon默认规则

AvailabilityFilteringRule:忽略短路状态和并发过高的服务器

WeightedResponseTimeRule:根据服务器响应时间作为权重,响应时间越长权重越小

ZoneAvoidanceRule:根据区域选择

BestAvailableRule:忽略短路的服务器,选择并发较低的服务器

RandomRule:随机选择一个可用服务器

Retry:重试机制的选择逻辑

OpenFeign和Ribbon的区别

OpenFeign整合了Ribbon和Hystrix,屏蔽了Ribbon拼接URL,参数的细节,使用声明式编程,让服务调用变得更加简单,OpenFiegn底层也是走的Ribbon的负载均衡策略。推荐使用OpenFeign

OpengFiegn的工作流程

首先,当程序启动时,@EnableFeignClient会扫描@FeignClient注解的接口,并交给Spring容器管理。

当发起请求时,会使用jdk动态代理,并为每个方法都生成相应的RequestTemplate,同时封装http信息,包括url和请求参数等,

最后把RestTemplate交个HttpClient发送请求,使用ribbon的负载均衡发起调用

为什么要使用Eureka 为什么要使用Ribbon 为什么要使用config配置中心

在微服务系统中,各个服务之间是需要进行网络通信的,那么他们相互调用就得知道对方的通信地址。eureka就是专门来做做服务注册与发现,解决服务之间通信问题的

当一个微服务做了集群,也就是同一个服务名会对应多个地址,那么我们在调用的时候,应该调用哪一个就成了问题,Ribbon是一个负债均衡器,它可以按照负债均衡算法,向多个服务发起调用。当一个微服务有多个集群时,就可以使用它做请求的分发

在微服务系统中,服务数量很多,而每个服务都有自己的配置文件,管理起来很麻烦。用了配置中心就可以帮我们集中管理配置文件,它支持本地配置文件,也支持将配置文件放到远程仓库如git集中管理

为什么Feign的客户端接口没有写实现类也可以直接被依赖注入

自动注入的实例其实是一个jdk动态代理对象,Feign会为每个方法生成相应的requestTemplate,它根据服务名找到对应的服务,根据返回值类型、形参列表匹配相应的接口,然后封装url、请求参数,最后生成request请求,使用Ribbon负载均衡发起调用

介绍一下Hystrix

Hystrix意为熔断器,它可以将出现故障的服务,通过熔断、降级等手段隔离开,这样不影响整个系统的主业务。它可以防止由单节点异常导致整个微服务故障,如果遇到故障时,快速失败,熔断的同时可以返回兜底数据达到服务降级的目的

什么是熔断,什么是降级

熔断,是对服务链路的一种保护机制,当链路上的某个服务不可访问时,服务就会触发降级返回拖地数据,同时当失败率到达一个阈值,就标记该服务为短路状态,当请求访问时直接熔断。直到检查到该服务能正常访问时,就快速恢复

降级,是当某个服务不可访问时,我们返回一些事先准备好的数据给客户端,比如说,友情提示服务暂不可用,请骚后重试,这样用户体验就上去了

什么是资源隔离?

指的是限制某一个分布式服务的资源使用,可以理解为限流,也就是限制某个服务的请求数量。它包括线程池隔离和信号量隔离

线程池隔离,是指用一个线程池来存储当前请求,可以通过设置线程池最大线程数和最大排队队列数来限制请求数量

信号量隔离:是指用一个计数器来记录当前有多少个线程在运行,请求进来计数器就增加1,超过最大信号量,就直接返回

资源隔离:信号量和线程池的区别

线程池方式是异步处理,它与调用线程不是同一个线程

信号量方式是同步处理,与调用线程是同一个线程

线程池方式由于需要排队,调度,线程切换,因此开销较大,信号量方式无需切换线程,开销较小

对于CAP理论,Eureka选择的是AP还是CP?它保证了一致性还是可用性?

CAP理论指的是,一个分布式系统中,一致性,可用性,分区容错性,三个要素只能同时实现两点。Eureka选择的是AP,它是弱一致性的,保证了可用性和分区容错性,放弃了数据一致性。也就是说当多个Eureka之间不可通信时,需要保证服务可用,正常提供服务注册发现功能,但是网络恢复后最终还是会同步的。

说一下Eureka的自我保护

为了防止服务被误删除,Eureka不会立即删除过时的服务数据。这种机制可能会导致客户端从注册中心获取到已经下线的服务并发起调用而导致错误,因此在开发阶段我们可以关闭自我保护机制。在生产环境中,我们需要打开自我保护,因为它可以防止因为网络波动,服务没有及时续约而造成的服务误删除问题。

你们项目是如何做服务降级的?

比如在秒杀业务中,需要实时从redis中查询库存,通过设置hystrix的最大信号量,以此来防止redis雪崩。当并发过高,请求数超过最大信号量,触发降级,直接向客户端返回兜底数据:”活动太火爆啦,请骚后重试“

Zuul有哪几类Filter,他们的执行顺序是怎么样的?

zuul按照执行顺序,分为pre前置过滤,route路由过滤,post后置过滤,error异常后过滤

正常流程是请求先经过前置过滤器,到达路由过滤器进行路由,路由到各种微服务执行请求,返回结果后经过后置过滤,返回用户

异常流程,如果再整个过程中出现异常,都会进入error异常过滤器,处理完毕后经过post过滤器返回用户,如果error自己出现异常,最终也会通过post过滤器返回用户,如果post过滤器出现异常,也会跳转到error过滤器,然后直接返回用户

在Zuul中做登录检查如何实现?

可以通过继承ZuulFilter抽象类,自定义pre类型的过滤器,shouldFilter方法中可以定义需要放行的资源,run方法中检查请求头中的token信息,如果没有token,就响应到客户端未登录的信息,并组织filter继续往后执行

在Zuul中如何做限流?

方式一:可以通过继承ZuulFilter抽象类自定义pre过滤器,加上限流算法,来实现

方式二:可以通过hystrix的资源隔离模式,设置线程池最大连接数或者最大信号量来实现

方式三:常用,Ratelimit,使用令牌桶算法。。。

配置中心解决什么问题?

在分布式系统中,服务数量很多,而每个服务都有自己的配置文件,管理起来很麻烦。配置中心是个好东西,可以帮我们集中管理配置文件,它支持本地配置文件,也支持将配置文件放到远程仓库如git集中管理。

EureakServer的搭建流程

第一步,导入eureka-server依赖,以及springboot的web环境依赖。

第二布,主启动类上打注解,@EnableEurekaServer,开启eureka服务端功能

第三步,yml配置文件中,配置注册中心的端口号,主机名,注册中心地址

Ribbon的整合流程

第一步,导入ribbon依赖

第二部,给RestTemplate的Bean定义方法上,加上注解@LoadBalanced,让这个restTemplate有负载均衡的功能

第三步,修改restTemplate调用服务的url,将目标主机名换成目标服务名

Feign的整合流程

第一步,导入openfeign依赖

第二部,主配置类加注解,@EnableFeignClients,开启feign支持

第三步,定义feign客户端接口,并加上注释@FeignClient(“目标服务名”),接口中定义方法,该方法与目标服务的对应方法的方法名,返回值类型,形参列表,url路径要一致

Hystrix的整合流程
  • 第一步,导入hystrix依赖

  • 第二部,主启动类加注解,@EnableCircuitBreaker,开启熔断功能

  • 第三步,在需要开启熔断功能的方法上,加注解@HystrixCommand(fallbackMethod=“xxx”),xxx是降级方法

  • 第四步,定义降级方法,方法名需要和fallbackMethod的值一致,形参列表和返回值类型需要和目标方法一致

feign整合Hystrix:

  • 第一步,yml中配置,feign.hystrix.enable=true,开启hystrix功能

  • 第二部,@FeignClient标签中,定义fallback或者fallbackFactory,指定降级类

  • 第三步,

如果是fallback,就实现feign接口,并覆写接口中的方法作为降级方法

如果是fallbackFactory,就实现FallbackFactory接口,同时指定泛型为feign接口,覆写create方法,返回一个feign接口的匿名内部类,类中写降级方法

Zuul的整合流程

第一步,导入zuul依赖

第二步,主启动类上加注解@EnableZuulProxy,开启zuul功能

第三步,yml中配置,统一访问前缀prefix,禁用通过服务名方式访问服务ignoredServices,配置路由routes指定某个服务使用某个路径来访问

ConfigServer的整合流程

配置中心服务端配置:

​ 第一步,导入config-server依赖

​ 第二步,主启动类加注解,@EnableConfigServer,开启配置中心

​ 第三步,配置文件中,配置远程仓库地址,仓库账号密码

客户端配置:

​ 第一步,导入config-client依赖

​ 第二步,创建bootstrap.yml配置文件,配置中心地址config.uri,要拉取的配置文件名name,环境名profile

你们微服务项目的技术栈描述一下

​ 前端门户系统:HTML + JQuery + CSS

​ 前端管理系统:VUE + ElementUI

​ 后端系统:基于SpringCloud微服务框架(Eureka+OpenFeign+Hystrix+Zuul+Config)

+MyBatisPlus+SpringMVC+Redis+ElasticSearch+RabbitMQ+AlicloudOSS

浏览器发起一个请求,在你的微服务项目中的怎么去执行的?

浏览器发起的所有请求首先通过Nginx,通过负载均衡算法,路由给zuul集群,然后通过zuul前置过滤,作登录校验后,它会从配置中心拉取的通讯地址中,根据url匹配到对应的服务,然后使用ribbon发起restful调用。微服务间也可以通过feign相互调用,最终执行完任务,返回浏览器

说下Ribbon和Feign的区别呢

Ribbon和Feign都是SpringCloud Netflix中实现负载均衡的组件,不同点在于

Ribbon是需要我们手动构建http请求,根据目标服务名通过负载均衡算法直接调用目标服务,

Feign是采用接口的方式,将需要调用的目标服务方法定义成抽象方法,路径,服务名,形参列表,返回值类型需要保持一致。我们只需要调用接口中的方法就可以了。它会自动帮我们生成jdk动态代理,为每个方法生成RequestTemplate并封装url和请求参数,使用负载均衡算法发起调用

Ribbon的实现方式,一般配合RestTemplate发起http请求,我们需要在注册RestTemplate的Bean的方法上加@LoadBalanced,使它具有负载均衡的能力

Feign的实现方式,是在主启动类上加@EnableFeignClients,在客户端接口上加注解@FeignClient

Spring,SpringBoot和SpringCloud的关系以及区别

Spring是一个开源的轻量级控制反转和面向切面编程的容器框架。轻量级是说它开发使用简单,功能强大。控制反转是指将对象的创建,销毁控制交给ioc容器,方便解耦合,降低维护难度,面向切面编程是指将相同的逻辑横向抽取出来,可以对一些通用业务如事务,日志进行集中管理。

Springboot是一个基于spring的框架,对spring做了大量简化,使开发流程更快,更高效。比如它大量简化maven依赖,基于注解配置(JavaConfig)无需XML,内嵌Tomcat,部署流程简单,打包和部署更加灵活,允许独立运行

SpringCloud是基于SpringBoot实现的,用于微服务架构中管理和协调服务的,它是一系列框架的有序集合,它为开发者提供了一系列工具,例如服务发现与注册,配置中心,网关,负载均衡,熔断器,链路追踪等等,让微服务架构落地变得更简单

分布式事务

什么是分布式事务,

分布式事务,指的是在分布式环境中,一个请求可能涉及到对多个数据库的写操作,要保证多数据库的一致性就需要用到分布式事务

分布式事务你知道哪些解决方案? 这些方案如何选型

常见的分布式事务解决方案,2PC,TCC,可靠消息最终一致性,最大努力通知

2PC,它将整个事务流程分为两个阶段,P指的是准备阶段,C指的是提交阶段。它是一个阻塞协议,不适用于并发较高,事务生命周期长的分布式事务。

TCC,它是基于补偿性事务的AP系统的一种实现,补偿也就是说先按照预定方案执行,如果失败了就走补偿方案。它可以自己定义数据操作的粒度,但是对应用的侵入性强,可以用在登录送积分,送优惠券等等场景

可靠消息最终一致性,指的是当事务发起方执行完本地事务后,就发出一条消息通知其他参与方,并且他们一定能接收到消息并处理事务。适合执行周期长,并且实时性要求不高的场景

最大努力通知,是在不影响主业务的情况下,尽可能的保证数据的一致性,它适用于一些最终一致性敏感度低的业务,比如支付结果通知

什么是2pc

2PC,是将整个事务流程分为两个阶段,P指的是准备阶段,C指的是提交阶段。它常见的标准有XA,JTA,Seata

由DTP模型定义事务管理器TM和资源管理器RM之间通讯的接口规范叫做XA,它规定的交互方式是酱紫的:应用程序AP通过TM提交和回滚事务,TM通过XA接口来通知RM数据库事务的开始,结束,提交,回滚

2PC能保证分布式事务的原子性,但是也有很多缺陷

比如,在第一阶段,如果参与者迟迟不回复协调者,就会造成事务的阻塞,性能不好

比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,一部分参与者收到消息提交了事务,另一部分没有收到消息没有提交事务,这就会导致数据不一致

再比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,收到指令的参与者也宕机了,我们就不能确定事务的执行结果,究竟有没有提交

Seata相比传统2PC有什么区别,以及优点?

感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"

子性,但是也有很多缺陷

比如,在第一阶段,如果参与者迟迟不回复协调者,就会造成事务的阻塞,性能不好

比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,一部分参与者收到消息提交了事务,另一部分没有收到消息没有提交事务,这就会导致数据不一致

再比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,收到指令的参与者也宕机了,我们就不能确定事务的执行结果,究竟有没有提交

Seata相比传统2PC有什么区别,以及优点?

感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

[外链图片转存中…(img-LO3dejod-1714712762711)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/795800
推荐阅读
相关标签
  

闽ICP备14008679号