第3课_Go实现熔断降级限流
热度🔥:10 免费课程
授课语音
Go 实现熔断、限流、降级方案
在 Go 语言中,可以利用各种库或自定义实现熔断、限流和降级功能。以下是各功能的实现方案及示例代码,所有示例均包含详细中文注释。
1. 熔断
使用 go-resilience 或 Hystrix 等库来实现熔断机制。
示例代码
package main
import (
"errors"
"fmt"
"time"
"github.com/eapache/go-resiliency/circuitbreaker"
)
func main() {
// 创建一个熔断器,最大失败3次,超时时间为2秒
breaker := circuitbreaker.New(3, 2*time.Second)
for i := 0; i < 10; i++ {
err := breaker.Run(func() error {
// 模拟服务调用
return simulateService(i)
})
if err == circuitbreaker.ErrBreakerOpen {
// 熔断器打开,拒绝请求
fmt.Println("熔断器打开,直接拒绝请求")
} else if err != nil {
// 服务调用失败
fmt.Printf("服务调用失败: %v\n", err)
} else {
// 服务调用成功
fmt.Println("服务调用成功")
}
time.Sleep(500 * time.Millisecond)
}
}
func simulateService(request int) error {
if request%4 == 0 {
return errors.New("模拟服务调用失败")
}
return nil
}
2. 限流
使用 golang.org/x/time/rate 包实现令牌桶算法进行限流。
示例代码
package main
import (
"fmt"
"golang.org/x/time/rate"
"time"
)
func main() {
// 创建一个限流器,每秒生成1个令牌,最大存储1个令牌
limiter := rate.NewLimiter(1, 1)
for i := 0; i < 10; i++ {
if limiter.Allow() {
// 允许请求
fmt.Printf("第 %d 次请求成功\n", i+1)
} else {
// 拒绝请求
fmt.Printf("第 %d 次请求被限流\n", i+1)
}
time.Sleep(300 * time.Millisecond)
}
}
3. 降级
通过包装函数或中间件实现降级逻辑。当检测到某服务不可用时,返回默认结果。
示例代码
package main
import (
"errors"
"fmt"
"time"
)
func main() {
for i := 0; i < 10; i++ {
result, err := callWithFallback(func() (string, error) {
return simulateService(i)
}, func() string {
return "降级结果: 返回默认值"
})
if err != nil {
fmt.Printf("请求失败,执行降级逻辑: %v\n", result)
} else {
fmt.Printf("请求成功: %v\n", result)
}
time.Sleep(300 * time.Millisecond)
}
}
// 模拟服务调用
func simulateService(request int) (string, error) {
if request%3 == 0 {
return "", errors.New("服务调用失败")
}
return "服务返回正常数据", nil
}
// 带降级逻辑的函数
func callWithFallback(service func() (string, error), fallback func() string) (string, error) {
result, err := service()
if err != nil {
// 调用降级函数
return fallback(), err
}
return result, nil
}
总结
- 熔断:通过
go-resiliency/circuitbreaker
实现三态(Closed、Open、Half-Open)的熔断器。 - 限流:利用
golang.org/x/time/rate
的令牌桶算法实现对请求频率的限制。 - 降级:通过包装服务调用逻辑,加入降级处理逻辑(如返回默认值、静态页面等),提高服务的可用性。
以上方案可单独使用,也可结合在一起实现复杂的服务治理策略。