spring cloud面试题
什么是 Spring Cloud?
Spring Cloud是一个微服务框架,它提供了全套的分布式系统解决方案。
使用 Spring Cloud 有什么优势
将单体服务拆分所带来的问题:
- 服务实例太多怎么办
- 服务调用关系太杂乱怎么办
- 服务访问出错了怎么办
- 配置信息散落在各个服务中怎么办
- 服务调用链路太长怎么办
等等会带来一系列的问题。
使用spring cloud提供的一些组件。
*微服务* | *Spring Cloud与Netflix OSS* |
---|---|
配置管理 | Spring Config Server |
服务发现 | Spring Cloud Netflix Eureka |
负载平衡 | Spring Cloud Netflix Ribbon |
API网关 | Spring Cloud Zuul |
API网关 | Spring Cloud Gateway |
安全问题 | Spring Cloud Security |
集中化日志记录 | 自建ELK |
集中的度量 | Spring Spectator & Atlas |
分布式跟踪 | Spring Cloud Sleuth、zipkin |
弹性和容错性 | Netflix Hystrix, Netflix Turbine, & Netflix Ribbon |
自动伸缩和自我修复 | - |
打包、部署和调度。 | Apache Maven. Spring Cloud没有真正的调度程序。 |
作业管理 | Spring Batch |
单例应用程序。 | Spring Cloud Cluster |
服务监控(会给我们提供一个可视化界面) | Spring Cloud Admin |
服务注册和发现是什么意思?Spring Cloud 如何实现?
服务注册:它指的是将服务实例的信息注册到服务注册中心。实例的信息一般包括ip地址、端口号、注册时间等信息。
服务发现:通过服务注册中心来查询和发现可用的服务实例。一般是获取可用目标服务的IP地址、端口号等信息列表,通过负载均衡的方式进行服务的调用。
spring cloud通过eureka来实现服务注册和发现。Eureka 服务注册和发现可以在这种情况下提供帮助。由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找。
eureka底层保存注册信息使用的是concurrenthashmap来做的。
spring cloud怎样实现负载均衡?
我们可以使用spring cloud提供的ribbon组件来实现负载均衡。
什么是 Hystrix?它如何实现容错?
Hystrix是Netflix开源的一个库,用于在分布式系统中实现容错性。它主要用于处理分布式系统中的服务间依赖关系,以确保系统在面对依赖故障或高负载时能够继续提供有限的功能而不完全崩溃。Hystrix通过提供以下功能来实现容错:
1.降级(Fallback)
当一个依赖的服务发生故障或超时时,Hystrix可以提供一个备用的、降级的响应,而不是返回错误或抛出异常或者让客户端一直在那里等待。这有助于保持系统的一部分功能继续可用,而不会因依赖服务的问题而受到影响。说白了就是在对应的业务方法上添加相应的注解,并指定fallback方法在出现问题的时候进行回调。
2.熔断(Circuit Breaker)
Hystrix引入了熔断器的概念,类似于电路中的熔断器。如果某个依赖的故障率超过了一定的阈值,Hystrix会打开熔断器,暂时阻止对该依赖的请求,以减轻负载和避免连锁故障。在一段时间后,熔断器会尝试半开状态,允许一部分请求通过,如果成功,就继续关闭熔断器,否则保持打开。
3.资源隔离(Thread Pooling and Request Batching)
Hystrix允许为不同的依赖服务配置独立的线程池,以确保某个依赖服务的问题不会影响到整个系统的线程资源。此外,Hystrix还支持请求批处理,可以将多个请求合并为一个,减少对依赖服务的负载。
4.实时监控和度量
Hystrix提供了实时监控和度量功能,可以通过仪表盘查看依赖服务的性能指标,如请求成功率、失败率、响应时间等。这有助于运维人员及时发现和解决问题。
5.自动恢复
一旦依赖服务的故障率降低到可接受水平,Hystrix会自动恢复对该服务的正常请求处理,不再触发熔断机制。
6.超时处理
Hystrix可以配置每个依赖服务的超时时间,如果请求超时,它会被视为失败,并根据熔断策略进行处理。
总的来说,Hystrix通过熔断、降级、资源隔离等策略,以及实时监控和度量来实现容错。它允许开发者在分布式系统中更好地处理依赖服务的故障,提高系统的可用性和稳定性。然而,需要注意的是,Hystrix在Netflix的官方GitHub仓库中已经宣布停止维护,推荐使用更先进的容错和断路器库,如Resilience4j或Sentinel。
@GetMapping("/user/test")
@HystrixCommand(fallbackMethod = "fallback2")
public String test(@RequestParam ("number")Integer number) {
if (number == 1) {
return "success";
}
RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject("http://127.0.0.1:8081/rw/user/test", String.class);
return str;
}
private String fallback2(Integer number) {
return "太拥挤了,请稍后再试2";
}
说白了就是我们需要在某个调用下游系统的方法上面加上@HystrixCommand(fallbackMethod = "fallback2")注解,并且自定义回调方法就可以了。
什么是 Hystrix 断路器?我们需要它吗?
和上面的回答保持一致就可以了。
什么是 Netflix Feign?它的优点是什么?
feign是一个微服务,需要单独的开发。
@FeignClient(name = "microservice-provider-user") // 这个是我么需要调用的微服务的名称
@RequestMapping(value = "/user")
public interface UserFeignClient {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
User findById(@PathVariable("id") Long id);
}
这个是服务调用者:
@RestController
@RequestMapping("movie")
public class MovieController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
}
}
也就是说想使用feign进行调用的话,服务消费者和服务提供者都需要引入自己开发的feign的微服务模块,才能够进行远程调用。
Feign是Netflix开发的一个基于注解的轻量级HTTP客户端,它使得编写服务间的HTTP通信变得更加简单和优雅。
Netflix Feign具有以下几个优势:
声明式API:Feign允许开发人员通过接口和注解定义服务间的API调用。通过简单的接口定义,Feign可以自动生成调用目标服务的HTTP请求,使得服务间的通信定义更加清晰和易于理解。
集成负载均衡:Feign内部集成了Ribbon负载均衡器,可以通过配置和注解实现对多个服务提供实例的负载均衡。开发人员不需要手动处理服务实例的选择,Feign会自动根据负载均衡策略选择并调用合适的服务实例。
整合容错处理:Feign还集成了Hystrix容错处理框架,可以通过注解和配置实现服务调用的容错机制。当目标服务发生故障或响应超时时,Feign可以根据配置进行熔断、降级或重试等操作,提高了系统的可靠性和稳定性。
简化HTTP通信:Feign封装了底层的HTTP通信细节,开发人员只需要关注业务逻辑,无需手动处理HTTP请求和响应。Feign提供了丰富的注解,使得开发人员可以方便地定义请求的URL、方法、参数、Header等信息,大大简化了HTTP通信的编写和管理。
可扩展性:Feign提供了扩展点,开发人员可以通过自定义注解、解码器、编码器等来扩展和定制Feign的功能。这使得Feign可以适应各种业务场景和需求,提供更灵活和定制化的解决方案。
综上所述,Netflix Feign的优势在于简化了服务间的HTTP通信,提供了声明式API和集成了负载均衡和容错处理,可以大大简化和优化服务调用的编写和管理。
什么是 Spring Cloud Bus?我们需要它吗?
我们将微服务中的配置文件集中存储在远程Git仓库,并且通过配置中心微服务从Git仓库拉取配置文件,当用户微服务启动时会连接配置中心获取配置信息从而启动用户微服务。
如果我们更新Git仓库中的配置文件,那用户微服务是否可以及时接收到新的配置信息并更新呢?答案是不会。
Spring Cloud Bus 是 Spring Cloud 中一个用于服务之间通信的组件。它基于消息中间件实现,可以实现配置的动态刷新和事件的广播通知,提高配置的实时性和可靠性。
因为要想要服务的调用实时知道你的配置信息发生变化,说白了,你还是需要手动执行命令去获取git仓库中的配置的。使用命令:curl -X POST http://localhost:8080/actuator/bus-refresh。存在安全性问题,所以在实际生产环境中使用的比较少。
Spring Cloud Ribbon是什么?
是spring cloud Netflix的组件。用于实现分布式系统中的客户端负载均衡和服务调用。
案例演示:https://blog.csdn.net/weixin_50616848/article/details/124537583
feign是什么?
是spring cloud Netflix的组件。用于实现分布式系统中的客户端负载均衡和服务调用。
feign和ribbon的联系和区别?
功能不同:Ribbon主要提供了客户端负载均衡的功能,可以在多个服务提供者之间分发请求。Feign则是在Ribbon的基础上提供了一个更高级的抽象层,简化了服务间的调用方式,使得调用方式更加像本地方法调用。
使用方式不同:Ribbon需要手动编写代码来实现负载均衡的功能,需要实现负载均衡器和服务列表的管理。而Feign则是基于注解和接口定义的方式,可以自动根据接口定义生成客户端代码,并且已经集成了Ribbon的负载均衡功能,使用起来更加方便。
可扩展性不同:Ribbon提供了丰富的可定制化选项,可以根据实际情况自定义负载均衡策略、重试机制等。而Feign则相对简单,提供了较少的可扩展性选项,如果需要更高级的功能,则需要自己编写代码实现。
综上所述,Ribbon适合对负载均衡和服务调用有更深入理解的开发者,可以自己编写代码实现需要的功能。而Feign则更加适合快速开发和初学者,可以使用注解和接口定义的方式来简化服务间的调用方式。
zuul是什么
是spring Cloud Netflix 中的网关组件,zuul是阻塞式的网关。
gateway是什么?
是spring cloud Netflix中的网关组件,是非阻塞式的。
Security是什么?
是spring cloud Netflix中的安全组件。
Sleuth是什么?
是spring cloud Netflix中的一个能够实现链路追踪功能的组件。
zipkin是什么?
Zipkin是一个开源的分布式追踪系统,能够收集时间数据以帮助了解服务的性能和可用性。它提供了用户界面来可视化追踪数据,帮助开发者快速定位问题。这玩意不属于Netflix公司出品。
Zuul有几种过滤器类型?分别是?
zuul 有四种过滤器类型,分别是:
1、Pre:过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求
的微服务、记录调试信息等;
2、Routing:过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用
Apache HttpClient或Netfilx feign请求微服;
3、Post:过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收
集统计信息和指标、将响应从微服务发送给客户端;
4、Error:在其他阶段发生错误时执行该过滤器。除了默认的过滤器类型微服务;
总结:路由之前、路由中、路由后、发生错误。
在项目中有没有用过openfeign
就说自己项目中有用过openfeign,自己在做spring cloud alibaba的项目的时候有用过openfeign。
然后给面试官介绍一下feign和openfeign之间的区别。
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。
OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
eureka和nacos怎样进行技术选型(面试有被问到)
eureka因为是属于Netflix公司的,现在已经停止更新了。
nacos是阿里巴巴的,现在还一直更新着呢。
eureka是ap模式的。nacos支持AP和cp,这个我们可以通过配置进行指定。
eureka他的功能比较单一,就是服务的注册与发现。nacos他的功能就比较多了,提供服务的注册与发现以及也提供了配置中心的功能。
也就是说如果你的项目本来就是Netflix的那么你就选择eureka。如果你的项目是阿里体系的,那么你就无脑选择nacos就可以了。
spring cloud加载bootstrap.yml和application.yml的先后顺序是什么呀
bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等
application.yml(application.properties) 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
加载顺序:
bootstrap.yml > application.yml > application-dev(prod).yml
加载bootstrap.yml和application.yml的应用上下文是同一个吗
bootstrap.yml和application.yml的应用上下文不是同一个。
在Spring Boot中,有两种上下文:bootstrap和application。bootstrap是应用程序的父上下文,它由父ApplicationContext加载,并且比application上下文优先加载。bootstrap.yml用于应用程序的引导阶段,主要用于加载外部配置中心的配置信息,其属性不能被覆盖。而application.yml用于定义应用级别的配置信息,可以包含动态替换的内容。
说一下你们gateway网关路由是怎么做的,你是怎么开发一个路由的,是配一个路由吗?路由是由什么组成的(面试有被问到)
gateway网关的路由是通过nacos或者是eureka中的服务名称来进行动态路由的。也就是说需要在gateway微服务的配置文件中进行配置一下就可以了。说白了就是根据服务名配一个路由。
搭建gateway微服务项目的时候,需要在pom.xml配置文件中引入gateway的依赖。
//TODO 下来再细致的看一下
你们项目中是怎样处理事务的(面试有被问到)
https://segmentfault.com/a/1190000042071649?utm_source=sf-similar-article
将一些不需要实时返回的结果放到线程池中进行执行,比说说给客户发送通知短信,打印批单等操作。
(这个一定要和面试官讲到)
因为我们系统是一个业务中台系统,最大努力通知方案,编一点,如果对方没有给我们响应,我们过一段时间也是会去查他的。
(这个一定要和面试官讲到,我的终极大招)
因为我们系统是一个业务中台的系统,需要和我们公司内部的其他系统进行交互,说白了一个交易的完成是需要调用很多其他系统的接口才能完成的,这个时候,我们在调用其他系统,会根据其他系统给我们返回的错误码,进行判断比方说不是AAAA话,就将这个错误码在进行一次封装,比方说前面加上CCG等等,最后拼接好,返回给调用方。
当然在这个过程中,我们可能也需要进行存表的操作,比方说我有两张表或者多张表需要进行数据插入的操作,但是在每张表操作的期间,可能都需要去调用其他系统的接口,这个时候,比方说我第二张表插入数据失败了,这个时候,我们是会手动去再将第一张表中的数据进行一个删除。也就是说,用了这种最笨的办法。
除此之外,我们还有一个后管系统,当然主要是给自己内部人员使用,这个时候,如果有一个交易需要插入两张表的操作,我们是采用了spring 框架提供的一个transactiontemplate的类来进行了个封装,封装了我们自己的事务模版,然后将两表的操作放到了这里面,也就是通过它来实现,第二张表插入失败回滚第一张表的数据,进而来保证事务的一致性。