Spring Cloud 微服务架构

Spring Cloud是一个全家桶式的技术栈,包含了很多组件

       限流、熔断、降级

问题

回答

限流

限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或默认数据,如商品详情页库存默认有货)。

 

令牌桶算法:.随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token,如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.(Guava 的 RateLimiter)

 

Redis实现:假设一个用户(用IP判断)每分钟访问某一个服务接口的次数不能超过10次,那么我们可以在Redis中创建一个键,并此时我们就设置键的过期时间为60秒,每一个用户对此服务接口的访问就把键值加1,在60秒内当键值增加到10的时候,

降级

就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。

 

movie-goods:随机降级,降级之后实时查数据

熔断

参考:

https://segmentfault.com/a/1190000005988895

服务的健康状况 = 请求失败数 / 请求总数. 
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.

  1. 当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态.

  2. 当熔断器开关打开时, 请求被禁止通过.

  3. 当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.

问题

回答

什么是微服务?

应用程序模块化,将其分解成较小的独立服务,每个服务的功能单一;服务拆分与解耦,降低复杂性;

微服务的优缺点

优点:服务职责小,可以聚焦业务功能;被小团队单独开发减少沟通成本解耦、独立部署;能使用不同的语言开发

缺点:分布式系统可能复杂难以管理

微服务技术栈

Spring Cloud 和 Dubbo 有哪些区别?

Dubbo的定位始终是一款RPC框架

Spring Cloud的目的是微服务架构下的一站式解决方案。

 

SpringCloud:Http协议+rest接口调用远程过程的通信

Dubbo:使用Netty这样的NIO框架,是基于TCP协议传输的,配合以Hession序列化完成RPC通信

 

Spring Boot 和 Spring Cloud

Spring boot:快速开发单个微服务,使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置

Spring Cloud:微服务体系开发中的架构问题,提供了一整套的解决方案,基于Spring Boot实现的云应用开发工具

微服务注册中心Eureka

参考:

拜托!面试请不要再问我Spring Cloud底层原理

库存服务、仓储服务、积分服务中都有一个Eureka Client组件

  • Eureka Client:负责将这个服务的信息注册到Eureka Server中

  • Eureka Server:注册中心,里面有一个注册表,保存了各个服务所在的机器和端口号

Eureka如何承载千万级访问?

1.设置适当的请求频率

2.纯内存的注册表

3.多级缓存机制

 

参考:

微服务注册中心如何承载大型系统的千万级访问?

 

每个Client 每隔30s拉一次数据,每隔30s发送一次心跳,Server在一定的时间(默认90秒)未收到客户端的心跳,则认为服务宕机。

 

注册表数据结构:CocurrentHashMap 维护注册表、拉取注册表、更新心跳时间,全部发生在内存里。 key 是服务名称 value 是 Map<String, Lease<InstanceInfo>>

Map里面Key是服务实例的id,Lease,里面则会维护每个服务最近一次发送心跳的时间,InstanceInfo就代表了服务实例的具体信息,比如机器的ip地址、hostname以及端口号

 

采用了多级缓存机制来进一步提升服务请求的响应速度

Eureka比Zookeeper

Zookeeper保证CP,保证一致性和分区容错性 。master选举的时候可能导致服务瘫痪

 Eureka保证AP,保证可用性和分区容错性,允许数据一致性但得保证可用性

Feign

使用了动态代理

  • 首先,如果你对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理

  • 接着你要是调用那个接口,本质就是会调用 Feign创建的动态代理,这是核心中的核心

  • Feign的动态代理会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址

  • 最后针对这个地址,发起请求、解析响应

负载均衡 Ribbon

它的作用是负载均衡,会帮你在每次请求时选择一台机器,均匀的把请求分发到各个机器上

 

Ribbon的负载均衡默认使用的最经典的Round Robin轮询算法

Ribbon是和Feign以及Eureka紧密协作,完成工作的,具体如下:

  • 首先Ribbon会从 Eureka Client里获取到对应的服务注册表,也就知道了所有的服务都部署在了哪些机器上,在监听哪些端口号。

  • 然后Ribbon就可以使用默认的Round Robin算法,从中选择一台机器

  • Feign就会针对这台机器,构造并发起请求。

熔断降级Hystrix

Hystrix会搞很多个小小的线程池,比如订单服务请求库存服务是一个线程池,请求仓储服务是一个线程池,请求积分服务是一个线程池。每个线程池里的线程就仅仅用于请求那个服务。

Hystrix 资源隔离

 

HystrixCommand

将多个依赖服务的调用分别隔离到各自的资源池内

Hystrix 实现资源隔离,主要有两种技术:

  • 线程池 Hystrix自己的线程去执行调用,限流是通过线程池的大小来控制的,适合绝大多数场景

  • 信号量 tomcat 线程去调用,信号量的容量来进行限流,适合对内部的一些比较复杂的业务逻辑的访问,不做网络请求

command key & command group

command key:依赖服务的一个接口,多个 command key 属于一个command group,可以有自己的线程池

command group:依赖服务

coreSize:线程池的大小,默认是 10

queueSizeRejectionThreshold:如果说线程池中的 10 个线程都在工作中,没有空闲的线程来做其它的事情,此时再有请求过来,会先进入队列积压。如果说队列积压满了,再有请求过来,就直接 reject,拒绝请求,执行 fallback 降级的逻辑,快速返回。

Hystrix 执行内部原理

参考:

https://github.com/doocs/advanced-java/blob/master/docs/high-availability/hystrix-process.md

步骤一:创建 command HystrixCommand 一个结果调用 HystrixObservableCommand 多个结果调用

步骤二:调用 command 执行方法 execute() 同步;queue() 异步;observe() ;toObservable()

步骤三:检查是否开启缓存

步骤四:检查是否开启了断路器

步骤五:检查线程池/队列/信号量是否已满

步骤六:执行 command HystrixCommand 的 run() HystrixObservableCommand 对象的 construct()

步骤七:断路健康检查

步骤八:调用 fallback 降级机制 断路器处于打开状态;线程池/队列/semaphore满了;command 执行超时;run() 或者 construct() 抛出异常

网络路由 Zuul

这个组件是负责网络路由的,所有请求都往网关走,网关会根据请求中的一些特征,将请求转发给后端的各个服务。

核心组件

  • Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里

  • Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台

  • Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求

  • Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题

  • Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值