欢迎光临散文网 会员登陆 & 注册

SpringCloud相关核心知识点

2023-05-31 17:26 作者:黑马程序员黄埔训练营  | 我要投稿

1 SpringBoot和SpringCloud什么区别 ?

springboot和springcloud的区别主要是:

1.作用不同;springboot的作用是为了提供一个默认配置,从而简化配置过程;springcloud的作用是为了给微服务提供一个综合管理框架

2.使用方式不同;springboot可以单独使用;springcloud必须在springboot使用的前提下才能使用。

springboot的设计目的是为了在微服务开发过程中可以简化配置文件,提高工作效率,可以认为是一个脚手架工具 , 帮助我们快速的搭建基于spring的项目

SpringCloud就是利用SpringBoot将各种微服务项目中的解决方案封装成starter , 提供默认配置 , 让我们在项目开发过程中能够方便的使用各种组件

2 你们项目为什么要使用微服务

传统的大型单体应用程序在部署和运行时,需要单台服务器具有大量内存和其他资源。大型的单体应用必须通过在多个服务器上复制整个应用程序来实现横向扩展,因此其扩展能力极差;此外,这些应用程序往往更复杂,各个功能组件紧耦合,使得维护和更新非常困难。在这种情况下,想单独升级应用的一个功能组件,就会牵一发而动全身 , 某一个功能升级了可能会导致其他功能又出现故障 , 项目运行过程中某一个地方出现了bug可能会导致整个应用崩溃

在微服务架构中,传统的大型单体应用被拆分为小型模块化的服务,每项服务都围绕特定的业务领域构建,不同微服务可以用不同的编程语言编写,甚至可以使用完全不同的工具进行管理和部署 , 与单体应用程序相比,微服务组织更好、更小、更松耦合,并且是独立开发、测试和部署的。由于微服务可以独立发布,因此修复错误或添加新功能所需的时间要短得多,并且可以更有效地将更改部署到生产中。此外,由于微服务很小且无状态,因此更容易扩展 !

但是微服务也有问题 , 微服务最致命的地方在于成本和管理问题。一个系统由多个微服务组成,多个微服务之间的系统整合,团队间合作和沟通难度,是呈指数级增长的。项目管理和部署的难度也非常高 , 需要考虑到很多东西 , 而且因为服务比较多 , 需要的服务器成本也比较高

所以具体要不要搞微服务, 还是得仔细的分析和思考 , 权衡之后再决定 , 我们的项目中因为面向的是整个互联网用户 , 考虑到后期运营比较好的情况下可能会出现的用户增长 , 流量增长 , 以及不断的版本迭代 , 方便后期扩展和功能迭代所以选择了微服务架构

3 Spring Cloud 5大组件有哪些?

Spring Cloud五大组件主要是

1.注册中心组件 , 例如 : Eureka 和 Nacos

2.负载均衡组件 , 例如 : Ribbon 和 Spring Cloud LoadBalancer

3.远程调用组件 , 例如 : Feign 和 Dubbo

4.服务熔断组件 , 例如 : Hystrix 和 Sentinel

5.服务网关组件 , 例如 : Zuul 和 Spring Cloud Gateway

4 什么是微服务?微服务的优缺点是什么?

微服务就是一个独立的 , 职责单一的服务应用程序,一般在项目开发过程中会按照业务和需求将项目拆分成N个微服务

1.优点:松耦合,聚焦单一业务功能,无关开发语言,团队规模降低 , 扩展性好, 天然支持分库

2.缺点:随着服务数量增加,管理复杂,部署复杂,服务器需要增多,服务通信和调用压力增大

5 你们项目中微服务之间是如何通讯的?

服务的通讯方式主要有二种 :

1.同步通信:通过Feign发送http请求调用 或者 通过Dubbo发送RPC请求调用

2.异步通信:使用消息队列进行服务调用,如RabbitMQ、KafKa等

6 服务注册和发现是什么意思?Spring Cloud 如何实现服务注册发现?

各种注册中心组件的原理和流程其实大体上类似 , 核心的功能就一下几个 :

1.服务注册 : 服务启动的时候会将服务的信息注册到注册中心, 比如: 服务名称 , 服务的IP , 端口号等

2.服务发现 : 服务调用方调用服务的时候, 根据服务名称从注册中心拉取服务列表 , 然后根据负载均衡策略 , 选择一个服务, 获取服务的IP和端口号, 发起远程调用

3.服务状态监控 : 服务提供者会定时向注册中心发送心跳 , 注册中心也会主动向服务提供者发送心跳探测, 如果长时间没有接收到心跳, 就将服务实例从注册中心下线或者移除

7 你们项目中使用的注册中心是什么 ? 有没有了解过原理 ?

我们项目中注册中心用的是Nacos , 基本上所有的注册中心的核心功能都包括服务注册 , 服务发现, 服务状态监控 , 他的核心原理如下 :

1.客户端启动时会将当前服务的信息包含ip、端口号、服务名、分组名、集群名等信息封装为一个Instance对象,准备向Nacos服务器注册服务,在注册服务之前,会根据Instance中的信息创建一个BeatInfo对象,然后创建一个定时任务,每隔一段时间向Nacos服务器发送PUT请求并携带相关信息,作为定时心跳连接,服务器端在接收到心跳请求后,会去检查当前服务列表中有没有该实例,如果没有的话将当前服务实例重新注册,注册完成后立即开启一个异步任务,更新客户端实例的最后心跳时间,如果当前实例是非健康状态则将其改为健康状态

2.心跳定时任务创建完成后,通过POST请求将当前服务实例信息注册进Nacos服务器,服务器端在接收到注册实例请求后,会将请求携带的数据封装为一个Instance对象,然后为这个服务实例创建一个服务Service,一个Service下可能有多个服务实例,服务在Nacos保存到一个ConcurrentHashMap中,格式为命名空间为key,value为map,分组名和服务名为内层map的key,value为服务数据

3.服务创建完成之后,开启一个定时任务(5s执行一次),检查当前服务中的各个实例是否在线,如果实例上次心跳时间大于15s就将其状态设置为不健康,如果超出30s,则直接将该实例删除;

4.然后将当前实例添加到对应服务列表中,这里会通过synchronized锁住当前服务,然后分两种情况向集群中添加实例,如果是持久化数据,则使用CP模型,通过leader节点将实例数据更新到内存和磁盘文件中,然后同步写入到其他节点 , 必须集群半数以上节点写入成功才会给客户端返回成功;

5.如果是非持久话实例数据,使用的是AP模型,首先向任务阻塞队列添加一个本地服务实例改变任务,去更新本地服务列表,然后在遍历集群中所有节点,分别创建数据同步任务放进阻塞队列异步进行集群数据同步,不保证集群节点数据同步完成即可返回;

6.在将服务实例更新到服务注册表中时,为了防止并发读写冲突,采用的是CopyOnWrite的思想,将原注册表数据拷贝一份,添加完成之后再替换回真正的注册表,更新完成之后,通过发布服务变化事件,将服务变动通知给客户端,采用的是UDP通信,客户端接收到UDP消息后会返回一个ACK信号,如果一定时间内服务端没有收到ACK信号,还会尝试重发,当超出重发时间后就不在重发,虽然通过UDP通信不能保证消息的可靠抵达,但是由于Nacos客户端会开启定时任务,每隔一段时间更新客户端缓存的服务列表,通过定时轮询更新服务列表做兜底,所以不用担心数据不会更新的情况,这样既保证了实时性,又保证了数据更新的可靠性;

7.服务发现:客户端通过定时任务定时从服务端拉取服务数据保存在本地缓存,服务端在发生心跳检测、服务列表变更或者健康状态改变时会触发推送事件,在推送事件中会基于UDP通信将服务列表推送到客户端,同时开启定时任务,每隔10s定时推送数据到客户端

8 你们项目负载均衡如何实现的 ?

服务调用过程中的负载均衡一般使用SpringCloud的Ribbon 组件实现 , Feign的底层已经自动集成了Ribbon , 使用起来非常简单 , 客户端调用的话一般会通过网关, 通过网关实现请求的路由和负载均衡

RIbbon负载均衡原理 :

SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址做了修改。

基本流程如下:

1.LoadBalancerInterceptor拦截RestTemplate请求

2.调用RibbonLoadBalancerClient从请求url中获取服务名称

3.调用DynamicServerListLoadBalancer根据服务名称到注册中心拉取服务列表 , 注册中心返回列表

4.DynamicServerListLoadBalancer调用IRule使用配置的负载均衡策略负载均衡规则,从服务列表中选择一个服务实例

5.RibbonLoadBalancerClient用服务实例的IP和端口替换请求路径中的服务名称

6.向服务实例发起http请求

9 Ribbon负载均衡策略有哪些

Ribbon默认的负载均衡策略有七种 :

通过定义IRule实现可以修改负载均衡规则,有两种方式:

代码方式:通过配置类, 配置一个IRule接口的实现类 , 这是一种通用配置 , 使用于所有的服务调用

@Bean

public IRule randomRule(){ 

   return new RandomRule();

}

配置文件方式:在配置文件中配置负载均衡规则

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务 

 ribbon:   

 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

10 你们项目的配置文件是怎么管理的 ?

大部分的固定的配置文件都放在服务本地 , 一些根据环境不同可能会变化的部分, 放到配置中心中管理 , 我们项目使用Nacos配置中心进行配置的统一管理 , 包括 : 开发环境配置 , 测试环境配置生产环境配置

11 你们项目中有没有做过限流 ? 怎么做的 ?

限流其实在整个请求的处理流程中都需要做

1.客户端发送请求到Nginx需要进行限流

2.通过Nginx负载均衡请求到网关 , 网关也需要限流

3.网关路由请求到微服务 , 微服务也需要限流

每一层所使用的限流方案也不一样 :

1.nginx层主要是对请求的IP进行限流 , 使用的是limit_req_zonelimit_req配置 , 底层使用的是漏桶算法实现的 , nginx层限流主要是对下游的网关起到保护作用

2.网关层限流主要使用的是Spring Cloud Gateway提供Request Rate Limiting过滤器实现的 , 底层使用Redis基于令牌桶算法实现限流 , 网关限流主要是对下游的微服务系统起到保护作用

    3.微服务限流的目的主要是为了保护微服务本身不被大流量冲垮 , 可以使用Hystrix和Sentinel进行限流 , 底层使用的是信号量和线程隔离实现的 , 当请求达到限制或者失败频率较高会自动熔断 , 执行降级逻辑

    12 断路器/熔断器用过嘛 ? 断路器的状态有哪些


我们项目中使用Hystrix/Sentinel实现的断路器 , 断路器状态机包括三个状态:

1.closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态

2.open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态5秒后会进入half-open状态

3.half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作

请求成功:则切换到closed状态

请求失败:则切换到open状态

13 你们项目中有做过服务降级嘛 ?

我们项目中涉及到服务调用得地方都会定义降级, 一般降级逻辑就是返回默认值 , 降级的实现也非常简单 , 就是创建一个类实现FallbackFactory接口 , 然后再对应的Feign客户端接口上面 , 通过@FeignClient注解中的fallbackFactory属性指定降级类工厂

引用FallbackFactory

@FeignClient(value = "task-service",fallbackFactory = TaskServiceFallbackFactory.class)

public interface TaskService {   }



SpringCloud相关核心知识点的评论 (共 条)

分享到微博请遵守国家法律