go-resiliency
是一个为 Go 语言编写的库,提供了多种容错模式,包括重试(Retry)、熔断器(Circuit Breaker)、限流(Rate Limiter)等功能。以下是一个简单的使用示例,展示如何使用 go-resiliency
的熔断器功能。
go-resiliency
首先,需要安装 go-resiliency
包:
go get github.com/sony/gobreaker
以下是一个简单的 Go 程序,展示如何使用 go-resiliency
的熔断器功能来保护对外部服务的调用。
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/sony/gobreaker"
)
// 模拟一个可能失败的 HTTP 请求
func unreliableHTTPCall(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP request failed with status: %d", resp.StatusCode)
}
return "success", nil
}
func main() {
// 设置熔断器的配置
settings := gobreaker.Settings{
Name: "HTTPCallCircuitBreaker",
Timeout: 5 * time.Second, // 超时时间
ReadyToTrip: gobreaker.DefaultReadyToTrip, // 默认熔断条件
MaxRequests: 3, // 允许的最大失败请求数
Interval: 5 * time.Second, // 熔断后恢复的时间间隔
}
// 创建熔断器
circuitBreaker := gobreaker.NewCircuitBreaker(settings)
// 使用熔断器包装 HTTP 调用
callWithCircuitBreaker := circuitBreaker.Wrap(func() (string, error) {
return unreliableHTTPCall("http://example.com")
})
// 尝试调用
for i := 0; i < 10; i++ {
result, err := callWithCircuitBreaker()
if err != nil {
log.Printf("Call failed: %v", err)
} else {
log.Printf("Call succeeded: %s", result)
}
time.Sleep(1 * time.Second)
}
}
熔断器配置:
MaxRequests
:允许的最大失败请求数。当达到这个值时,熔断器会触发。Interval
:熔断器触发后,恢复的时间间隔。Timeout
:每个请求的超时时间。
包装函数:
circuitBreaker.Wrap
将原始的 HTTP 调用函数包装起来,这样每次调用都会通过熔断器进行控制。
调用逻辑:
http://example.com
)响应失败或超时,熔断器会阻止后续调用,直到恢复时间结束。
假设 http://example.com
有时会失败,程序的输出可能如下:
2025/03/14 12:00:00 Call failed: HTTP request failed with status: 500
2025/03/14 12:00:01 Call failed: HTTP request failed with status: 500
2025/03/14 12:00:02 Call failed: circuit breaker is open
2025/03/14 12:00:03 Call failed: circuit breaker is open
2025/03/14 12:00:04 Call failed: circuit breaker is open
2025/03/14 12:00:05 Call failed: circuit breaker is open
2025/03/14 12:00:06 Call succeeded: success
通过 go-resiliency
的熔断器功能,你可以有效地保护系统免受下游服务故障的影响,同时避免资源耗尽和系统崩溃。