Go使用Hystrix限流、熔断。。。

普通版本

package main
 
import (
    "fmt"
    "github.com/afex/hystrix-go/hystrix"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)
 
func helloHandler(c *gin.Context) {
    // 执行你的业务逻辑
    c.String(http.StatusOK, "Hello from Hystrix!")
}
 
func main() {
    r := gin.Default()
 
    // 使用Hystrix包装你的处理函数
    hystrix.ConfigureCommand("my_command", hystrix.CommandConfig{
		Timeout:                1000, // 单次请求 超时时间(ms)
		MaxConcurrentRequests:  1,    // 最大并发量,限流(基于token令牌,使用完会放回)
		SleepWindow:            5000, // 熔断后多久去尝试服务是否可用(ms)
		RequestVolumeThreshold: 1,    // 熔断器在评估跳闸前,需要至少统计的请求数
		ErrorPercentThreshold:  1,    // 验证熔断的 错误百分比
	})
 
    r.GET("/hello", func(c *gin.Context) {
        // 执行Hystrix命令
        err := hystrix.Do("my_command", func() error {
            helloHandler(c)
            return nil
        }, func(err error) error {
            // 回退函数,当断路器打开时执行
            c.String(http.StatusOK, "限流了。。。")
            return nil
        })
 
        if err != nil {
            c.Status(http.StatusInternalServerError)
            fmt.Println("Hystrix error:", err)
        }
    })
 
    r.Run(":8080")
}

中间件版本

package main

import (
    "github.com/afex/hystrix-go/hystrix"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

// HystrixMiddleware 是一个 Gin 中间件,用于包装 Hystrix 命令。
func HystrixMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 配置 Hystrix 命令
        hystrix.ConfigureCommand("my_command", hystrix.CommandConfig{
            Timeout:                3000, // 3 seconds
            MaxConcurrentRequests:  10,
            SleepWindow:            2000, // 2 seconds
            ErrorPercentThreshold:  25,
        })

        // 创建一个 Hystrix 执行器
        var hystrixErr error
        hystrix.Do(commandName, func() error {
            // 在这里调用你的业务逻辑处理器
            c.Next() // 执行后续的中间件或最终的处理器
            return nil
        }, func(err error) error {
            // 熔断器打开时的回退逻辑
            hystrixErr = err
            c.JSON(http.StatusOK, gin.H{ "error": "circuit breaker is open or command failed"}
            })
            return nil
        })

        // 如果 Hystrix 执行出错,则设置响应状态码
        if hystrixErr != nil {
            c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "hystrix error"})
        }
    }
}

func helloHandler(c *gin.Context) {
    c.String(http.StatusOK, "Hello from Hystrix!")
}

func main() {
    r := gin.Default()

    // 使用 Hystrix 中间件包装特定的路由
    r.Use(HystrixMiddleware())

    r.GET("/hello", helloHandler)

    r.Run(":8080")
}
posted @ 2024-06-18 14:06  朝阳1  阅读(81)  评论(0)    收藏  举报