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, // 最大并发数,超过并发返回错误 RequestVolumeThreshol