这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
03.核心服务治理功能
服务发布
指让一个服务升级运行新的代码的过程
为什么服务发布是一个问题呢?
因为通常企业都是在线服务,不好突然断开再更新,突然断开会导致服务不可用,会服务抖动,一部分流量消失,会有服务回滚
蓝绿部署
先升级绿色部分,先关闭老的绿色,让流量都到蓝色实例,等更新完再用同样的操作更新蓝色
这种方式简单,稳定但需要两倍资源。
灰度发布(金丝雀发布)
为了防止新的实例有bug,会先添加一个新的实例去测试,再逐步添加下线实例。但是在发布实例时,随时可能会服务回滚一部分
流量治理
在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端到端流量的流量控制
第一个针对不同地区的流量分配
第二个可以针对运行版本和测试版本分流,运行班90,测试版10
第三个可以根据机器的性能分配
第四个根据请求类型,少量流量去特殊的功能
负载均衡
负责分配请求在每个下游实例上的分布。
常见的LB策略:Round Robin,Random,Ring Hash,Least Request
稳定性治理
线上服务总是会出问题的,这与程序的正确性无关。
原因:网络攻击,流量突增,机房断电,光纤被挖,机器故障,网络故障,机房空调故障
微服务架构中典型的稳定性治理功能
限流:比如服务B中的rate limit组件,去控制流量
熔断:服务A发现服务B存在问题,可以拒绝请求吗,暂时断掉连接,等待B恢复,间断性试连B
过载保护:服务B的组件发现压力较大,比如CPU>99%,可以拒绝掉一部分请求
降级:服务B压力过大,请求太多,服务B会拒绝掉一部分请求,保证一些高级的请求可以运行
04.字节跳动微服务治理实践
重试
本地函数
可能的异常:
- 参数非法 OOM(Out Of Memory)
- NPE(Null Pointer Exception)
- 边界case
- 系统崩溃死循环
- 程序异常退出
重试的意义不大
远程函数
- 团络抖动
- 下游负载高导致超时下游机器宕机
- 本地机器负载高,
- 调度超时
- 下游熔断、限流
有重试的意义,有可能下一次调用就会成功,可以大大降低因为偶然性失败的概率
如图for循环3次重试
意义
降低错误率
假设单次请求的错误概率为0.01,那么连续两次错误概率则为0.0001。
降低长尾延时
对于偶尔耗时较长的请求,重试请求有机会提前返回。等太久不返回,重试一次可能迅速返回
容忍暂时性错误
某些时候系统会有暂时性异常(例如网络抖动》,重试可以尽量规避。
避开下游故障实例
一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。
难点
为什么重试好用却默认不用?
幂等性
重试风暴
由于调用链路,可能导致没有bug的D若干次才能请求到
重试策略:
1.设定一个重试比例阈值(例如1%),重试次数占所有请求比例不超过该阈值。使某个时间窗口只能重试X次
2.防止链路重试
链路层面的防重试风暴的核心是限制每层都发生重试.理想情况下只有最下一层发生重试。可以返回特殊的 status表明“请求失败,但别重试”。
返回特殊的状态码,让上一层不重试
3.Hedged requests 对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应.这样可以极大的缩短服务延迟。
超时设置
超时的时间不好统一设置,不可能适用所有场景
重试效果验证
可以看到只有单纯的for循环,层数变多时,时间会大大增加