轻松构建微服务之服务治理
微信公众号:内核小王子
关注可了解更多关于数据库,JVM内核相关的知识;
如果你有任何疑问也可以加我pigpdong[^1]
API网关
依据系统的运行情况,自动的进行流量调度,在无需人工干预的情况下,提升整个系统的稳定性,,让系统应对爆品等突发事件的时候,在依赖弹性计算进行扩容的时间窗口内避免底层资源被耗尽.
流量调度一般放在API网关里面做,所以API网关需要有以下特点,业务逻辑简单,能够支持在管理后台动态修改服务配置,性能要高可以抗住高流量.
所以服务治理最好也可以在api网关里做,服务熔断,以及负载均衡,流量控制等,当然API网关还应该把协议转换,请求安全校验的工作做掉.
上图为一个API网关架构图,一个总的gateway接入所有流量,然后分发给二级gateway,下面我们具体看下一个gateway应该做哪些事情
-
请求路由 调用端不在需要知道服务的具体地址,只需要将请求发给网关,由网关层进行转发
-
服务注册 由于服务调用统一交给网关进行转发,那么网关就需要知道所有服务提供方的实例地址,所有服务提供方,需要将信息注册给网关,或者网关从注册中心获取后进行缓存.
-
负载均衡 网关层可以实现在多个服务实例之间进行负载均衡,例如round robin或者设置权重
-
安全管理 用户的鉴权统一防治gateway做,以及对用户恶意攻击的防范.
-
流量控制 在监控到某个服务可能过载后可以对该服务进行熔断设计,避免该服务拖垮其他服务,也包括一些重试,限流等
-
灰度发布 由于网关层可以做服务的管理功能,那么就可以在网关层实现灰度发布,对不同版本的服务导入不同的流量
-
API聚合 可以在网关层将多个单一的微服务进行简单的聚合,将各个微服务的返回结果进行聚合,这样就可以避免用户端和服务端频繁的业务调用,如果有复杂的业务逻辑建议还是放在底层服务实现.
-
应用监控 网关层由于是所有微服务调用链路的起点,可以展示分布式链路追踪的分析统计结果,提供每个服务的吞吐量,响应时间,返回码的性能统计报表
-
弹力设计 网关层因为要接入大量流量,所以自身应该高可用,所以自身能够进行熔断和自动扩容等机制
降级
降级我们一般有以下方案
-
停止次要服务 当系统监控到某个服务不可用,或者即将突破能够抗住的压力,可以将该服务停掉,不在请求该服务,或者直接返回一个通用的code
-
降低一致性要求 当大量流量进入的时候,我们可以通过异步的方式处理请求,异步可能无法保证业务的强一致性,但是如果我们可以接受最终一致性可以采用这种方案,另外就是使用缓存,缓存可能和底层数据不一致,但是底层需要能够处理或规避这种风险
-
简化功能 正常情况下一个页面可能需要返回大量的信息,那么在降级后可以只返回必要的信息,那么其他不必要信息对应的服务就可以不用调用了
熔断
当某个服务不可用后,而调用方的请求还在不停的重试,导致浪费CPU并且等待超时,降低系统的QPS,而熔断器模式可以检测到系统不可用后不在调用该服务,继续执行其他流程,熔断器需要能够记录服务单位时间或者最近服务调用失败的次数,并且可以支持配置当到达某一个量化的阈值后就进行熔断,同时支持当服务恢复后可以自动解除熔断限制.
目前Netfix的Hystrix已经停止维护,开源实现我们可以借鉴阿里的sentinel
限流
当某个服务在达到可以支持的请求阈值后,而服务调用方还在不停的发起,我们可以对该服务进行限流,例如拒绝新来的请求,或者返回一个通用的返回码,也可以对服务进行降级,减少返回的信息,只返回核心数据等.也有一些业务在监控到某些服务达到阈值后,将优先给有白名单的用户分配资源,而对其他的用户进行限流策略.或者延时处理.
限流目前有两种流行的算法
队列算法
按先进先出,将请求进行排队缓存,如果要支持VIP用户,也可以用优先级队列,这样白名单用户将会比普通用户早一点获取资源
漏桶算法
如图漏桶算法,将流入代表用户请求,而流出代表处理请求,漏桶需要设置一个桶的大小,就是容量,可以是一个队列,用来存放还没有处理的请求,而底下的桶洞控制请求处理的速度,当新的请求达到桶的容量后,就执行拒绝策略.所以在针对突发流量的情况下缺乏效率.
令牌桶算法
以一定的速率往桶里放入令牌,然后每个请求都需要从桶里拿出一个令牌,一个桶能保存的最大令牌数有限制,当请求速度太快就会导致桶里没有多余的令牌,那么就会将请求进行拒绝策略,如果请求太少就会导致桶里令牌装满溢出,所以令牌桶有一定的在突发流量情况下可以支持继续处理请求.