41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
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()})
|
||
}
|
||
}
|
||
}
|