zoukankan      html  css  js  c++  java
  • 23.熔断器学习,熔断器的三种状态,状态获取

    package main
    
    import (
        "fmt"
        "github.com/afex/hystrix-go/hystrix"
        "math/rand"
        "sync"
        "time"
    )
    
    type Product struct {
        ID    int
        Title string
        Price int
    }
    
    func getProduct() (Product, error) {
        r := rand.Intn(10)
        if r < 6 { //模拟api卡顿和超时效果
            time.Sleep(time.Second * 10)
        }
        return Product{
            ID:    101,
            Title: "Golang从入门到精通",
            Price: 12,
        }, nil
    }
    
    func RecProduct() (Product, error) {
        return Product{
            ID:    999,
            Title: "推荐商品",
            Price: 120,
        }, nil
    
    }
    
    func main() {
        rand.Seed(time.Now().UnixNano())
        configA := hystrix.CommandConfig{ //创建一个hystrix的config
            Timeout:                3000,                  //command运行超过3秒就会报超时错误,并且在一个统计窗口内处理的请求数量达到阈值会调用我们传入的降级回调函数
            MaxConcurrentRequests:  5,                     //控制最大并发数为5,并且在一个统计窗口内处理的请求数量达到阈值会调用我们传入的降级回调函数
            RequestVolumeThreshold: 5,                     //判断熔断的最少请求数,默认是5;只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行熔断与否的判断
            ErrorPercentThreshold:  5,                     //判断熔断的阈值,默认值5,表示在一个统计窗口内有50%的请求处理失败,比如有20个请求有10个以上失败了会触发熔断器短路直接熔断服务
            SleepWindow:            int(time.Second * 10), //熔断器短路多久以后开始尝试是否恢复,这里设置的是10
        }
        hystrix.ConfigureCommand("get_prod", configA) //hystrix绑定command
        c, _, _ := hystrix.GetCircuit("get_prod")     //返回值有三个,第一个是熔断器指针,第二个是bool表示是否能够取到,第三个是error
        resultChan := make(chan Product, 1)
    
        wg := &sync.WaitGroup{}
    
        for i := 0; i < 20; i++ {
            go func() {
                wg.Add(1)
                defer wg.Done()
                errs := hystrix.Do("get_prod", func() error { //使用hystrix来讲我们的操作封装成command,hystrix返回值是一个chan error
                    p, _ := getProduct() //这里会随机延迟0-4秒
                    fmt.Println("hello")
                    resultChan <- p
                    return nil //这里返回的error在回调中可以获取到,也就是下面的e变量
                }, func(e error) error {
                    fmt.Println("hello")
                    rcp, err := RecProduct() //推荐商品,如果这里的err不是nil,那么就会忘errs中写入这个err,下面的select就可以监控到
                    resultChan <- rcp
                    return err
                })
                if errs != nil { //这里errs是error接口,但是使用hystrix.Go异步执行时返回值是chan error各个协程的错误都放到errs中
                    fmt.Println(errs)
                } else {
                    select {
                    case prod := <-resultChan:
                        fmt.Println(prod)
                    }
                }
    
                fmt.Println(c.IsOpen())       //判断熔断器是否打开,一旦打开所有的请求都会走fallback
                fmt.Println(c.AllowRequest()) //判断是否允许请求服务,一旦打开
            }()
        }
        wg.Wait()
    }
    

    下面是输出,可以看到hello执行的次数明显没有200次,所有的输出加起来也只有89行,但是我们开了200个协程,也就是说熔断器直接熔断服务了,一部分请求直接被拒绝了,只有等待我们设置的10s后再把熔断器设置成半打开状态,再次执行根据结果判断熔断器应该设置成什么状态

    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    {999 推荐商品 120}
    true
    false
    hello
    hello
    hello
    hello
    {101 Golang从入门到精通 12}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    hello
    hello
    hello
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {101 Golang从入门到精通 12}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    hello
    hello
    hello
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    {999 推荐商品 120}
    true
    false
    




  • 相关阅读:
    程序员应该看的书籍列表
    完整版QQ(腾讯)开放平台操作指南(包含:qq登录能力获取等等)
    使用Electron构建跨平台的抓取桌面程序
    LinqHelper拓展
    20161014001 DataGridView 单元格内容 自动计算
    20161013001 DataGridView 数据转 DataTable
    20161011001 treeView 递归
    20160929001 Guid生成
    20160815001
    20160715001
  • 原文地址:https://www.cnblogs.com/hualou/p/12087946.html
Copyright © 2011-2022 走看看