流程

分布式、微服务

首先明确一个概念,分布式

例如,有一个电商系统,用户 > 订单 > 库存 > 仓储 > 积分

这些业务都在在一个服务中的,耦合极其严重,每次开发、打包、部署、极其繁琐

最主要的一个问题的,如果其中某个服务出现了问题,必然会影响其余服务

分布式通常按业务拆分成多个子系统

每个业务服务子系统部署在单独的机器上

一次下单请求调用多个服务协作共同完成

每个服务只处理自己范围内的业务

业界主流的分布式解决方案 Dubbo / Spring Cloud

现在把上面的电商系统,拆分成 订单服务、库存服务、存储服务、积分服务

这些服务部署在不同的机器上

Spring Cloud 为我们提供了分布式业务场景中的各个解决方案

1、注册中心Eureka
注册中心是一个单独的服务,主要负责服务的注册与发现
订单服务、库存服务、存储服务、积分服务这些服务在启动的时候,会向注册中心提供自己的服务地址
例如 [订单服务:192.168.52.101:8080],[库存服务:192.168.52.102:8080]
这个过程称之为服务注册
Eureka的另外一个功能的服务发现
各个服务会通过服务发现,把维护在Eureka注册中心里的服务地址拉取到自己本地
服务之间调用的时候,就可以直接从自己本地拿到对方服务的地址

2、Ribbon负载均衡
Ribbon 的核心功能的负载均衡
内部提供了多种负载均衡算法
默认采用轮询的方式
Ribbon会向Feign提供各个服务器地址进行远程调用,如果涉及到某个服务是集群方式,单个应用部署在多个机器上
例如[订单服务:192.168.52.101:8080],[库存服务:192.168.52.102:8080 / 192.168.52.103:8080]
例如库存服务有多个,则会采用轮询的方式向 Feign 提供 服务地址
3、Feign 远程调用
服务之间相互调用的时候,会通过 Feign 进行 http 进行调用
Feign通过接口的方法调用Rest服务
遵循了面向接口编程的方式

4、Hystrix 断路器
这块是属于高可用方面的解决方案
单点故障之后的解决方案
涉及到服务降级、服务限流、服务熔断、近实时监控

5、zuul 路由网关
现在的项目一般都是采用前后端分离的方式
如果没有网关这块,那么前端要维护上百个后端接口,这么多接口直接对外暴露,极其繁琐,复杂
zuul 所有的请求都可以通过这个入口,来进行访问后端服务
zuul 主要涉及到代理、路由、过滤三大功能

springcloud 分布式版限流 springcloud怎么实现分布式_缓存

原理

注册中心Eureka

两个核心功能

服务注册与发现

心跳与故障

我们服务启动之后会在Eureka中注册

在Eureka中有一个注册表

表中维护了我们的服务地址

其余服务启动的时候,会去Eureka中拉取注册表

拉取的这个间隔可以进行配置

服务注册与发现

在Eureka中有一个多级缓存的概念( ReadOnly缓存 / ReadWrite缓存 )

内部维护的3块区域 【ReadOnly缓存】 >> 【ReadWrite缓存】 >> 【注册表】

目的是为了优化并发冲突

如果没有这3块区域,边写边读的并发操作,锁的冲突对系统是有一定的影响的

在服务发现的时候,会去 【ReadOnly缓存】 中拉取 注册表信息

在服务 注册 / 修改 的时候,会在【注册表】中注册服务信息,会立马同步到 【ReadWrite缓存】

在 【ReadOnly缓存】 到 【ReadWrite缓存】之间 会有一个线程 定时同步注册表信息,这个时间也是可以配置的

所以说,我们在新加入一个服务,可能调用的时候,不会立马感知到

这是因为 【ReadOnly缓存】 还没有同步最新的 注册表

心跳与故障

在服务注册之后

服务会定时向注册中心发送心跳( 可以配置时长,例如:30s)

会有一个线程定时去检查服务的心跳

如果发现某个服务在过去60秒 (这个也是可以配置的) 没有发送心跳

那么就认为这个服务挂了,会从【注册表】中把这个服务给删除

删除之后,会把 【ReadWrite缓存】 给清空

等到下一次 【ReadOnly缓存】 同步 【ReadWrite缓存】的时候,缓存中都是空的

等到服务再去 【ReadOnly缓存】 中获取 【注册表】 的时候,发现是空的,然后会继续往上找

【ReadOnly缓存】 >> 【ReadWrite缓存】 >> 【注册表】

Feign

如果你基于Spring Cloud对外发布一个接口,实际上就是支持http协议的,对外发布的就是一个最最普通的Spring MVC的http接口

feign它对一个接口打了一个注解,他一定会针对这个注解标注的接口生成动态代理

然后你针对feign的动态代理去调用他的方法的时候,此时会在底层生成http协议格式的请求,/order/create?productId=1

底层的话,使用HTTP通信的框架组件,HttpClient

先得使用Ribbon去从本地的Eureka注册表的缓存里获取出来对方机器的列表

然后进行负载均衡,选择一台机器出来,接着针对那台机器发送Http请求过去即可

zuul

配置一下不同的请求路径和服务的对应关系,你的请求到了网关,它直接查找到匹配的服务

然后就直接把请求转发给那个服务的某台机器

Ribbon从Eureka本地的缓存列表里获取一台机器,负载均衡,把请求直接用HTTP通信框架发送到指定机器上去

springcloud 分布式版限流 springcloud怎么实现分布式_负载均衡_02