微服务治理之如何优雅应对突发流量洪峰

为什么需要降载

微服务集群中,调用链路错综复杂,作为服务提供者需要有一种保护自己的机制,防止调用方无脑调用压垮自己,保证自身服务的高可用。

最常见的保护机制莫过于限流机制,使用限流器的前提是必须知道自身的能够处理的最大并发数,一般在上线前通过压测来得到最大并发数,而且日常请求过程中每个接口的限流参数都不一样,同时系统一直在不断的迭代其处理能力往往也会随之变化,每次上线前都需要进行压测然后调整限流参数变得非常繁琐。

那么有没有一种更加简洁的限流机制能实现最大限度的自我保护呢?

什么是自适应降载

自适应降载能非常智能的保护服务自身,根据服务自身的系统负载动态判断是否需要降载。

设计目标:

  1. 保证系统不被拖垮。

  2. 在系统稳定的前提下,保持系统的吞吐量。

那么关键就在于如何衡量服务自身的负载呢?

判断高负载主要取决于两个指标:

  1. cpu 是否过载。

  2. 最大并发数是否过载。

以上两点同时满足时则说明服务处于高负载状态,则进行自适应降载。

同时也应该注意高并发场景 cpu 负载、并发数往往波动比较大,从数据上我们称这种现象为毛刺,毛刺现象可能会导致系统一直在频繁的进行自动降载操作,所以我们一般获取一段时间内的指标均值来使指标更加平滑。实现上可以采用准确的记录一段时间内的指标然后直接计算平均值,但是需要占用一定的系统资源。

统计学上有一种算法:滑动平均(exponential moving average),可以用来估算变量的局部均值,使得变量的更新与历史一段时间的历史取值有关,无需记录所有的历史局部变量就可以实现平均值估算,非常节省宝贵的服务器资源。

滑动平均算法原理 参考这篇文章讲的非常清楚。

变量 V 在 t 时刻记为 Vt,θt 为变量 V 在 t 时刻的取值,即在不使用滑动平均模型时 Vt=θt,在使用滑动平均模型后,Vt 的更新公式如下:

Vt=β⋅Vt−1+(1−β)⋅θt

  • β = 0 时 Vt = θt

  • β = 0.9 时,大致相当于过去 10 个 θt 值的平均

  • β = 0.99 时,大致相当于过去 100 个 θt 值的平均

代码实现

接下来我们来看下 go-zero 自适应降载的代码实现。

core/load/adaptiveshedder.go

自适应降载接口定义:

// 回调函数
Promise interface {
    // 请求成功时回调此函数
    Pass()
    // 请求失败时回调此函数
    Fail()
}

// 降载接口定义
Shedder interface {
    // 降载检查
    // 1. 允许调用,需手动执行 Promise.accept()/reject()上报实际执行任务结构
    // 2. 拒绝调用,将会直接返回err:服务过载错误 ErrServiceOverloaded
    Allow() (Promise, error)
}

接口定义非常精简意味使用起来其实非常简单,对外暴露一个`Allow()(Promise,error)。

go-zero 使用示例:

业务中只需调该方法判断是否降载,如果被降载则直接结束流程,否则执行业务最后使用返回值 Promise 根据执行结果回调结果即可。

func UnarySheddingInterceptor(shedder load.Shedder, metrics *stat.Metrics) grpc.UnaryServerInterceptor {
    ensureSheddingStat()

    return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
        handler grpc.UnaryHandler) (val interface{}, err error) {
        sheddingStat
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明
为了估计任意时刻的排沙量及总排沙量,可以根据试验数据建立一个数学模型。常用的模型包括经验公式、统计模型和物理模型等。这里我们介绍一种简单的经验公式方法,即利用试验数据的变化趋势来拟合一条曲线,并根据曲线方程计算任意时刻的排沙量和总排沙量。 具体步骤如下: 1. 对试验数据进行可视化处理,可以使用Matlab等工具进行绘图,观察数据的变化趋势,找出可能存在的规律。 2. 根据观察结果,选择合适的函数形式对数据进行拟合。在这里,我们尝试使用二次函数来拟合试验数据。二次函数的一般形式为: f(x) = ax^2 + bx + c 其中,a、b、c是待求的系数。 3. 使用Matlab等工具对二次函数进行拟合,得到方程的系数。可以使用`polyfit`函数来实现。 ```matlab x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42]; y = [1800, 1900, 2100, 2200, 2300, 2400, 2500, 2600, 2650, 2700, 2720, 2650, 2600, 2500, 2300, 2200, 2000, 1850, 1820, 1800, 1750, 1500, 1000, 900, 32, 60, 75, 85, 90, 98, 100, 102, 108, 112, 115, 116, 118, 120, 118, 105, 80, 60, 50, 30, 26, 20, 8, 5]; p = polyfit(x, y, 2); ``` 4. 根据拟合结果得到的方程,即可估计任意时刻的排沙量和总排沙量。以总排沙量为例,可以使用方程的定积分来计算。在这里,我们将计算时间段从6月29日零时到7月10日零时的总排沙量(单位:亿吨)。 ```matlab a = p(1); b = p(2); c = p(3); t1 = 0; t2 = 12 * 24; % 时间段:12天 Q = 1 / 3 * a * (t2^3 - t1^3) + 1 / 2 * b * (t2^2 - t1^2) + c * (t2 - t1); Q = Q / 1e8; % 将单位换算为亿吨 ``` 这里的结果为Q=2.81亿吨,表示在这个时间段内小浪底水库的总排沙量约为2.81亿吨。同样的方法也可以用来估计任意时刻的排沙量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值