Spring Cloud 面试
spring cloud如何实现服务的注册与发现
服务在发布时,指定对应的服务名(包括了服务的ip地址和port) 将服务注册到注册中心(eureka 或者 zookeeper) 这一过程是springcloud自动实现,只需要在main方法添加@EnableDisscoveryClient 同一个服务修改端口就可以启动多个实例
调用方法: 传递服务名称通过注册中心获取所有的可用实例 通过负载均衡策略调用(ribbon和feign)对应的服务
ribbon和feign区别
-添加依赖不同:
- ribbon 添加maven依赖 spring-stater-ribbon 使用 @ribbonClient (value=“服务名称”) 使用Resttemplate调用远程服务对应的方法
- feign 添加maven依赖 spring-starter-feign 服务提供对外接口 调用方法使用 @FeignClient (“指定服务名”)
启动类注解不同:
- ribbon使用的是 @RibbonClient
- Feign使用的是 @EnableFeginClients
服务的指定位置不同:
- Ribbon是在 @RibbonClient 注解上声明
- Feign则是在定义抽象方法的接口中使用 @FeignClient 声明;
调用方式不同:
- Ribbon需要自己构建 http 请求,模拟 http 请求然后使用ResTemplate发送给其他服务,步骤繁琐,
- Feign则是在Ribbon的基础上进行了一次改进,采用接口方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建 http 请求,不过注意的是抽象方法的注解,方法签名要和提供的服务方法完全一致
springcloud断路器的作用
- 当一个服务调用另一个服务由于网络原因或者自身原因出现问题时,调用者就会等待被调用者的响应,当更多的服务请求到这些资源时就会造成更多的请求等待.这样就会发现连锁效应(雪崩效应) 断路器用来解决这一问题
状态:
完全打开: 一定时间内,达到一定次数的无法调用,并且多次监测没有恢复的迹象,断路器完全打开,下次请求就不会请求到服务器
半开: 短时间内 有恢复迹象 断路器会将部分请求发给该服务 当正常调用时, 断路器关闭
关闭: 当服务处于正常状态 能正常调用时,断路器关闭
springcloud和dubbo的区别
初始定位不同:
- SpringCloud定位为微服务架构下的一站式解决方案;Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用和治理
生态环境不同:
- SpringCloud依托于Spring平台,具备更加完善的生态体系;而Dubbo一开始只是做RPC远程调用,生态相对匮乏,现在逐渐丰富起来。
调用方式:
- SpringCloud是采用Http协议做远程调用,接口一般是Rest风格,比较灵活;Dubbo是采用Dubbo协议,接口一般是Java的Service接口,格式固定。但调用时采用Netty的NIO方式,性能较好。
组件差异比较多:
- 例如SpringCloud注册中心一般用Eureka,而Dubbo用的是Zookeeper
SpringCloud生态丰富,功能完善,更像是品牌机,Dubbo则相对灵活,可定制性强,更像是组装机。
熔断,降级
-
降级:
系统将某些不重要的业务或接口的功能降低,可以只提供部分功能,也可以完全停到所有所有不重要的功能。降级的思想是丢车保帅。
常见降级方式:
- 系统后门降级: 系统预留后门用于降级,比如提供一个降级URL,访问URL时就执行降级指令。缺点:如果服务器数量多,需要一台一台去操作,效率低。
- 独立系统降级: 将降级操作独立到一个单独的系统中,可以实现复杂的权限管理、批量操作等功能。
-
熔断:
- 在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。
这种牺牲局部,保全整体的措施就叫做熔断。
-
开启熔断:
在固定的时间内,接口调用错误比例达到一个阈值,会开启熔断;
在进入熔断状态后,后续对该服务接口的调用不经过网络,会直接执行默认方法。
-
熔断恢复:
首先熔断状态不可能是永久的,当经过规定的时间后,服务将会从熔断状态恢复,再次接受请求调用。
-
熔断常用组件: Hystrix
Spring Cloud Hystrix是基于Netflix的开源框架Hystrix实现,该框架实现了服务熔断、线程隔离等一系列服务保护功能。
-
对于熔断机制的实现,Hystrix设计了三种状态:
-
熔断关闭状态(Closed) :
服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。
-
熔断开启状态(Open) :
在固定时间内(Hystrix默认是10秒),接口调用出错比率达到一个阈值(Hystrix默认为50%),会进入熔断开启状态。 进入熔断状态后, 后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。
-
半熔断状态(Half-Open) :
在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。
所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。
如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。
-
eureka和zookeeper都可以进行服务注册发现,两者有什么区别
- Zookeeper 保证了 CP(C:一致性,P:分区容错性);
- Eureka 保证了AP(A:高可用) ;
- Zookeeper 有header和follower角色(当header挂掉,会从剩下的follower里面选举一个header),在选举期间注册服务瘫痪不可用;
- Eureka 使用了去中心化架构各个节点平等,只要一台就能保证服务可以,但查询到的数据不一定是最新的,可以很好的应对网络故障导致的部分节点失联 ;
- Eureka还有一种自我保护机制,如果在15分钟内超过 85% 的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
- Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;
- Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
- 当网络稳定时,当前实例新注册的信息会被同步到其它节点中。
eureka和nacos的区别
-
CAP理论的区别:
C一致性,A高可用,P分区容错性
- eureka只支持AP
- nacos支持CP和AP两种
nacos是根据配置识别CP或AP模式,如果注册Nacos的client节点注册时配置是ephemeral=true即为临时节点,那么Naocs集群对这个client节点效果就是AP,反之则是CP,即不是临时节点
# false为永久实例,true表示临时实例开启,注册为临时实例
spring.cloud.nacos.discovery.ephemeral: true
-
连接方式不同:
- nacos使用的是netty和服务直接进行连接,属于长连接。
- eureka是使用定时发送和服务进行联系,属于短连接。
-
服务异常剔除方式不同:
-
eureka:
- Eureka client在默认情况每隔30s向Eureka Server发送一次心跳,当Eureka Server默认连续90s秒没有收到心跳时,会把Eureka client 从注册表中剔除,再由Eureka-Server 默认60秒的清除间隔,把Eureka client 给下线。
也就是在极端情况下Eureka 服务 从异常出现到剔除服务,再到完全不接受请求可能需要 30s+90s+60s=3分钟左右(还是未考虑ribbon缓存情况下)。
EurekaInstanceConfigBean 类下 private int leaseRenewalIntervalInSeconds = 30; //心跳间隔30s private int leaseExpirationDurationInSeconds = 90; //默认90s没有收到心跳从注册表中剔除 EurekaServerConfigBean 类下 private long evictionIntervalTimerInMs = 60000L; //异常服务剔除下线时间间隔
- Eureka client在默认情况每隔30s向Eureka Server发送一次心跳,当Eureka Server默认连续90s秒没有收到心跳时,会把Eureka client 从注册表中剔除,再由Eureka-Server 默认60秒的清除间隔,把Eureka client 给下线。
-
nacos:
-
nacos client 通过心跳上报方式告诉nacos注册中心服务的健康状态,默认心跳间隔5秒。
nacos会在超过15秒未收到心跳后将实例设置为不健康状态,可以正常接收到请求 。
超过30秒nacos将实例删除,不会再接收请求 。
-
-
-
操作实例方式不同:
-
eureka:
只提供了实例列表、实例的状态、实例的错误信息。相比于nacos过于简单。
-
nacos:
提供了nacos console可视化控制界面,可以对实例列表进行监听、上下线、权重配置等。
并且config service对服务实例提供了配置中心,可以对配置进行crud、版本管理等。
-
-
自我保护机制的区别:
1)相同点:
保护阈值都是个比例,0-1 范围,表示健康的实例 (instance)占全部实例(instance)的比例。
2)不同点:
-
保护方式不同:
-
eureka保护方式:
在短时间内,统计续约失败的实例,如果比例达到一定阈值,则会自动触发自我保护的机制。在该机制下,eureka不会提出任何服务,等到正常后,再推出自我保护机制。
#自我保护机制开关配置 eureka.server.enable-self-preservation: false
-
nacos保护方式:
**当域名健康实例 (Instance) 占总服务实例(Instance) 的比例小于阈值时,无论实例 (Instance) 是否健康,都会将这个实例 (Instance) 返回给客户端。**这样做虽然损失了一部分流量,但是保证了集群的剩余健康实例 (Instance) 能正常工作。
-
-
保护范围不同:
Eureka的自我保护阈值是针对所有服务的。
Nacos的阈值是针对某个具体的服务的。
-
分布式存储
- 分布式存储是指将数据存储在多个节点上,通过网络协议实现数据共享和协同处理,以实现数据的高可用性、可扩展性和容错性。
- 传统集中存储结构,将数据存储在单一节点上,当该节点出现故障时会造成整个系统瘫痪。
分布式存储通常包含:
- 数据分区和副本: 将数据划分为若干个分区,并将每个分区的副本存储在多个节点上,以提高数据的可用性和容错性。
- 数据一致性:在多个节点上存储同一个数据副本时,需要保证数据的一致性,即数据的更新必须在所有节点上同步完成。
- 负载均衡:将数据和请求均匀的分布到不同的节点,以提高系统的吞吐量和性能。