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()}) + } + } +}