说一下SpringCloud常用组件
服务注册与发现:eureka,nacos
配置中心:nacos,Apollo
服务的熔断限流降级:sentinel
网关:gateway
远程调用:openfeign
负载均衡:ribbon/loadbalancer
链路追踪:skywalking
CAP & BASE
CAP理论:一致性(Consistency),可用性(Availability),分区容错性(Partition tolerance)
CA模型,例如传统型数据库Oracle,mysql
CP,例如zk
AP,例如redis
nacos可以是cp也可以是AP
Base理论
基本可用(Basically Available)
软状态(Soft State)
最终一致性(Eventually Consistent)
BASE是对CAP中一致性和可用性权衡的结果
注册中心与配置中心
注册中心是AP还是CP
CP意味着注册中心集群内部数据未达到一致之前,不允许服务注册和发现
AP意味着注册中心集群内部数据未达到一致之前,还是能提供服务,最终一致就好了。
nacos基本架构及原理
当服务提供方启动时,会向nacos发送注册请求,nacos将注册请求放到一个阻塞队列中,会有一个负责注册的线程池单独执行注册请求,将处理请求写和注册的操作分离开,提高性能。采用内存队列,避免并发写异常。
当服务提供方产生变化的时候,nacos会采用服务端udp推送和客户端主动拉取两种模式进行结合,udp协议非常快,不需要保持长连接。在注册中心场景中服务的消费者多余提供者,如果每一次服务更新,nacos要和大量消费者去建立Tcp,性能会下降。如果udp通知失败,客户端每10s还会主动去拉去一次,客户端拉取和服务器推送时互补的。
服务的提供方会向nacos server注册信息,这个注册信息会包装成Instance,放到ServiceInfo中
服务的提供方每隔5s会向nacos server发送心跳,如果server端在15秒内未收到Client心跳,则会标记为不健康的状态;若在30s内收到Client心跳,则恢复为健康状态,否则从Server的内存中清除该实例。(不健康的实例,server会自动清除)
服务消费者在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Server本地,同时在Nacos Server本地开启一个定时任务,定时拉取服务端最新的注册表信息更新到本地缓存中
nacos的资源隔离
namespace:以大环境进行隔离
group:以组进行分离
nacos临时实例和持久实例
临时实例:Client主动向Server上报其健康状态(类似推模式)。默认心跳间隔5秒,15秒内Server未收到Client心跳,则会将其标记为不健康状态;30秒内收到Client心跳,则恢复健康状态,否则从Server端内存删除。
持久实例:Server会主动去检测Client的健康状态(类似拉模式),默认每20s检测一次。不健康的实例,不会被清除,需要手动清除。
eureka工作原理
服务提供方到eureka上注册,写到注册表中
注册表信息会同步到readwrite缓存中,当readwrite没有就上注册表拉去。
readwrite缓存中的数据会每隔30s通过一个线程同步到readonly缓存中
服务消费方每隔30s到readonly拉去缓存
eureka失效剔除和自我保护机制
失效剔除:
服务提供方会因为内存溢出、网络故障等原因导致服务无法正常工作。eureka server会开启一个定时任务,每隔60s对所有失效的服务进行剔除。(从服务列表中剔除这个服务)
自我保护:
比如关掉一个服务,eureka面板会报一条警告,这就是触发了自我保护机制。因为网络延迟等原因,心跳失败实例的比例可能超标。所以剔除服务并不妥当,因为服务可能没有宕机。eureka会把当前实例的注册信息保护起来,不予剔除。一般在生产环境有效,开发阶段一般关闭保护服务
说一下eureka注册中心原理以及和zookeeper实现注册中心的区别
服务提供方启动时,会在eureka上面进行一个注册,注册完后每隔30s就会发送一个消息,证明自己存在。
eureka注册中心还有一个定时任务,每隔60s就会检测,超过90s没有对服务进行续期,就会被剔除
服务调用方启动时,回去注册中心获取最新的服务提供方的列表,调用方列表是每隔30s去提供方获取最新的列表,来更新。
eureka是AP思想,所以保证最终一致性,不管提供方还是调用方都有延迟,如果eureka做一个集群,他们之间相互注册,他们之间的数据采用的是复制,数据同步也采用最终一致性,所以集群会有延迟。
dubbo在使用zookeeper注册中心的时候,提供方在zookeeper注册中心保持一个长连接,如果临时断开连接,就会自动删除。zookeeper是强一致性方案(cp)
nacos配置中心动态刷新原理
nacos结合了推和拉的优势,客户端采用长轮询机制,定时发起长轮询请求,当发现服务端配置和客户端配置一致时,服务端会拿到请求,进入等待期,服务端拿到连接后一直不返回结果,知道这段时间配置发生变化,服务端把拿到的请求返回。
服务端会把请求放入队列中,有两种情况:第一种,时30s之内服务端配置发生了变化服务端返回结果。第二种,30s没有任何变化,服务端也会返回一个没有变化的结果。
负载均衡ribbon & loadBalancer
什么是服务端负载均衡,什么是客户端负载均衡
客户端负载均衡:客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡。
服务端负载均衡:比如nginx,先发请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;
常见的负载均衡算法
随机,通过随机选择服务进行执行,一般这种方式很少使用
轮巡,负载均衡默认实现方式,一个一个的来;
加权轮巡,通过对服务器性能分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力
地址hash,通过客户端请求地址的hash值取模映射进行服务器调度
最小连接数,即使请求均衡了,压力不一定均衡,最小连接数就是根据服务器的情况,(请求压力参数)将请求分配到当前压力最小的服务器上
ribbon及loadbalancer工作原理
对restTemplate做了定制,定制过程种加了拦截器
restTemplate在调用的时候就会执行拦截器,通过拦截器里面我们就找到对应负载均衡的LoadBalancer,去选择一个服务对应的实例的ip和port出来
继续执行请求调用
feign
feign的基本使用
@EnableFeignClients
@FeignClient
feign的拦截器使用
解决头信息丢失问题
feign在远程调用的时候,会丢掉头信息的内容,所以需要拦截器,把头信息重新设置回去
feign的工作原理
@EnableFeignClients,会扫描标注了@FeignClient注解的接口,创建feignClientFactoryBean放到Spring容器中
如果要使用某个接口的时候,会使用feignClientFactoryBean采用jdk动态代理创建一个代理对象
通过代理对象发送请求,接收响应
feign与openfeign
OpenFeign对Feign进行了增强,OpenFeign支持SrpingMVC注解
OpenFeign时声明式的HTTP客户端,让远程调用更简单。
提供了HTTP请求模板,可以定义HTTP请求的参数,格式,地址
整合了负载均衡组件和熔断降级组件
网关
网关应该具有那些功能
1、路由转发 2、认证,鉴权 3、安全 4、防刷 5、流量控制 6、黑名单(防作弊)
那些能做网关
zuul:灰度发布,限流,熔断,动态路由需要做二次开发
gateway
nginx+Lua
Kong:就是nginx里面基于Lua写的一个模块实现了网关功能
自研网关
gateway中重要概念
路由(route)
路由时网关最基础的部分,路由信息包括一个ID,目的URI,一组断言工厂,一组Filter
断言(predicates)
断言即一个条件判断,根据当前http请求进行指定的规则匹配(http请求头,请求时间)。只有符合匹配规则时,断言才为true,此时请求才会被直接路由到目标地址(服务器),或先路由到某个过滤器链,经过层层处理后,在路由到相应的目标地址。
过滤器(Filter)
SpringCloud Gateway中的Filter分为Gateway Filter和Global Filter。Filter可以对请求和响应进行处理。
对请求进行处理逻辑部分,当请求的断言为true时,会被路由到设置好的过滤器,以对请求或响应进行处理。例如,可以为请求添加一个请求参数或为响应添加header。总之,就是对请求(pre filter)或响应(post filter)进行处理
gateway中的全局过滤器
继承GlobalFilter,
获取token,并对token进行条件判断
效验token进行身份验证
限流算法
令牌桶,漏斗桶,滑动窗口
gateway工作原理
gateway的路由包括id,uri,断言器,filter
请求先经过断言器,如果断言为true,请求到达filter
请求执行filter之后,才会转给对应的服务
请求到DispatcherHandler
DispatcherHandler根据请求分发到对应的RoutePredicateHandlerMapping
将请求转给FilteringWebHandler
FilteringWebHandler会拿到多个Filter取执行
最后通过netty将请求发到服务端
微服务认证鉴权方案
请求通过负载均衡发给网关
先判断是否携带token,没有就返回客户端
检验token合法性,成功就提取用户信息
将提取出来的用户信息放在请求头中,带到微服务
在微服务中准备一个拦截器,拦截请求头的信息,解析出来放到ThreadLocal中
其他服务就从ThreadLocal中获取用户信息
服务D通过Feign调用服务C,需要实现RequestInterceptor从ThreadLocal中获取用户信息,再将头信息带到服务C
zuul的工作原理
正常流程:
请求过来先被ZuulServlet拦截,然后将请求发给pre类型过滤器,后到达routing类型,进行路由,到达服务提供者执行请求并返回结果,到达post过滤器。而后响应
异常流程:
整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了
Sentinel
什么是服务雪崩
服务的依赖失败:A服务依赖B服务,其他服务依赖A服务,B服务故障,导致A服务超时,导致其他调用A服务的服务超时,一直延申下去导致项目不可用
比如A服务接收的QPS为5000,这是调用方B调用的时候QPS为3000QPS,另一个调用方C为15KQPS,所以A服务处理调用方C时,因为请求大,自身接收有限。所以A服务执行时会宕机,导致其他调用方失效
熔断器工作原理
服务调用过程中,获取远端的服务在一定时间内的失败比例,当达到规定失败比例时,开启熔断器
熔断器打开之后,下次调用直接采用本地的降级方法直接返回。
隔一定的时间,会将用户的请求放过去(此时熔断器为半打开状态),能调通服务,说明服务恢复,熔断器关闭。不通就继续熔断降级。
sentinel使用
定义资源
通过API
声明方式:@SentinelResource指定资源
定义规则(sentinel的dashbord控制台)
feign上支持sentinel的使用方式
通过FallBack指定
通过FallBackFactory指定
sentinel规则持久化
不改造前:每一个服务会和sentinel dashbord通信,我们在访问服务的时候,sentinel dashbord就会收集到这些信息,可以在dashboard看到我们的资源,然后再dashbord配置规则,让这个规则推给我们的服务,但是只在这个服务的内存中,服务重启,规则消失。
改造后:引入nacos配置中心来做持久化,dashboard改了之后推给nacos配置中心,服务就从配置中心拉取,也可以通过nacos的配置中心进行规则配置。
sentinel提供了那些规则
流控规则,熔断,降级规则,热点参数,系统规则
sentinel的工作原理
我们使用时会指定资源,请求过程中会将资源转换成Entry,同时会为Entry添加一系列的slot,形成slot chain,
每个slot有各自的职责,想扩展slot,可以通过SPI机制来实现
sentinel和hystrix
sentinel是产品级的(开箱即用),hystrix是组件级的
hystrix基于线程池隔离和信号量隔离,sentinel基于信号量隔离
hystrix的控制台不完善,sentinel提供完善的控制台
链路追踪
SkyWalking
架构图
seata
微服务其他
说一下你对微服务的理解?如果让你搭建微服务,你怎么解决以后的扩展和并发问题?
微服务的理解:
微服务就是把各个模块拆分成不同的项目,每个模块都只关注一个特定的业务功能,每个项目都是一个独立的项目,运行在独立的进程上,这意味着一个小单元的损坏不会影响其他单元。所以,可以在不影响完整项目的情况下可以重建其他某些单元。
解决扩展和并发问题:
考虑垂直扩展(硬件升级)或水平扩展(服务实例增加),利用docker进行部署,将服务制作成镜像,按照响应的要求进行部署容器。
并发对每个服务要按需集群部署,如果数据库压力过大,就可以读写分离,分库分表,主从复制。将热点数据存到缓存中,先从缓存找,没有在从db找;可以用hystrix线程池隔离和信号量隔离;mq削峰
服务器升级,你们的网关怎么处理的?
灰度发布
新服务上限时,为保证不出问题,可以将少量请求转发到新服务上,其他请求还是发到旧服务上去,等新服务测试通过了,就可以平均分配请求,这就是灰度发布。
要完成灰度发布,要修改ribbon的负载均衡策略,通过特定的标识,,将10%的请求转发到新服务上,90%的请求转发到旧服务上,制定各种规则进行灰度测试。
现在让你搭建一个SpringCloud的微服务架构,考虑哪些东西搭建出来?
API网关,数据库横向扩展,缓存,服务拆份和服务发现,统一配置中心,熔断、限流、降级
怎么判断请求到了哪些服务?如果同时有几百万请求进来,项目怎么处理?
①、使用服务链路追踪SpringCloud Sleuth追踪调用的链路
②、同时有几百万请求:
限流
缓存
mq削峰
数据库读写分离,分库分表
SpringCloud常用注解
@FeignClient:
@EnableFeignClients:开启SpringCloud Feign支持
@EnableEurekaServer:启动一个服务注册中心
@EnableEurekaClient:配置服务注册和服务发现
@LoadBalanced:开启负载均衡
@EnableHystrix:启动断路器,断路器依赖于服务注册和发现
dubbo和SpringCloud区别
Dubbo时RPC框架,SpringCloud是微服务架构下的一站式解决方案。
SpringCloud基于HTTP通信,使用feign调用,调用服务提供方controller的接口,采用json传递数据
Dubbo采用Sokcet协议,底层使用netty调用服务提供方的service接口,采用二进制序列化传递数据
Zull(Gateway)网关挂了怎么办
互联网公司中网关都是集群
在微服务中,所有服务请求都会统一请求到zull网关上
评论区