微服务架构介绍2

文章介绍了微服务架构中的服务治理,包括蓝绿部署和灰度发布的概念与实施步骤,强调了流量治理和负载均衡的重要性。此外,文章详细讨论了重试在远程调用中的意义、难点以及相应的重试策略,包括限制重试比例和使用hedgedrequests。最后,提到了重试效果的验证方法。
摘要由CSDN通过智能技术生成

前言: \textcolor{Green}{前言:} 前言:

💞这个专栏就专门来记录一下寒假参加的第五期字节跳动训练营
💞从这个专栏里面可以迅速获得Go的知识

3 核心服务治理功能

3.1 服务发布

服务发布(deployment),即指让一个服务升级运行新的代码的过程。

服务发布的难点:

在这里插入图片描述

蓝绿部署

(1)需要准备两个相同的应用运行环境,命名为蓝色环境、绿色环境,刚开始,蓝色环境和绿色环境都运行着相同的应用版本,只有绿色环境对外提供服务。

(2)开发了一个新版本,那么放到蓝色环境上进行反复的测试、修改、验证,确定达到上线标准后,利用负载均衡器/反向代理/路由等手段将对外服务切换为蓝色环境。

(3)一段时间后,如果发生故障,那么迅速切换回绿色环境;如果运行没有异常,那么绿色环境更新版本到,版本再次一致。

(4)当需要开发下一个版本,重复前面的步骤,蓝色绿色相互切换相互备份。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
再次同样的步骤
在这里插入图片描述
在这里插入图片描述
蓝绿部署非常的简单、稳定。但是需要双倍的资源
在这里插入图片描述

灰度发布(金丝雀发布)

金丝雀(canary)对瓦斯极其敏感,17世纪时,英国矿工在下井前会先放入一只金丝雀,以确保矿井中没有瓦斯

回滚难度大,基础设施要求高

3.2 流量治理

在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端到端流量的路由路径进行精确控制。
在这里插入图片描述
用了多种分类进行区分。

这里指的是侠义的对流量进行控制

3.3 负载均衡

负载均衡(Load Balance)负责分配请求在每个下游实例上的分布

常见的 LB 策略

  • Round Robin
  • Random
  • Ring Hash
  • Least Request

  • 在这里插入图片描述

在这里插入图片描述
一个服务中,通常每个实例的负载应是大体均衡一致的。

3.4 稳定性治理

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

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

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

  • 限流
  • 熔断
  • 过载保护
  • 降级
    在这里插入图片描述

4. 字节跳动服务治理实践

4.1 重试的意义

本地函数调用

func LocalFunc(x int) int {
    res := calculate(x - 2)
    return res
}

此时我们因本地函数嗲用发现

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

需要明白:本地函数调用没有重试的意义

远程函数调用

fun RemoteFunc(ctx context.Context, x int) (int, error) {
    ctx2, defer_func := context.WithTimeout(ctx, time.Second)
    defer defer_func()
    res, err := grpc_client.Calculate(ctx2, x - 2)
    return res, err
}

远程调用会的异常:

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

重试可以避免偶发的错误,提高SLA(Service-Level Agreement)

fun RemoteFunc(ctx context.Context, x int) (int, error) {
    ctx2, defer_func := context.WithTimeout(ctx, time.Second)
    defer defer_func()
    res, err := grpc_client.Calculate(ctx2, x - 2)
    return res, err
}

fun RemoteFuncRetry(ctx context.Context, x int) (res int, err error) {
    for i := 0; i < 3; i++ {
        if res, err = RemoteFunc(ctx, x); err == nil {
            return
        }
    }
    return
}

此时我们就知道重试的意义

  • 降低错误率
    • 假设单次请求的错误概率为 0.01,那么连续两次错误概率为 0.0001。
  • 降低长尾延时
    • 对于偶尔耗时较长的请求,重试请求有机会提前返回。
  • 容忍暂时性错误
    • 某些时候系统会有暂时性异常(例如网络抖动),重试可以尽量规避。
  • 避开下游故障实例
    • 一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。

4.2 重试的难点

既然重试的好处有很多,为什么默认不用呢?

这是因为:

  • 幂等性:多次请求可能导致数据不一致
  • 重试风暴:随着调用深度的增加,重试次数会指数级上涨
  • 超时设置:假设一个调用正常是 1s 的超时时间,如果允许一次重试。有个问题:如果第一次请求经过多少时间时,才开始重试呢?

重试风暴
在这里插入图片描述

4.3 重试策略

重试只有在大部分请求都成功,只有少量请求失败时,才有必要。如果大部分请求都失败,重试只会增加问题严重性。

  1. 限制重试比例
    设定一个重试比例阈值(例如 1%)。重试次数占所有请求比例不超过该阈值
    在这里插入图片描述

  2. 防止链路重试
    链路层面的防重试风暴的核心是限制每层都发生重试,理想情况下只有最下一层发生重试。可以返回特殊的 status 表明:“请求失败,但别重试”
    在这里插入图片描述
    缺点:对业务代码有侵入性

  3. Hedged requests
    对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应。
    在这里插入图片描述

4.4 重试效果验证

实际验证经过上述重试策略后,在链路上发生的重试放大效应。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦 羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值