返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Go语言中熔断的原理是什么
  • 829
分享到

Go语言中熔断的原理是什么

2024-04-02 19:04:59 829人浏览 泡泡鱼
摘要

本篇内容介绍了“Go语言中熔断的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!今天我们就来一起看

本篇内容介绍了“Go语言中熔断的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

今天我们就来一起看一下客户端上的限流措施:熔断。

熔断器

Go语言中熔断的原理是什么

熔断器[^2]

如上图[^2]所示,熔断器存在三个状态:

关闭(closed): 关闭状态下没有触发断路保护,所有的请求都正常通行

打开(open): 当错误阈值触发之后,就进入开启状态,这个时候所有的流量都会被节流,不运行通行

半打开(half-open): 处于打开状态一段时间之后,会尝试尝试放行一个流量来探测当前 server  端是否可以接收新流量,如果这个没有问题就会进入关闭状态,如果有问题又会回到打开状态

hystrix-go

熔断器中比较典型的实现就是 hystrix,golang 也有对应的版本,我们先来看一下 hystrix-go 是怎么实现的

案例

先看一个使用案例,首先我们使用 gin 启动一个服务端,这个服务端主要是前 200ms 的请求都会返回 500,之后的请求都会返回 200

func server() {  e := gin.Default()  e.GET("/ping", func(ctx *gin.Context) {   if time.Since(start) < 201*time.Millisecond {    ctx.String(Http.StatusInternalServerError, "pong")    return   }   ctx.String(http.StatusOK, "pong")  })  e.Run(":8080") }

然后配置 hystrix,hystrix.ConfigureCommand(command name, config) hystrix 的配置是按照每个  command 进行配置,使用的时候我们也需要传递一个 command,下面的配置就是我们的请求数量大于等于 10 个并且错误率大于等于 20%  的时候就会触发熔断器开关,熔断器打开 500ms 之后会进入半打开的状态,尝试放一部分请求去访问

func main(){  hystrix.ConfigureCommand("test", hystrix.CommandConfig{   // 执行 command 的超时时间   Timeout: 10,    // 最大并发量   MaxConcurrentRequests: 100,    // 一个统计窗口 10 秒内请求数量   // 达到这个请求数量后才去判断是否要开启熔断   RequestVolumeThreshold: 10,    // 熔断器被打开后   // SleepWindow 的时间就是控制过多久后去尝试服务是否可用了     // 单位为毫秒   SleepWindow: 500,    // 错误百分比   // 请求数量大于等于 RequestVolumeThreshold 并且错误率到达这个百分比后就会启动熔断   ErrorPercentThreshold: 20,  }) }

然后我们使用一个循环当做客户端代码,会请求 20 次,每一个请求消耗 100ms

func main() {  go server()     // 这里是 config 代码   for i := 0; i < 20; i++ {   _ = hystrix.Do("test", func() error {    resp, _ := resty.New().R().Get("http://localhost:8080/ping")    if resp.IsError() {     return fmt.Errorf("err code: %s", resp.Status())    }    return nil   }, func(err error) error {    fmt.Println("fallback err: ", err)    return err   })   time.Sleep(100 * time.Millisecond)  }  }

所以我们执行的结果就是,前面 2 个请求报 500,等到发起了 10 个请求之后就会进入熔断, 500ms 也就是发出 5  个请求之后就会重新去请求服务端

Go语言中熔断的原理是什么

image-20210504164650024

hystrix-go 核心实现

核心实现的方法是  AllowRequest,IsOpen判断当前是否处于熔断状态,allowSingleTest就是去看是否过了一段时间需要重新进行尝试

func (circuit *CircuitBreaker) AllowRequest() bool {  return !circuit.IsOpen() || circuit.allowSingleTest() }

IsOpen先看当前是否已经打开了,如果已经打开了就直接返回就行了,如果还没打开就去判断

请求数量是否满足要求

请求的错误率是否过高,如果两个都满足就会打开熔断器

func (circuit *CircuitBreaker) IsOpen() bool {  circuit.mutex.RLock()  o := circuit.forceOpen || circuit.open  circuit.mutex.RUnlock()   if o {   return true  }   if uint64(circuit.metrics.Requests().Sum(time.Now())) < getSettings(circuit.Name).RequestVolumeThreshold {   return false  }   if !circuit.metrics.IsHealthy(time.Now()) {   // too many failures, open the circuit   circuit.setOpen()   return true  }   return false }

hystrix-go已经可以比较好的满足我们的需求,但是存在一个问题就是一旦触发了熔断,在一段时间之类就会被一刀切的拦截请求,所以我们来看看 google  sre 的一个实现

Google SRE 过载保护算法

Go语言中熔断的原理是什么

算法如上所示,这个公式计算的是请求被丢弃的概率[^3]

  • requests: 一段时间的请求数量

  • accepts: 成功的请求数量

  • K: 倍率,K 越小表示越激进,越小表示越容易被丢弃请求

这个算法的好处是不会直接一刀切的丢弃所有请求,而是计算出一个概率来进行判断,当成功的请求数量越少,K越小的时候Go语言中熔断的原理是什么的值就越大,计算出的概率也就越大,表示这个请求被丢弃的概率越大

Kratos 实现分析

func (b *sreBreaker) Allow() error {  // 统计成功的请求,和总的请求  success, total := b.summary()   // 计算当前的成功率  k := b.k * float64(success)  if log.V(5) {   log.Info("breaker: request: %d, succee: %d, fail: %d", total, success, total-success)  }  // 统计请求量和成功率  // 如果 rps 比较小,不触发熔断  // 如果成功率比较高,不触发熔断,如果 k = 2,那么就是成功率 >= 50% 的时候就不熔断  if total < b.request || float64(total) < k {   if atomic.LoadInt32(&b.state) == StateOpen {    atomic.CompareAndSwapint32(&b.state, StateOpen, StateClosed)   }   return nil  }  if atomic.LoadInt32(&b.state) == StateClosed {   atomic.CompareAndSwapInt32(&b.state, StateClosed, StateOpen)  }   // 计算一个概率,当 dr 值越大,那么被丢弃的概率也就越大  // dr 值是,如果失败率越高或者是 k 值越小,那么它越大  dr := math.Max(0, (float64(total)-k)/float64(total+1))  drop := b.trueOnProba(dr)  if log.V(5) {   log.Info("breaker: drop ratio: %f, drop: %t", dr, drop)  }  if drop {   return ecode.ServiceUnavailable  }  return nil }  // 通过随机来判断是否需要进行熔断 func (b *sreBreaker) trueOnProba(proba float64) (truth bool) {  b.randLock.Lock()  truth = b.r.Float64() < proba  b.randLock.Unlock()  return }

总结

可用性仅靠服务端来保证是不靠谱的,只有整条链路上的所有服务都做好了自己可用性相关的建设我们的服务 SLA 最后才能够有保证。今天我们讲了  hystrix-go 和 kratos 两种熔断的实现方式,kratos采用 Google SRE  的实现的好处就是没有半开的状态,也没有完全开启的状态,而是通过一个概率来进行判断我们的流量是否应该通过,这样没有那么死板,也可以保证我们错误率比较高的时候不会大量请求服务端,给服务端喘息恢复的时间。

“Go语言中熔断的原理是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Go语言中熔断的原理是什么

本文链接: https://lsjlt.com/news/66208.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Go语言中熔断的原理是什么
    本篇内容介绍了“Go语言中熔断的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!今天我们就来一起看...
    99+
    2024-04-02
  • Go语言中goroutine的调度原理是什么
    Go语言中goroutine的调度原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、关于并发的基础知识在讲gorou...
    99+
    2024-04-02
  • GO语言中Chan的实现原理是什么
    今天小编给大家分享一下GO语言中Chan的实现原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。chan 是什么是一种...
    99+
    2023-07-05
  • GO语言中defer实现原理是什么
    这篇文章主要介绍“GO语言中defer实现原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“GO语言中defer实现原理是什么”文章能帮助大家解决问题。defer 是什么咱们一起来看看 def...
    99+
    2023-07-05
  • go语言中slice,map,channl底层原理是什么
    今天小编给大家分享一下go语言中slice,map,channl底层原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-06-30
  • Go语言的make和new实现原理是什么
    这篇文章主要介绍“Go语言的make和new实现原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go语言的make和new实现原理是什么”文章能帮助大家解决问题。概述虽然 make...
    99+
    2023-07-05
  • docker用go语言的原因是什么
    小编给大家分享一下docker用go语言的原因是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!首先主流服务使用Unix/Linux操作系统,而go语言对于第三方的依赖相当的少,这样使用go语言开发的Docker基本能够...
    99+
    2023-06-14
  • SpringBoot断言机制的原理是什么
    这篇文章主要介绍“SpringBoot断言机制的原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot断言机制的原理是什么”文章能帮助大家解决问题。JUnit 5 内置的断言可...
    99+
    2023-07-02
  • Go语言名为何为Go的原因是什么?
    标题:Go语言名为何为Go的原因是什么? Go语言(也称为Golang)是一种由Google开发的编程语言,自2009年首次发布以来,其受欢迎程度不断增长,被广泛应用于各种领域,包括网...
    99+
    2024-03-08
    语言 原因 命名 go语言 网络编程
  • GO 语言中的 SHELL 是什么?
    随着计算机技术的不断发展,人们对于计算机语言的需求也越来越高。其中,Go 语言被越来越多的程序员所青睐。在 Go 语言中,SHELL 是一个非常重要的概念。本文将会介绍 SHELL 在 Go 语言中的作用以及如何使用。 一、SHELL 是...
    99+
    2023-09-05
    自然语言处理 shell 对象
  • GO语言中的缓存管理:容器框架的实现原理是什么?
    随着网络技术的不断发展,数据量的不断增加,对数据的快速响应成为了当今互联网应用的重要问题。在这个背景下,缓存技术作为一种优化手段越来越受到开发者的关注。而GO语言因为其高效性、简洁性和可扩展性,成为了越来越多开发者选择的语言。那么,在GO...
    99+
    2023-07-24
    容器 框架 缓存
  • go语言中泛型是的是什么
    今天小编给大家分享的是go语言中泛型是的是什么,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。在go语言中,泛型就是编写模板适应所有类型,只有在具体使用时才定义具体变量类型;通过引入类...
    99+
    2023-07-04
  • Go语言中数组索引和存储的实现原理是什么?
    Go语言是一门功能强大的编程语言,它拥有很多独特的特性,比如强类型、垃圾回收机制和原生支持并发等。其中,数组是Go语言中最基本的数据结构之一,它在很多场景下都有着广泛的应用。本文将介绍Go语言中数组索引和存储的实现原理。 数组的定义和初始...
    99+
    2023-11-06
    索引 数组 存储
  • Go 的“类型断言”方式背后的原因是什么?
    问题内容 我试图理解这样一个事实:golang 的类型断言仅适用于显式定义为接口类型的变量,不适用于具体类型(即“string”、“int32”)等..)。 这是一个快速而简单的代码示...
    99+
    2024-02-06
    overflow
  • Go语言中的并发是什么
    这篇文章主要介绍“Go语言中的并发是什么”,在日常操作中,相信很多人在Go语言中的并发是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言中的并发是什么”的疑惑有所帮...
    99+
    2024-04-02
  • Go语言中的反射是什么
    本篇内容介绍了“Go语言中的反射是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是反射反射,嗯...,就是反着的意思呗,就是把东西反...
    99+
    2023-06-15
  • go语言中sql指的是什么
    今天小编给大家分享一下go语言中sql指的是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。SQL是指“结构化查询语言”,...
    99+
    2023-07-04
  • go语言中str指的是什么
    本篇内容主要讲解“go语言中str指的是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言中str指的是什么”吧!在go语言中,str指的是“字符串”,是一个不可改变的字节序列。字符串可...
    99+
    2023-07-04
  • 理解Go语言的标志是什么?
    标题:深入探讨Go语言的标志及代码示例 作为一门快速、高效、简洁的编程语言,Go语言在近年来广受开发者的欢迎。那么,理解Go语言的标志是什么?本文将从语言特点、代码示例等方面进行深入探...
    99+
    2024-04-02
  • Go语言是什么
    Go语言(又称 Golang)是一种静态强类型、编译型的编程语言,可以轻松构建简单、可靠以及高效的软件。Go语言语法与C语言相近,但功能更加丰富。Go语言的作者有三个,他们分别是:罗伯特·格利茨默(Robert Griesemer)、罗伯·...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作