golang实现服务熔断机制的Circuit Breaker插件库circuitbreaker的使用
golang实现服务熔断机制的Circuit Breaker插件库circuitbreaker的使用
Circuitbreaker提供了一个简单的方式在Go程序中使用熔断器模式。熔断器通常用于程序进行远程调用时,当远程调用失败或超时达到一定阈值时,熔断器会"跳闸"阻止后续调用,避免系统资源被耗尽。
安装
go get github.com/rubyist/circuitbreaker
使用示例
基本使用示例
// 创建一个在10次失败后会跳闸的熔断器
cb := circuit.NewThresholdBreaker(10)
// 订阅熔断器事件
events := cb.Subscribe()
go func() {
for {
e := <-events
// 监控熔断器事件如BreakerTripped、BreakerReset、BreakerFail、BreakerReady
}
}()
// 使用熔断器包装远程调用
cb.Call(func() error {
// 这里执行远程调用
// 如果失败,返回error
}, 0) // 0表示不使用超时
带超时的熔断器
// 创建一个在10次失败后会跳闸的熔断器,并设置5秒超时
cb := circuit.NewThresholdBreaker(10)
cb.Call(func() error {
// 这里执行远程调用
// 如果失败,返回error
}, time.Second * 5) // 5秒超时,超时算作失败
基于连续失败的熔断器
// 创建一个在10次连续失败后会跳闸的熔断器
cb := circuit.NewConsecutiveBreaker(10)
// 使用方式同上
基于错误率的熔断器
// 创建一个基于错误率的熔断器,当错误率达到95%且至少有100个样本时跳闸
cb := circuit.NewRateBreaker(0.95, 100)
// 使用方式同上
手动控制熔断器
cb := circuit.NewThresholdBreaker(10)
for {
if cb.Ready() {
// 熔断器未跳闸,继续执行
err := doSomething()
if err != nil {
cb.Fail() // 失败计数,达到10次会跳闸
continue
}
cb.Success()
} else {
// 熔断器处于跳闸状态
}
}
HTTP客户端包装
// 创建一个带5秒超时和10次失败阈值的HTTP客户端
// 传入nil会创建一个常规的http.Client,也可以传入自定义的http.Client
client := circuit.NewHTTPClient(time.Second * 5, 10, nil)
// 使用包装后的客户端
resp, err := client.Get("http://example.com/resource.json")
以上示例展示了circuitbreaker库的主要功能,可以根据实际需求选择合适的熔断策略来保护你的远程调用。
更多关于golang实现服务熔断机制的Circuit Breaker插件库circuitbreaker的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现服务熔断机制的Circuit Breaker插件库circuitbreaker的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 服务熔断机制:Circuit Breaker 使用指南
熔断器模式是微服务架构中重要的稳定性保障机制,可以有效防止服务雪崩效应。在 Go 生态中,circuitbreaker
是一个优秀的熔断器实现库。
安装 circuitbreaker
go get github.com/rubyist/circuitbreaker
基本使用示例
package main
import (
"fmt"
"time"
"github.com/rubyist/circuitbreaker"
)
func main() {
// 创建熔断器实例
cb := circuit.NewThresholdBreaker(3) // 3次失败后熔断
// 模拟服务调用
for i := 0; i < 10; i++ {
// 使用熔断器保护服务调用
err := cb.Call(func() error {
// 这里是实际的服务调用逻辑
if i < 5 {
return fmt.Errorf("模拟服务失败")
}
return nil
}, 1*time.Second) // 设置超时时间
if err != nil {
fmt.Printf("调用失败: %v, 熔断状态: %v\n", err, cb.State())
} else {
fmt.Printf("调用成功, 熔断状态: %v\n", cb.State())
}
time.Sleep(500 * time.Millisecond)
}
}
高级配置
func advancedExample() {
// 创建可配置的熔断器
cb := circuit.NewRateBreaker(0.5, 10) // 失败率50%以上触发,最少10次调用
// 自定义配置
cb = &circuit.Breaker{
ShouldTrip: circuit.ThresholdTripFunc(5), // 5次失败后熔断
WindowTime: 10 * time.Second, // 统计窗口时间
Timeout: 2 * time.Second, // 超时时间
ReadyToTrip: func(counts circuit.Counts) bool {
// 自定义熔断触发条件
return counts.ConsecFailures >= 3 ||
(counts.Total >= 10 && counts.FailRate() >= 0.6)
},
OnStateChange: func(oldState, newState circuit.State) {
// 状态变更回调
fmt.Printf("状态变更: %s -> %s\n", oldState, newState)
},
}
// 使用熔断器
for i := 0; i < 15; i++ {
err := cb.Call(func() error {
if i%3 == 0 { // 模拟1/3的失败率
return fmt.Errorf("服务错误")
}
return nil
}, 0) // 0表示使用熔断器默认超时
if err != nil {
fmt.Printf("调用失败: %v, 状态: %v, 统计: %+v\n",
err, cb.State(), cb.Counts())
} else {
fmt.Printf("调用成功, 状态: %v\n", cb.State())
}
time.Sleep(300 * time.Millisecond)
}
}
实际应用场景
package main
import (
"context"
"fmt"
"net/http"
"time"
"github.com/rubyist/circuitbreaker"
)
var cb = circuit.NewThresholdBreaker(3)
func protectedAPICall(url string) (string, error) {
var result string
err := cb.Call(func() error {
// 创建带超时的HTTP客户端
client := &http.Client{
Timeout: 2 * time.Second,
}
// 创建带超时的请求上下文
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("HTTP错误: %s", resp.Status)
}
// 处理响应...
result = "处理后的响应数据"
return nil
}, 0) // 0表示使用熔断器默认超时
return result, err
}
func main() {
for i := 0; i < 10; i++ {
res, err := protectedAPICall("https://example.com/api")
if err != nil {
fmt.Printf("API调用失败: %v (状态: %v)\n", err, cb.State())
} else {
fmt.Printf("API调用成功: %s (状态: %v)\n", res, cb.State())
}
time.Sleep(1 * time.Second)
}
}
最佳实践
- 合理设置熔断阈值:根据服务特点设置失败次数或失败率阈值
- 监控熔断状态:通过
State()
方法监控熔断器状态变化 - 设置合理的超时时间:防止长时间阻塞
- 熔断恢复策略:熔断器会自动尝试半开状态恢复,但可以自定义恢复逻辑
- 结合重试机制:可以与重试机制配合使用,但要注意重试次数和熔断阈值的协调
总结
circuitbreaker
库提供了简单而强大的熔断器实现,通过合理配置可以显著提高系统的稳定性。在实际应用中,应该根据服务特点和业务需求调整熔断策略,并结合监控系统实时跟踪熔断状态。