当前位置: 首页 > news >正文

kratos源码分析:熔断器

文章目录

    • 为什么需要熔断
    • Google sre弹性熔断算法
    • kratos Breaker源码分析
      • 公共接口
      • sre实现
      • 上报请求结果
      • 判定是否熔断

为什么需要熔断

一般来说,当服务器过载(overload)时,需要给client返回服务过载的报错
但是拒接请求也有成本,可能响应错误码本身没啥成本,但处理请求协议栈,构建响应header等也有一笔开销
如果被拒绝的请求数量很大,后端任然会过载,因为其绝大多数CPU都花在拒绝请求上

因此最好的办法是客户端不要将请求发到服务端:当客户端检测到其最近的请求中有很大一部分因“服务过载”错误而被拒绝时,直接在本地失败,不会经过网络IO发给服务端
熔断也可以称为客户端限流

Google sre弹性熔断算法

google sre提供了一种自适应的客户端熔断算法,其维护了过去一段时间内的两个信息:

  • requests:往下游发起请求的总数
  • accepts:成功的请求数

  1. 正常情况下,这两个值是相等的
  2. 但当下游出现异常时,accepts会逐渐小于requests
  3. 一旦requests达到了accepts的K倍,客户端就要启动自适应限流,新产生的请求以一定概率被拒绝
    1. 拒绝请求的概率计算公式为: m a x ( 0 , r e q u e s t s − K ∗ a c c e p t s r e q u e s t s + 1 ) max(0, \frac{requests - K * accepts}{requests + 1}) max(0,requests+1requestsKaccepts)
  4. 当下游逐渐恢复时,accetps会增加,使得上述公式中分子变为负数,拒绝的概率降为0

可以调整K值,使算法产生不同的效果:

  • 减少K值会使得行为更激进,也就是更容易发生熔断
  • 增大K值会使得自适应熔断不那么激进

kratos Breaker源码分析

接下来分析kratos中熔断器,其采用了google sre的自适应客户端限流算法

公共接口

熔断器对外暴露3个方法:

  • Allow:每次调下游之前判断熔断器状态,根据返回结果决定是否往下游发送请求
  • MarkSuccess:每次调下游如果成功,上报Succ
  • MarkFailed:每次调下游如果失败,上报Failed
type CircuitBreaker interface {  Allow() error  MarkSuccess()  MarkFailed()  
}

在这里插入图片描述

业务中用起来大概是这样:

// 初始化breaker
b := sre.NewBreaker()// 请求下游前判断熔断器状态  
if err = breaker.Allow(); err != nil {  return  
}// 请求下游
err := fn()// 执行成功或失败将结果告知 breaker
if(err != nil){  breaker.MarkFailed()  
}else{  breaker.MarkSuccess()  
}

sre实现

  • stat:维护请求总数和成功数的滑动窗口
  • k:熔断算法的K值
  • request:开始熔断的请求数阈值,滑动窗口中请求数量达到request才开始熔断
  • state:熔断器状态,该字段实际没啥用
type Breaker struct {  // 滑动窗口stat window.RollingCounter  // 随机数产生器,同于根据概率熔断请求r    *rand.Rand  randLock sync.Mutex  // 熔断算法的K值k       float64// 开始熔断的请求数阈值request int64  state int32  
}

上报请求结果

func (b *Breaker) MarkSuccess() {  b.stat.Add(1)  
}  func (b *Breaker) MarkFailed() {  b.stat.Add(0)
}
  • MarkSuccess:内部会将总数+1,成功数+1
  • MarkFailed:内部只会将总数+1

本文的重点不是滑动窗口,这里知道其干了啥就好


判定是否熔断

在这里插入图片描述

  1. summary() 拿到滑动窗口中的请求总数和成功数
  2. 如果没达到熔断条件,返回err=nil。两个判定条件:
    1. 条件一:滑动窗口中请求总数没达到阈值(total < b.request
    2. 条件二:近期失败的数量不够多(k * accepts > total
  3. 否则就需要熔断,根据公式计算熔断概率dr
  4. 判定是否命中概率:生成一个0~1之间的随机数,如果小于dr说明命中
func (b *Breaker) Allow() error {  // 拿到滑动窗口中的请求总数和成功数accepts, total := b.summary()  requests := b.k * float64(accepts)  // 没达到熔断条件 if total < b.request || float64(total) < requests {  atomic.CompareAndSwapInt32(&b.state, StateOpen, StateClosed)  return nil  }  // 下面就是需要熔断atomic.CompareAndSwapInt32(&b.state, StateClosed, StateOpen)// 计算熔断概率  dr := math.Max(0, (float64(total)-requests)/float64(total+1))  drop := b.trueOnProba(dr)  // 需要熔断if drop {  return circuitbreaker.ErrNotAllowed  }  return nil  
}

从滑动窗口中获得请求总数total和成功请求数success:

func (b *Breaker) summary() (success int64, total int64) {  b.stat.Reduce(func(iterator window.Iterator) float64 {  for iterator.Next() {  bucket := iterator.Bucket()  // 统计总数  total += bucket.Count  for _, p := range bucket.Points {  // 统计成功的数量  success += int64(p)  }  }  return 0  })  return  
}

trueOnProba就是生成一个0~1之间的随机数,看是否小于概率proba

func (b *Breaker) trueOnProba(proba float64) (truth bool) {  b.randLock.Lock()  truth = b.r.Float64() < proba  b.randLock.Unlock()  return  
}

相关文章:

kratos源码分析:熔断器

文章目录 为什么需要熔断Google sre弹性熔断算法kratos Breaker源码分析公共接口sre实现上报请求结果判定是否熔断 为什么需要熔断 一般来说&#xff0c;当服务器过载&#xff08;overload&#xff09;时&#xff0c;需要给client返回服务过载的报错 但是拒接请求也有成本&…...

CTF_1

CTF_Show 萌新赛 1.签到题 <?php if(isset($_GET[url])){system("curl https://".$_GET[url].".ctf.show"); }else{show_source(__FILE__); }?> 和 AI 一起分析 1.if(isset($_GET[url]))检查GET请求中是否存在名为url的参数。 curl 2.curl…...

【系统】Mac crontab 无法退出编辑模式问题

【系统】Mac crontab 无法退出编辑模式问题 背景一、问题回答1.定位原因&#xff1a;2.确认编辑器类型3.确保编辑器进入正确3.1 确认是否有crontab调度任务3.2 进入编辑器并确保编辑器正常3.3 保存操作 4.确认crontab任务存在5.确保脚本的可执行性和正确性 二、后续 背景 之前…...

K8s中 statefulset 和deployment的区别

在 Kubernetes 中&#xff0c;StatefulSet 和 Deployment 是两种管理 Pod 的控制器&#xff0c;它们的主要区别在于 状态管理 和 Pod 的标识。以下是详细对比&#xff1a; 1. 功能定位 Deployment 用途&#xff1a;用于 无状态应用 的部署&#xff0c;例如 Web 服务、API 服务…...

springboot中的AOP以及面向切面编程思想

快速入门体验AOP aop中相关概念 实现导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 新建aop文件夹,里面声明XXXAspect类 @Aspect // 声…...

降低Mobx技术债问题-React前端数据流方案调研整理

我们现在主要是使用Mobx&#xff0c;但是Mobx的易于上手和灵活度也带来了很多预期以外的问题&#xff0c;随着项目的增长我们的代码技术债变得愈加沉重&#xff0c;不同的模块杂糅一起、单一store无限膨胀。 为此我们的调研是希望能找到一个更好的state配置、数据流的约定方案。…...

RabbitMQ消息可靠性保证机制7--可靠性分析-rabbitmq_tracing插件

rabbitmq_tracing插件 rabbitmq_tracing插件相当于Firehose的GUI版本&#xff0c;它同样能跟踪RabbitMQ中消息的注入流出情况。rabbitmq_tracing插件同样会对流入流出的消息进行封装&#xff0c;然后将封装后的消息日志存入相应的trace文件中。 # 开启插件 rabbitmq-plugins …...

SQL进阶技巧:如何求解直接线上最多的点数?

目录 0 问题描述 1 数据准备 2 问题分析 3 求解优化 步骤一:构建 “斜率键” 并统计点的数量(核心步骤) 步骤二:找出最多的点数(最终结果) 0 问题描述 “平面上最多的点数” 问题通常是指在一个二维平面中给定了若干个点的坐标(例如以 (x,y) 的形式表示),要求找…...

【老白学 Java】泛型应用 - 卡拉 OK(四)

泛型应用 - 卡拉 OK&#xff08;四&#xff09; 文章来源&#xff1a;《Head First Java》修炼感悟。 上文说到&#xff0c;解决了按歌名排序的问题后&#xff0c;老白立刻想到了按歌手名字排序的问题。 老白决定趁热打铁&#xff0c;尝试着实现自定义排序方式。 Collections…...

android studio更改应用图片,和应用名字。

更改应用图标&#xff0c;和名字 先打开AndroidManifest.xml文件。 更改图片文件名字&#xff08; 右键-->构建-->重命名&#xff08;R&#xff09;&#xff09;...

SQL Server 表值函数使用示例

在 SQL Server 中,表值函数(Table-Valued Functions, TVFs)是一种用户定义函数,它可以返回一个表。表值函数有两种类型:内联表值函数(Inline Table-Valued Function)和多语句表值函数(Multi-Statement Table-Valued Function)。下面分别介绍这两种类型的表值函数及其使…...

SpringBoot项目的创建方式

目录 1.通过idea创建SpringBoot项目 2.在idea中通过aliyun创建SpringBoot 3.通过spring官网下载再用idea打开 5.通过mavenjava项目改为springboot项目 6.测试springboot 第二种方法使用的是idea2021版本&#xff0c;其余方法使用idea2017版本 1.通过idea创建SpringBoot项…...

微服务设计(第2版)读书笔记

微服务概述 什么是微服务&#xff1f; 答&#xff1a;微服务&#xff08;microservice&#xff09;是基于业务领域建模的&#xff0c;可独立发布的服务。它会把业务内聚的功能封装起来&#xff0c;并通过网络供其他服务访问。将这样的服务组合起来构建出更复杂的系统。 微服务…...

idea无法识别文件,如何把floder文件恢复成model

前景&#xff1a; 昨天&#xff0c;我在之前的A1214模块包下新增了一个demo类&#xff0c;然后又新建了一个A1216模块&#xff0c;写了算法题&#xff0c;后面打算用git提交&#xff0c;发现之前的A1214模块下的demo类和新建的模块源文件都已经被追踪了&#xff0c;都是绿色的&…...

vscode的keil assistant 中搜索不到全局变量

搜不到 但是在包含的文件中输入 ../../../,就是全局搜索的结果 我的文件结构是&#xff1a;\Desktop\LVGL文件系统移植&#xff08;lvgl8&#xff0e;&#xff13;&#xff09;\Projects\MDK-ARM 盲猜是keil assistant 当前文件夹打开的时候是进入到了MDK-ARM文件夹层次&…...

html+css网页设计 美食 餐饮杰12个页面

htmlcss网页设计 美食 餐饮杰12个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xff…...

重撸设计模式--代理模式

文章目录 定义UML图代理模式主要有以下几种常见类型&#xff1a;代理模式涉及的主要角色有&#xff1a;C 代码示例 定义 代理模式&#xff08;Proxy Pattern&#xff09;属于结构型设计模式&#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。 通过引入代理对象&am…...

Redis性能调优:深入剖析变慢原因及应对策略

如果观察到&#xff0c;这个实例的运行延迟是正常 Redis 基准性能的 2 倍以上&#xff0c;即可认为这个 Redis 实例确实变慢了。 1.如何查看实例的运行延迟 &#xff08;1&#xff09;redis-cli -h 127.0.0.1 -p 6379 --intrinsic-latency 60 执行该命令&#xff0c;就可以测…...

Python联合Halcon的详细教程

以下是一份Python联合Halcon的详细教程&#xff1a; 一、简介 Halcon是一款由德国MVTec公司开发的高级机器视觉软件&#xff0c;提供了一套强大的图像处理库&#xff0c;包括特征检测、识别、测量等功能。Python联合Halcon是一种将Python编程语言与计算机视觉库Halcon集成的应…...

raid 状态查看 storcli64

场景 当磁盘报错的时候使用该命令排查 fdisk -l /dev/sdb fdisk: cannot open /dev/sdb: Input/output error进一步使用 smartctl 排查 smartctl -a /dev/sdb 输出 smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.4.0-144-generic] (local build) Copyright (C) 2002-19, B…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...