微服务组件之限流器与熔断器

本文深入探讨了微服务架构中常见的服务延迟和通信失败问题,介绍了解决方案——限流器与熔断器。限流器用于在流量突增时保护后端服务,避免过载;熔断器则在依赖服务故障时切断连接,防止雪崩效应。文章详细解释了这两种组件的工作原理和使用方法。

在微服务架构里面一个很常见的问题就是服务之间的延迟和通信失败问题,极端的情况下,甚至会因为某个服务的性能下降或者故障宕机,导致访问超时,层层传递,引发雪崩,最终导致整个系统崩溃,而限流器和熔断器(这两个组件都是客户端的)能很好的解决这个问题,提高系统的可靠性和稳定性

限流器

限流器,从字面上理解就是用来限制流量,有时候流量突增(可预期的比如“双11”,不可预期的微博的热门话题等),会将后端服务压垮,甚至直接宕机,使用限流器能限制访问后端的流量,起到一个保护作用,被限制的流量,可以根据具体的业务逻辑去处理,直接返回错误或者返回默认值等等

golang 提供了拓展库(golang.org/x/time/rate)提供了限流器组件,用法上也很简单直观,通过下面这段代码就可以创建一个限流器。

// 每 800ms 产生 1 个 token,最多缓存 1 个 token,如果缓存满了,新的 token 会被丢弃
limiter := rate.NewLimiter(rate.Every(time.Duration(800)*time.Millisecond), 1)

限流器提供三种使用方式,Allow,Wait, Reserve

Allow: 返回是否有 token,没有 token 返回 false,或者消耗 1 个 token 返回 true
Wait: 阻塞等待,知道取到 1 个 token
Reserve: 返回 token 信息,Allow 其实相当于 Reserve().OK,此外还会返回需要等待多久才有新的 token

一般使用 Wait 的场景会比较多一些

if err := limiter.Wait(context.Background()); err != nil {
    panic(err)
}
// do you business logic

熔断器

和限流器对依赖服务的保护机制不一样,熔断器是当依赖的服务已经出现故障时,为了保证自身服务的正常运行不再访问依赖的服务,防止雪崩效应

熔断器有三种状态:

关闭状态:服务正常,并维护一个失败率统计,当失败率达到阀值时,转到开启状态
开启状态:服务异常,调用 fallback 函数,一段时间之后,进入半开启状态
半开启装态:尝试恢复服务,失败率高于阀值,进入开启状态,低于阀值,进入关闭状态
github.com/afex/hystrix-go,提供了 go 熔断器实现,使用上面也很方便,首先创建一个熔断器

hystrix.ConfigureCommand(
    "addservice", // 熔断器名字,可以用服务名称命名,一个名字对应一个熔断器,对应一份熔断策略
    hystrix.CommandConfig{
        Timeout:                100,  // 超时时间 100ms
        MaxConcurrentRequests:  2,    // 最大并发数,超过并发返回错误
        RequestVolumeThreshold: 4,    // 请求数量的阀值,用这些数量的请求来计算阀值
        ErrorPercentThreshold:  25,   // 错误率阀值,达到阀值,启动熔断,25%
        SleepWindow:            1000, // 熔断尝试恢复时间,1000ms
    },
)

提供了阻塞和非阻塞两种使用方式,完整代码可以参考如下链接: https://github.com/hatlonely/hellogolang/blob/master/sample/addservice/cmd/client/main.go

阻塞使用 Do 方法,返回一个 err

errc1 := hystrix.Go("addservice", func() error {
    var err error
    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
    defer cancel()
    res1, err = client.Add(ctx, req)
    if err == nil {
        success <- struct{}{}
    }
    return err
}, nil)
// 有 fallback 处理
errc2 := hystrix.Go("addservice", func() error {
    var err error
    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
    defer cancel()
    res2, err = client.Add(ctx, req)
    if err == nil {
        success <- struct{}{}
    }
    return err
}, func(err error) error {
    fmt.Println(err)
    res2 = &addservice.AddResponse{V: req.A + req.B}
    success <- struct{}{}
    return nil
})
for i := 0; i < 2; i++ {
    select {
    case <-success:
        fmt.Println("success", i)
    case err := <-errc1:
        fmt.Println("err1:", err)
    case err := <-errc2:
        // 这个分支永远不会走到,因为熔断机制里面永远不会返回错误
        fmt.Println("err2:", err)
    }
}

参考链接

测试代码: https://github.com/hatlonely/hellogolang/blob/master/sample/addservice/cmd/client/main.go
Circuit Breaker Pattern: https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589784(v%3dpandp.10)
hystrix-go: https://github.com/afex/hystrix-go/

转载请注明出处
本文链接:http://www.hatlonely.com/2018/06/21/微服务组件之限流器与熔断器/

第 19 期Python实战班正在火热招生中
第 8 期自动化运维班正在招生中
第4期golang正在招生中

详情扫码咨询

微服务组件之限流器与熔断器

免费视频 戳戳戳!

转载于:https://blog.51cto.com/51reboot/2149524

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值