微服务里面的限流 (uber/limit)概述
- go 微服务保稳三剑客: 熔断,限流,负载均衡
- 限流的作用
- 限制流量,在服务端生效
- 注意:熔断是客户端生效
- 保护后端服务
- 餐厅吃饭排队的问题,提供凳子,让等候,这就是限流操作
- 如果不限流,每个客户都吃不上饭
- 与熔断互补
- 限制流量,在服务端生效
限流的原理
- 限流用到漏桶算法
左侧
- 水龙头进水快,但是下面漏孔出水是匀速的
- 当请求量非常大的时候,相当于进水非常大
- 出水的孔的水滴是没有进水的流量大
- 所以这里,会有这样一个储蓄桶
- 不管水流有多大,出水的频率是固定的
- 保护了我们服务端处理的频率是固定的
- 这样就起到了对服务端进行保护的作用
- 这样就起到了一个缓冲的作用
右侧
- 右边是一种抽象,当客户端请求的时候
- 服务端接入请求,当我未限流的时候,都接到桶子里面
- 这个桶子就是进行流量控制,可以进行限流处理
- 被限流完,满足我们的算法请求
- 在限流里面,主要是这样一个漏桶算法
- 还有一个 令牌桶算法 是另一个层面的,这里不做详细说明
负载均衡概述
- go 微服务保稳三剑客: 熔断,限流,负载均衡
- 负载均衡的作用
- 提高系统可扩展性
- 如果漏桶算法中的处理速度存在瓶颈不满足需求,我们就要通过负载均衡来弥补
- 如果客户端请求,服务端压力比较大的时候,也可以用负载均衡
- 支持 HTTP, HTTPS, TCP, UDP 请求
- 主要算法:循环算法和随机算法,默认随机算法
- 负载均衡可以做在服务端,也可以做在客户端
- 主要演示,客户端调用负载均衡的算法
- 提高系统可扩展性
2 )均衡架构
- 当一个正常的api请求过来之后
- 这个 API 会再一个 Server上进行处理
- 当 Server A 压力特别大的时候,就会用到负载均衡
- 会把 Server A 横向扩展成 Server A1, Server A2, Server A3
- 当我们调用 API 的时候,因为随机算法,可能会访问到这3台机器的任意一台
- 这样,把系统横向扩展,提高了服务端的处理能力,这样 A1 压力就会少 2/3
- 我们的负载均衡主要是写在客户端这块, 也就是微服务的调用方
- 也就是说这里的 Server A1 等服务器会调用其他微服务
API 网关与三层架构设计
- 引入了api网关,势必影响微服务的架构,总体架构如下
- 通过正常的方式请求一个api的时候,比如 CartApi/FindAll
- 它会通过网关,根据网关的规则,找到 go.micro.api.cartapi CartApi.FindAll
- 它会访问 Cart Api 服务,基于这个服务,再去请求后端基础服务
- 这里引入API网关之后,请求和原来使用是一样的
- 暴露出API是对外提供使用的,并对基础服务进行简单的聚合
- 这样把架构分了3层,API网关层,API层,基础服务层
- 着重看下这三层的作用
- 第一层 Micro API 网关,通过 go micro api 网关进行暴露的
- 前端可以通过统一的网关地址,请求提供的接口
- 所以地址不会变,后面路由转发到提供的接口上去
- 这一块不需要我们开发,只要启动 micro api 就可以作为客户端的代理进行后端的请求
- 第二层 聚合业务层,就是我们暴露出去的api, 我们实现业务的聚合,通过 聚合业务层 把基于基础服务查询到的数据
- 通过业务逻辑代码组装起来,返回到请求上去
- 这样分层设计的好处:可以有效复用代码,越基础的代码,越稳定,复用率越高,确保底层服务职责单一,并且提高扩展性
- 越是底层的,就需要再业务上进行稳定,不需要经常修改,越是表层的东西根据业务逻辑的不同,而经常调整
- 这样,可以提高扩展性,聚合底层服务,满足业务需求
- 第三层 基础服务层,基础服务层就是之前代码中的 service, 处理最底层的业务逻辑,保证服务的单一职责
- 这个就是引入网关之后,整体架构带来的影响
- 在基础服务层的基础上,来开发聚合业务层,告诉我们聚合业务层api如何去开发
- 以及在聚合业务层,如何去跟 api 网关进行关联
微服务之API 网关 与 gin 框架
- 在标准三层架构中,通过网关请求 /greeter/say/hello, 这个路径网关会将请求转发到
- go.micro.api.greeter 服务的 Say.Hello方法处理
- 这里 go.micro.api 是网关默认服务名的前缀
- 路径中 /cartApi/cartApi/findAll 也可以写成 /cartApi/findAll
- 注意,go-micro的版本更新较为频繁,很多旧版的api都会升级,进而不适用新版go环境
- 在使用的时候,可以看官网对应的版本来看,go-micro 默认提供网关功能
- 在不使用三层架构的场景下,也可以不这么做,在一般业务开发中
- 我会倾向选择一个更具有开发效率的框架代替 go micro 生成的一些模板来开发API网关
- 比如 gin 或 beego框架,在某个特定的路由里面去组织和调用
- 其实,比如在 gin 框架中,使用路由定义不同的访问路径,这个就充当第一层,即网关的功能
- 在gin框架相关路由对应的控制器处理中作为第二层,聚合业务层
- 在对应控制器中调用的远程微服务,远程微服务就作为第三层基础服务层
- 这种不是标准的三层架构,个人认为只要设计耦合性比较低,并且便于管理即可