From f45daec8f1e8dcca8315a8cc65558fe08b57f482 Mon Sep 17 00:00:00 2001 From: JACKYMYPERSON Date: Sat, 13 Sep 2025 20:00:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=86=94=E6=96=AD=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- init/hystrix/hystrix.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 init/hystrix/hystrix.go diff --git a/init/hystrix/hystrix.go b/init/hystrix/hystrix.go new file mode 100644 index 0000000..29c70a4 --- /dev/null +++ b/init/hystrix/hystrix.go @@ -0,0 +1,40 @@ +package hystrix + +import ( + "fmt" + "github.com/afex/hystrix-go/hystrix" + "github.com/gin-gonic/gin" + "net/http" +) + +func CircuitBreakerMiddleware(commandName string) gin.HandlerFunc { + // 配置熔断器规则 + hystrix.ConfigureCommand(commandName, hystrix.CommandConfig{ + Timeout: 5000, // 超时时间(毫秒) + MaxConcurrentRequests: 100, // 最大并发数 + RequestVolumeThreshold: 20, // 请求阈值(触发统计的最小请求数) + SleepWindow: 5000, // "打开"状态后多久进入"半开"(毫秒) + ErrorPercentThreshold: 50, // 错误率阈值(%) + }) + + return func(c *gin.Context) { + // 执行受保护的逻辑 + err := hystrix.Do(commandName, func() error { + c.Next() // 执行后续中间件和处理函数 + + // 通过状态码判断是否失败(例如5xx错误) + status := c.Writer.Status() + if status >= 500 { + return fmt.Errorf("upstream error: %d", status) + } + return nil + }, nil) + + // 如果熔断器触发(打开或超时) + if err != nil { + // 直接返回降级响应,不再调用后续处理链 + c.AbortWithStatusJSON(http.StatusServiceUnavailable, + gin.H{"message": "服务暂时不可用,请稍后重试", "error": err.Error()}) + } + } +}