前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang 微服务中的断路器 hystrix 小案例

golang 微服务中的断路器 hystrix 小案例

作者头像
阿兵云原生
发布2023-09-01 08:36:02
1630
发布2023-09-01 08:36:02
举报
文章被收录于专栏:golang云原生newgolang云原生new

上次我们分享了 Hystrix 具体流程,作为断路器实现,我们如何将 hystrix 用在我们的项目代码中呢?

我们可以简单的将 hystrix-go 下载下来

go get github.com/afex/hystrix-go/hystrix

代码会放到我们的 GOPATH 中,的 pkg 下面,例如我的 window 路径是这样的

go\pkg\mod\github.com\afex\hystrix-go@v0.0.0-20180502004556-fa1af6a1f4f5\hystrix

代码目录是酱紫的:

我们来看一下基本代码逻辑,屡一下:

初始化配置

代码语言:javascript
复制
hystrix.ConfigureCommand(CircuitBreakerName, hystrix.CommandConfig{
  Timeout:                1000, 
  MaxConcurrentRequests:  5,
  RequestVolumeThreshold: 3,
  SleepWindow:            2000,
  ErrorPercentThreshold:  20,
 })

可以看到 \go\pkg\mod\github.com\afex\hystrix-go@v0.0.0-20180502004556-fa1af6a1f4f5\hystrix\settings.go

中会有这个结构体定义的默认值

解释一下上述默认值代表的意思

  • Timeout

指的是,命令执行的超时时间

远程调用逻辑执行超过该时间将被强制执行超时,就进行失败回滚中 , 默认是 1000 毫秒

  • MaxConcurrentRequests

最大并发请求数

表示每个 hystrix 命令最大执行的并发协程,用于进行流量控制和资源隔离

当同种的 hystrix 执行的并发数量超过了该值,请求将会直接进入到失败回滚逻辑中,并被标记为拒绝请求上报

  • RequestVolumeThreshold

最小请求阈值

只有滑动窗口时间内的请求数量超过该值,断路器才会执行对应的判断逻辑

在低请求量的时候,断路器是不会发生效应的,即时这些请求全部失败,因为他只要没有超过这个值,就不会触发

  • SleepWindow

超时窗口时间,指的是断路器打开 SleepWindow 时长后,进入半开状态

重新允许远程调用的发生,试探下游服务是否恢复正常

如果接下来的请求都是成功的,那么断路器会关闭,否则就会重新打开

  • ErrorPercentThreshold

指的是,错误比例阈值

当滑动窗口时间内的错误请求频率超过这个值的时候,断路器也会打开

小案例

我们写一个小案例,来使用这个hystrix

  • 配置 hystrix
  • new 一个 hystrix , NewStreamHandler
代码语言:javascript
复制
hystrixStreamHandler := hystrix.NewStreamHandler()
hystrixStreamHandler.Start()
  • 开一个 http 服务器,来专门来访问 掘金主页
  • 使用 wrk 性能测试工具来 打一下 我们的 服务器
    • wrk -c200 -t8 -d40 --latency http://127.0.0.1:9999/juejin

这个性能测试指令的意思是:

  • 开启 200个连接
  • 8个线程
  • 测试 40 s

性能测试小工具的使用可以查看文章 :性能测试小工具 wrk 可以怎么用

代码语言:javascript
复制
package main

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

// http  /juejin 具体执行的逻辑

func CircuitBreakerTest(ctx *gin.Context) {
 hystrix.Do("xiaomotong", func() error {
  ctx.Next()
  code := ctx.Writer.Status()
  if code != http.StatusOK {
   return errors.New(fmt.Sprintf(" 状态码是 : %d", code))
  }
  return nil

 }, func(err error) error {
  if err != nil {

   fmt.Printf("断路器检测到错误: %s\n", err.Error())
   // 返回熔断错误
   ctx.JSON(http.StatusServiceUnavailable, gin.H{
    "msg": err.Error(),
   })
  }
  return nil
 })
}

// 整个包的初始化, 初始化 hystrix
func init() {
 hystrix.ConfigureCommand("xiaomotong", hystrix.CommandConfig{
  Timeout:                1000,
  MaxConcurrentRequests:  5,
  RequestVolumeThreshold: 5,
  SleepWindow:            5000,
  ErrorPercentThreshold:  20,
 })
}

func main() {
 hystrixStreamHandler := hystrix.NewStreamHandler()

 hystrixStreamHandler.Start()

 go http.ListenAndServe(":9999", hystrixStreamHandler)
 r := gin.Default()
 gin.SetMode(gin.ReleaseMode)

 r.GET("/juejin", func(c *gin.Context) {

  _, err := http.Get("https://juejin.cn/")
  if err != nil {
   c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
   return
  }

  c.JSON(http.StatusOK, gin.H{"msg": "success"})
 }, CircuitBreakerTest)

 r.Run(":9999")
}

使用 wrk 工具,打了之后,我们可以看到服务器的打印效果如下:

出现上述打印,说明,已经达到了最大并发请求数

继续往下看

看到如上错误,说明断路器已经打开了,这个时候来的请求一律拒绝,就不会再去访问 掘金的网站了

等待 SleepWindow 超时窗口时间后,会进入到半开状态,这个时候,若再有请求,并且全都成功,那么断路器就会关闭掉

具体的源码分析,我们可以下篇娓娓道来

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-05-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿兵云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化配置
  • 小案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档