springCloud面试篇

本文介绍Spring Boot、Spring Cloud等技术在微服务架构中的应用,包括配置中心、注册中心、负载均衡、熔断器、网关等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot JAVA编写=========================
@SpringBootApplication复合注解
(1)SpringBootConfiguration(本质是Configuration)
(2)CompaonentScan
(3)EnableAutoConfiguration 启动的时候SpringBoot扫描到该注解会使用spring框架的SpringFactoriesLoader去扫描classPath下所有META-INF/spring.factories文件的配置信息,然后将这些配置类Bean加载到spring容器中

SpringCloud JAVA编写=========================
======== Config配置中心 ========================================
数据交互:
(1)Push推模式:客户端和服务端建立长链接,有数据变更及时推送,但是没有考虑服务端的消费能力
(2)Pull拉模式:客户端主动向服务端获取数据,存在获取不及时情况。获取时间点,频率不好控制
(2.1)轮询:推送延迟和服务端压力无法中和
(2.2)长轮询:客户端发起长轮询请求,服务端没有数据变更会hold住请求(不会消耗很多资源),直到有数据变化/等待一定时间后返回,客户端又发起一次长轮询
为什么要等待一段时间后再次发起长轮询?
答1:连接稳定性,长轮询在传输层本质走的还是TCP协议,如果服务假死。fullgc,重启会不稳定
答2:配置中心场景用户可能会新增监听,在此之前长轮询可能已经发出去了,无法生效

======== 注册中心对比 ========================================
ZK:遵循CP原则
consul:HashiCorp推出的开源工具,实现分布式服务发现与配置,Go语言编写可移植性好。不依赖其他工具(如ZK)CP原则,使用Raft算法,因为该算法需要半数以上的节点确认后才算注册成功,所以注册时间会稍长一些
Nacos:阿里开源,支持基于DNS和基于RPC的服务发现。注册中心+配置中心 CP+AP

======== Eureka 8761端口 JAVA 【停止维护】========================================
注册中心是统一管理所有服务注册信息的平台:记录和管理各个服务元信息,比如IP 端口 运行状态等
(一)功能描述
服务注册:(regist) 服务启动的时候将自身相关信息注册到注册中心上
http方式进行注册
【原理】:ConcurrentHashMap双层Map存储,{“服务名称”:{“实例IP”:“实例元信息,IP,端口,健康检查地址,上线时间等”}}
【调用链路】Eureka Client 启动 -> DiscoveryClient#register 服务注册 -> Eureka Server-> addInstance -> PeerAwareInstanceRegistryImpl#register
服务续约:(renew) 默认每隔30秒发送一次心跳进行续约告知Eureka service我很好
【原理】客户端 renew 调用同样是在调用DiscoveryClient#initScheduledTasks 方法
服务发现:默认每隔30秒从注册中心获取服务注册表信息DiscoveryClient,并缓存到本地(缺点:超大规模集群消耗内存)
服务下线:(cancel) client主动向service发送下线请求,然后从service服务注册表中删除
服务剔除:(evict)client连续90秒没有向service续约,service会主动进行服务剔除
【原理】Server 服务端程序启动的时候,会开启一个 EvictionTask 60秒定时线程,用来监控服务的健康状况
【调用链路】initEurekaServerContext -> PeerAwareInstanceRegistryImpl#openForTraffic -> AbstractInstanceRegistry#postInit -> AbstractInstanceRegistry.EvictionTask#run -> AbstractInstanceRegistry#evict(long)
(二)主要配置
eureka.client.registerWithEureka:表示是否将自己的实例注册到 Eureka Server中。选false
eureka.client.fetchRegistry:表示是否应从 Eureka Server 中获取 Eureka 的注册表信息。选false
(三)集群节点间数据同步
采用互相注册的方式实现高可用集群
1.通过 peerEurekaNodes.getPeerEurekaNodes() 得到 Eureka Server 的所有节点信息;
2.在当前节点中循环进行复制操作,需要排除自己,不需要将信息同步给自己;
3.复制操作会根据 Action 来进行对应的操作,通过 node 对象的方法构建复制的任务,任务本质还是通过调用 Eureka 的 Rest API 来进行操作的。
(四)自我保护机制
避免网络分区故障导致服务不可用:网络故障服务与EurekaService间无法通信,会剔除没有续约的正常服务
如果服务续约低于配置(15分钟内85%)会开启自我保护机制,不再剔除注册表的信息
(五)引入actuator手动下线服务
(六)为什么服务注册这么慢
只有被调用实例服务器和调用方客户端本地缓存中都具有相同的元数据后,客户端才能发现该服务(可能需要3个心跳)

======== Ribbon ========================================
(一)负载均衡:按照指定的负载均衡算法,将请求分配到后端服务器上,从而提高并行处理能力和高可用能力
集中式:消费者和服务提供方中间使用代理
硬件F5:四层负载均衡 通过虚拟IP+端口接收请求,在分配到真实的服务器
软件Nginx:七层负载均衡 通过虚拟的URL或主机名接收请求,然后再分配到真是的服务器
客户端:客户端自己根据请求做负载,Ribbon就是这样
ribbon流程:
1.首先构建一个服务实例列表,当然也可以通过服务名从注册中心获取
2.构建负债均衡器,并设置负载策略为随机策略
3.最后调用,Ribbon 会随机选择一个服务实例返回
(二)主要组件
ILoaderBalancer:定义一系列的操作接口,比如选择服务实例
IRule:算法策略,内置算法策略来为服务实例的选择提供服务
ServerList:负责服务实例信息的获取,可以获取配置文件中的,也可以从注册中心获取
ServerListFilter:过滤掉某些不想要的服务实例信息
ServerListUpdater:更新本地缓存的服务实例信息
IPing:对已有的服务实例进行可用性检查,保证选择的服务都是可用的
(三)负载均衡算法使用场景
1.定制和业务更匹配的策略
2.灰度发布
3.多版本隔离
4.故障隔离
(四)Ribbon饥饿加载模式
Ribbon在进行客户端负载均衡的时候并不是在启动的时候就加载上下文,而是第一次请求的时候去获取对应ServiceList的服务实例信息,因此第一次调用会慢
配置饥饿加载解决
ribbon.eager-load.enabled = true
ribbon.eager-load.clients = user-service

======== Feign ========================================
(一)基本概念
声明式REST客户端,让REST调用更简单,完全代理HTTP请求
Spring Cloud 对 Feign 进行了封装,使其支持 SpringMVC 标准注解和 HttpMessageConverters。
Feign 可以与 Eureka 和 Ribbon 组合使用以支持负载均衡,与 Hystrix 组合使用,支持熔断回退。
(二)使用技巧
1.继承特性:api接口可作为独立模块,消费端和生产者共同使用。生产者implements这个接口
2.拦截器:feign提供拦截器机制,已有拦截器BasicAuthRequestInteceptor implements RequestInteceptor。可通过RequestTemplate添加请求头等操作
3.请求对象类型参数传递:SpringQueryMao注解标识参数
4.日志配置:Feign的四种日志级别:NONE(无日志),BASIC(执行方法的URL+响应码+执行时间),HEADERS(BASIC+请求头信息),FULL(全部完整请求信息)
5.异常解码器:可自定义异常解码器,了解A调用B,B返回的异常信息
(三)源码
调用流程:
0.接口类使用@FeignClient注解标识被访问服务名称,接口方法上标注URL信息和请求参数等。
1.当调用的时候通过InvoationHandlerFactory组件,基于面向接口动态代理方式生成实现类。
2.根据StringCloud OpenFeign扩展的SpringMvcContract规则,解析接口类注解信息,编译成feign内部能识别的信息
3.MethodHandler在执行的时候生成request对象,可为request对象设置拦截器,在方法执行前后进行记日志校验等操作
4.最后使用Decoder进行解码,返回结果

======== Hystrix 熔断器 ========================================
(一)服务雪崩
概念:微服务架构下服务间相关依赖调用,当某个服务不可用,很容易使故障扩大,造成整个系统不可用
避免:
服务提供者:面对超出能力的请求量,扩容+限流,处理不了就拒绝保护自己
服务消费者:资源隔离+快速失败
(二)执行流程
1.创建Command(HystrixCommand或者HystrixObservableCommand),调用执行方法
2.检查是否开启缓存,基于一个request请求构建的上下文中进行缓存
3.检查是否开启断路器(half-open半开校验),如果断路器被打开就停止当前Command方法,执行fallback降级机制
4.检查线程池/信号量是否满了,满了的话直接fallback
5.真正执行command方法并记录成功,超时,失败等结果给断路器
(三)高可用系统特性
资源隔离、限流、熔断、降级、运维监控

======== 网关Zuul ========================================
(一)为什么使用Zuul
1.Zuul、Ribbon、Eureka 三个组件相结合,可以实现动态路由和负载均衡的功能
2.统一对外暴露接口,隐藏内部实现
3.统一身份认证和权限认证,参数校验
4.统一实现实时流量监控,在高流量服务降级。
5.流量分发,灰度测试
(二)过滤器,最核心功能
过滤器可以对请求或响应结果进行处理,Zuul 还支持动态加载、编译、运行这些过滤器。
过滤器的使用方式是采取责任链的方式进行处理,过滤器之间通过 RequestContext 来传递上下文
共计四种:
1.pre 过滤器:请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程。
2.route 过滤器:在路由请求时被调用。适用于灰度发布的场景,在将要路由的时候可以做一些自定义的逻辑。
3.post 过滤器:在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于添加响应头,记录响应日志等应用场景。
4.error 过滤器:处理请求发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息。
(三)自定义过滤器
只需要继承 ZuulFilter,然后重写4个方法
1.shouldFilter 方法决定了是否执行该过滤器,true 为执行,false 为不执行,这个也可以利用配置中心来做,达到动态的开启或关闭过滤器。
2.filterType 方法是要返回过滤器的类型,可选值有 pre、route、post、error 四种类型。
3.filterOrder 指定执行顺序,数字越小,优先级越高。
4.run 方法用来写实际的业务逻辑。

======== 网关对比 ========================================
(0)zuul有1和2两个版本,springCloud只集成了1版本,2版本是Netflix在18年推出支持异步调用的,可惜springCloud没有集成计划,而且推出了gateway来取代zuul1
(1)zuul1是同步阻塞模型,本质上是一个同步Servlet,没来一个请求,zuul会分配一个线程去处理,请求量大的时候容易资源耗尽。可以使用Servlet3.0规范支持的AsyncServlet进行优化,实现前端异步,支持更多的连接数。
(2)zuul2是异步非阻塞模型,基于netty实现
(3)SpringCloud Gateway构建于spring5+,springBoot2.x 响应式非阻塞API,同时支持websockets。执行流程:Spring cloudGateway发出请求。然后再由Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway web handler。Handler再通过指定的过滤器链将请求发送到我们实际的服务执行业务逻辑,然后返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值