• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go-kit微服务服务熔断(hystrix-go实现)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

go-kit 微服务 服务熔断(hystrix-go 实现)

  • 对客户端请求login方法添加熔断

Hystrix

  • 在微服务架构中,每个服务都是相互关联的,比如我们下单服务和扣钱服务是分开的,现在扣钱服务出现的bug不能正常服务
  • Hystrix可以让我们在在微服务架构中对服务间的调用进行控制,加入一些调用延迟或者服务降级的容错机制。

Hystrix的设计原则

  • 对依赖服务调用时出现的调用延迟和调用失败进行控制和容错保护
  • 在复杂的分布式系统中,阻止某一个依赖服务的故障在整个系统中蔓延
  • 提供fail-fast(快速失败)和快速恢复的支持
  • 提供fallback优雅降级的支持
  • 支持近实时的监控、报警以及运维操作

编写Hystrix类

import (
    "errors"
    "github.com/afex/hystrix-go/hystrix"
    "sync"
)

var config = hystrix.CommandConfig{
    Timeout:                5000, //执行command的超时时间(毫秒)
    MaxConcurrentRequests:  8,    //command的最大并发量
    SleepWindow:            1000, //过多长时间,熔断器再次检测是否开启。单位毫秒
    ErrorPercentThreshold:  30,   //错误率 请求数量大于等于RequestVolumeThreshold并且错误率到达这个百分比后就会启动
    RequestVolumeThreshold: 5,    //请求阈值(一个统计窗口10秒内请求数量)  熔断器是否打开首先要满足这个条件;这里的设置表示至少有5个请求才进行ErrorPercentThreshold错误百分比计算
}

type runFunc func() error

type Hystrix struct {
    loadMap  *sync.Map //储存每个调用函数对应的 Hystrix
    fallback string   //降级信息
}

func NewHystrix(msg string) *Hystrix {
    return &Hystrix{
        loadMap:  new(sync.Map),
        fallback: msg,
    }
}

func (s *Hystrix) Run(name string, run runFunc) error {
    if _, ok := s.loadMap.Load(name); !ok {
        hystrix.ConfigureCommand(name, config)
        s.loadMap.Store(name, name)
    }
    //name 为执行的命令名称
    //run  我们要执行的函数
    //fallback:run运行过程中发生错误时的回调方法
    err := hystrix.Do(name, func() error {
        return run()
    }, func(err error) error {
        //fmt.Println("运行 run 方法错误", err)
        return errors.New(s.fallback)
    })
    if err != nil {
        return err
    }
    return nil
}

添加Hystrix到调用客户端

  • 这里为了展示Hystrix的状态去掉了一些日志信息
hy := utils.NewHystrix("调用错误服务降级")
cbs, _, _ := hystrix.GetCircuit("login")
for i := 0; i < 100; i++ {
    time.Sleep(time.Millisecond * 100)
    userAgent, err := client.UserAgentClient()
    if err != nil {
        t.Error(err)
        return
    }
err = hy.Run("login", func() error {
    _, err := userAgent.Login(context.Background(), &pb.Login{
        Account:  "hwholiday",
        Password: "123456",
    })
    if err != nil {
        return err
    }
        //fmt.Println(ack.Token)
        return nil
    })
fmt.Println("熔断器开启状态:", cbs.IsOpen(), "请求是否允许:", cbs.AllowRequest())
    if err != nil {
        t.Log(err)
    }
}

去掉服务端的请求限制功能

func NewEndPointServer(svc Service, limit *rate.Limiter) EndPointServer {
    var loginEndPoint endpoint.Endpoint
    {
        loginEndPoint = MakeLoginEndPoint(svc)
        //loginEndPoint = NewGolangRateAllowMiddleware(limit)(loginEndPoint)
    }
    return EndPointServer{LoginEndPoint: loginEndPoint}
}

模拟服务器错误功能

if in.Account != "hwholiday" || in.Password != "123456" {
    err = errors.New("用户信息错误")
    return
}
//模拟耗时
//rand.Seed(time.Now().UnixNano())
//sl := rand.Int31n(10-1) + 1
//time.Sleep(time.Duration(sl) * time.Millisecond * 100)
//模拟错误
if rand.Intn(10) > 3 {
    err = errors.New("服务器运行错误")
    return
}
ack = &pb.LoginAck{}

运行

  • 运行 TestNewUserAgentClient 方法 (调用Login接口100次)

     

熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
s.LoginEndPoint rpc error: code = Unknown desc = 服务器运行错误
s.LoginEndPoint rpc error: code = Unknown desc = 服务器运行错误
s.LoginEndPoint rpc error: code = Unknown desc = 服务器运行错误
s.LoginEndPoint rpc error: code = Unknown desc = 服务器运行错误 (previously: rpc error: code = Unknown desc = 服务器运行错误; rpc error: code = Unknown desc = 服务器运行错误)
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: true 请求是否允许: false
熔断器开启状态: false 请求是否允许: true
s.LoginEndPoint rpc error: code = Unknown desc = 服务器运行错误
熔断器开启状态: false 请求是否允许: true


## 结语
+ 我们可以看到Hystrix的状态从 打开 ->关闭 -> 打开
+ Hystrix的用法还有很多,这里只展示简单的使用,更加高级的功能欢迎大家一起讨论
+ 欢迎添加QQ一起讨论


### [完整代码地址](https://github.com/hwholiday/learning_tools/tree/master/go-kit/v8)


作者:hwholiday
链接:https://www.jianshu.com/p/15975197c2be
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go语言 - 函数/方法发布时间:2022-07-10
下一篇:
go语言入门(一)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap