微服务架构下的服务治理 | 青训营笔记

112 阅读5分钟

这是我参与「第五届青训营」伴学笔记创作活动的第6天

服务治理

服务发布

服务发布,也就是我们运行一段新的代码,从而启动该服务的过程

那么就一定会遇到以下某些问题

  • 旧代码还在运行,新代码把旧的替换掉,这时就会出现短暂的服务不可用
  • 新代码运行时发生异常
  • 部分请求到旧代码中的请求会消失,也就是说这一部分流量损失了,发生了服务抖动问题

以上的问题在实际场景中都是不应该发生的,会造成极大的影响,比如抖音如果故障了一两分钟就有可能上热搜

所以我们就需要某种方案去避免这些问题的发生

蓝绿部署

原理:在发布时将服务分为两个集群,在进行服务发布的时候,先关掉其中一半的流量(使请求落到另一半上),然后再对这一半进行服务发布,然后再对另一半对同样的操作

优点: 简单、稳定

缺点: 需要两倍的资源,也就是说在服务发布时会减少一半的流量

适用场景:适合在流量较低的时候使用(应用每天的流量会有高峰期和低峰期,选择低峰期进行发布)

蓝绿部署

灰度发布(金丝雀发布)

这个方案的名字出自于一个经典故事

金丝雀对瓦斯及其敏感,在17世纪时,英国矿工在下井之前会往井里面放入一只金丝雀,从而确保矿井中没有瓦斯

原理:既然我们的新代码有可能会造成异常,那么我们就不要先将其进行大量发布,只需要先发布一个实例观察有无异常,无异常则追加发布另一个实例,以此类推直到所有实例都发布完毕

image-20230203233214202

该方案的原理看起来非常简单,那为什么还需要蓝绿部署呢?

原因在于,我们需要对一个一个实例依次更新,那这里就会有难点,我们需要精准地控制流量不会到达正在更新的实例

同时,如果我们对99%的实例都发布完毕,但是最后1%的实例却出现严重的bug,这时候就需要将99%已经更新完的实例进行回滚,这里的回滚也是一个比较困难的点,需要一个平台的支撑

所以说,该方案对于基础设施的要求是比较高的

稳定性治理

在线上服务中总是会出现问题的,尽管我们的程序有多正确,总会有各种程序外的原因导致错误发生

比如说 网络攻击、流量突增、机房断电、光纤被挖了、网络故障、机器故障、机房温度过高等诸多问题

限流

我们的服务能够并发处理的请求量会有一个上限,当超过了这个上限,就会导致处理的效率下降(抖动现象)

所以我们要限制好请求的数量,不让服务承受过多的请求

三种常见方案:

  • 拒绝服务
  • 排队等待
  • 服务降级

限流

熔断

在微服务架构中,一个服务可能会间接牵连着上百个服务,这时候,如果某个服务出现了异常而导致请求出现大量超时,就会阻塞很多其他服务的运行,从而导致整个微服务的崩盘(雪崩效应)

这时候我们就需要一种叫做“熔断”的技术,将该服务隔离起来,对该服务的调用执行熔断,使得后续的请求都不再调用该服务。

在经过一段时间后,再将熔断设置为“半开”状态,也就是放开少量的请求到该服务中,如果正常响应了则解除熔断,否则继续熔断。

熔断

过载保护

思想和限流相似,但该方案中则没有设置一个明确的请求量限制,而是观察服务的CPU利用率,当过高时就表示已经超载,这时候就会拒绝大部分的请求,从而达到一个保护的效果

过载保护

降级

服务器的资源是有限的,而用户的请求是无限的,当请求到达一定数量的时候,也就是说在用户并发高峰期时,会影响整体的服务性能。

服务会分为核心功能服务以及相对而言较普通的服务,而为了保证核心功能服务的稳定性和可用性,就需要一种“舍小保大”的策略,根据我们预定的策略,舍弃一些非核心接口的请求(保证核心功能服务的运行),而直接返回提前准备好的兜底处理信息。

服务降级

请求重试(重点在于网络请求)

重试的意义

image-20230204203941738

重试的缺点

幂等性

请求重试的前提是,我们的接口需要是确保幂等性的,即同样的请求,多次请求所造成的结果和影响是一致的

若是接口不幂等,多次请求就有可能会造成数据不一致的问题

重试风暴

尽管我们通常会设置一个静态的重试次数上限,但随着调用链路深度的增加,重试的次数会随之指数级地增长,会消耗较多的网络资源

所以我们需要重试策略,来避免重试风暴的发生

限制重试比例

设置一个重试比例阈值,只有当大部分的请求,失败次数不超过这个阈值时才允许重试,这样就可以大量地减少重试次数

防止链路重试

重试风暴的核心起因就在于链路中错误节点前的每个节点都需要进行重试

所以该方案的核心在于 限制每一层不会发生重试,理想的情况下最下一层才会发生重试

Hedged requests

对于可能超时的请求,重新向另一个下游实例发送一个相同的请求,等待先到达的响应