ycgg的GO语言之路Day14——微服务框架(2)| 青训营笔记

21 阅读4分钟

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

03.核心服务治理功能

服务发布

指让一个服务升级运行新的代码的过程

为什么服务发布是一个问题呢?

因为通常企业都是在线服务,不好突然断开再更新,突然断开会导致服务不可用,会服务抖动,一部分流量消失,会有服务回滚

蓝绿部署

image-20230209122758713.png

先升级绿色部分,先关闭老的绿色,让流量都到蓝色实例,等更新完再用同样的操作更新蓝色

这种方式简单,稳定但需要两倍资源。

灰度发布(金丝雀发布)

为了防止新的实例有bug,会先添加一个新的实例去测试,再逐步添加下线实例。但是在发布实例时,随时可能会服务回滚一部分

image-20230209123038888.png

流量治理

在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端到端流量的流量控制

image-20230209123404207.png

第一个针对不同地区的流量分配

第二个可以针对运行版本和测试版本分流,运行班90,测试版10

第三个可以根据机器的性能分配

第四个根据请求类型,少量流量去特殊的功能

负载均衡

负责分配请求在每个下游实例上的分布。

image-20230209123706544.png

常见的LB策略:Round Robin,Random,Ring Hash,Least Request

稳定性治理

线上服务总是会出问题的,这与程序的正确性无关。

原因:网络攻击,流量突增,机房断电,光纤被挖,机器故障,网络故障,机房空调故障

微服务架构中典型的稳定性治理功能

限流:比如服务B中的rate limit组件,去控制流量

熔断:服务A发现服务B存在问题,可以拒绝请求吗,暂时断掉连接,等待B恢复,间断性试连B

过载保护:服务B的组件发现压力较大,比如CPU>99%,可以拒绝掉一部分请求

降级:服务B压力过大,请求太多,服务B会拒绝掉一部分请求,保证一些高级的请求可以运行

image-20230209124339764.png

04.字节跳动微服务治理实践

重试

本地函数

可能的异常:

  • 参数非法 OOM(Out Of Memory)
  • NPE(Null Pointer Exception)
  • 边界case
  • 系统崩溃死循环
  • 程序异常退出

重试的意义不大

远程函数

  • 团络抖动
  • 下游负载高导致超时下游机器宕机
  • 本地机器负载高,
  • 调度超时
  • 下游熔断、限流

有重试的意义,有可能下一次调用就会成功,可以大大降低因为偶然性失败的概率

image-20230209125351353.png

如图for循环3次重试

意义

降低错误率

假设单次请求的错误概率为0.01,那么连续两次错误概率则为0.0001。

降低长尾延时

对于偶尔耗时较长的请求,重试请求有机会提前返回。等太久不返回,重试一次可能迅速返回

容忍暂时性错误

某些时候系统会有暂时性异常(例如网络抖动》,重试可以尽量规避。

避开下游故障实例

一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。

难点

为什么重试好用却默认不用?

幂等性
重试风暴

image-20230209125730815.png

由于调用链路,可能导致没有bug的D若干次才能请求到

重试策略:

1.设定一个重试比例阈值(例如1%),重试次数占所有请求比例不超过该阈值。使某个时间窗口只能重试X次

image-20230209141005019.png

2.防止链路重试

链路层面的防重试风暴的核心是限制每层都发生重试.理想情况下只有最下一层发生重试。可以返回特殊的 status表明“请求失败,但别重试”。

image-20230209141114107.png

返回特殊的状态码,让上一层不重试

3.Hedged requests 对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应.这样可以极大的缩短服务延迟。

image-20230209141317829.png

超时设置

超时的时间不好统一设置,不可能适用所有场景

重试效果验证

image-20230209141454804.png

可以看到只有单纯的for循环,层数变多时,时间会大大增加