go 进阶训练营 微服务可用性(中)笔记
过载保护
令牌桶算法
存放固定容量令牌的桶,按照固定速率往桶里添加令牌
https://pkg.go.dev/golang.org/x/time/rate
漏桶算法
作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing)
https://pkg.go.dev/go.uber.org/ratelimit
令牌桶和漏桶有什么区别和本质原理
令牌桶可以接受突增流量进行处理,漏桶是固定速率进行请求,对于突增流量会被丢弃。
本质原理:
漏斗桶/令牌桶确实能够保护系统不被拖垮, 但不管漏斗桶还是令牌桶, 其防护思路都是设定一个指标, 当超过该指标后就阻止或减少流量的继续进入,当系统负载降低到某一水平后则恢复流量的进入。但其通常都是被动的,其实际效果取决于限流阈值设置是否合理,但往往设置合理不是一件容易的事情
令牌桶和漏桶算法的缺点:太被动, 不能快速适应流量变化
集群增加机器或者减少机器限流阈值是否要重新设置?
设置限流阈值的依据是什么?
人力运维成本是否过高?
当调用方反馈429时, 这个时候重新设置限流, 其实流量高峰已经过了重新评估限流是否有意义?
自适应限流:根据系统当前的负载自动丢弃流量
计算系统临近过载时的峰值吞吐作为限流的阈值来进行流量控制,达到系统保护
服务器临近过载时,主动抛弃一定量的负载,目标是自保。
计算系统最大吞吐
利特尔法则
最大可以接受请求数量 = latency(处理时间) * 最大成功数量
CPU: 使用一个独立的线程采样,每隔 250ms 触发一次。在计算均值时,使用了简单滑动平均去除峰值的影响。
指数加权移动平均法(EWMA)
https://www.cnblogs.com/jiangxinyang/p/9705198.html
Inflight: 当前服务中正在进行的请求的数量。
Pass&RT: 最近5s,pass 为每100ms采样窗口内成功请求的数量,rt 为单个采样窗口中平均响应时间
使用 CPU 的滑动均值(CPU > 800)作为启发阈值,一旦触发进入到过载保护阶段,算法为:(pass* rt) < inflight
限流效果生效后,CPU 会在临界值(800)附近抖动,如果不使用冷却时间,那么一个短时间的 CPU 下降就可能导致大量请求被放行,严重时会打满 CPU。
在冷却时间后,重新判断阈值(CPU > 800 ),是否持续进入过载保护。
具体代码:
https://github.com/go-kratos/kratos/blob/v1.0.x/pkg/ratelimit/bbr/bbr.go
func (l *BBR) shouldDrop() bool {
if l.cpu() < l.conf.CPUThreshold {
prevDrop, _ := l.prevDrop.Load().(time.Duration)
if prevDrop == 0 {
return false
}
if time.Since(initTime)-prevDrop <= time.Second {
inFlight := atomic.LoadInt64(&l.inFlight)
return inFlight > 1 && inFlight > l.maxFlight()
}
l.prevDrop.Store(time.Duration(0))
return false
}
inFlight := atomic.LoadInt64(&l.inFlight)
drop := inFlight > 1 && inFlight > l.maxFlight()
if drop {
prevDrop, _ := l.prevDrop.Load().(time.Duration)
if prevDrop != 0 {
return drop
}
l.prevDrop.Store(time.Since(initTime))
}
return drop
}
func (l *BBR) maxFlight() int64 {
return int64(math.Floor(float64(l.maxPASS()*l.minRT()*l.winBucketPerSec)/1000.0 + 0.5))
}
这里除以 1000 也是让我想了一会的
一个窗口是100ms,使用 最大窗口通过的 (请求数量 * 窗口最小耗时 * 窗口数量) 这等于 1s内 10个窗口的最大请求数量
请求数量 * 窗口最小耗时 = 一个窗口最大可以接受的请求数量
然后 * 窗口数量 / 1000 等于一个窗口内最大的 吞吐数量
限流
限流是指在一段时间内,定义某个客户或应用可以接收或处理多少个请求的技术。
通过限流,你可以过滤掉产生流量峰值的客户和微服务,或者可以确保你的应用程序在自动扩展(Auto Scaling)失效前都不会出现过载的情况
令牌桶、漏桶 针对单个节点,无法分布式限流
为什么需要分布式限流?
保护下游服务和自身不会被突增的流量打死,比如服务日常可以处理1w流量,增加到2w出发自保护,但是一下子到10w的话,下游服务db和rpc服务承担不住,直接挂了。
每次心跳后,异步批量获取 quota,可以大大减少请求 redis 的频次,获取完以后本地消费,基于令牌桶拦截
如何基于单个节点按需申请,并且避免出现不公平的现象?
初次使用默认值,一旦有过去历史窗口的数据,可以基于历史窗口数据进行 quota 请求
最大最小公平分享”(Max-Min Fairness)。
直观上,公平分享分配给每个用户想要的可以满足的最小需求,然后将没有使用的资源均匀的分配给需要‘大资源’的用户
熔断
断路器(Circuit Breakers)
服务依赖的资源出现大量错误

触发熔断以后很快很多请求都会失败,对用户影响比较大, 所以是想让部分失败,丢弃部分请求,不要一下子打死
Google SRE
max(0, (requests - K*accepts) / (requests + 1))
代码位置:
https://github.com/go-kratos/kratos/blob/v1.0.x/pkg/net/netutil/breaker/sre_breaker.go
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)
}
// check overflow requests = K * success
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 := 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
}
限流 - 客户端流控 退让
https://github.com/go-kratos/kratos/blob/v1.0.x/pkg/net/netutil/backoff.go
限流-gutter
基于熔断的 gutter kafka ,用于接管自动修复系统运行过程中的负载,这样只需要付出10%的资源就能解决部分系统可用性问题。
经常使用 failover 的思路,但是完整的 failover 需要翻倍的机器资源,平常不接受流量时,资源浪费。高负载情况下接管流量又不一定完整能接住。所以这里核心利用熔断的思路,是把抛弃的流量转移到 gutter 集群,如果 gutter 也接受不住的流量,重新回抛到主集群,最大力度来接受。
总结
分布式限流
自适用保护自己
客户端的熔断
立体式的防御增加可用性
go 进阶训练营 微服务可用性(中)笔记的更多相关文章
- Chris Richardson微服务翻译:微服务架构中的服务发现
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...
- Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案
Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明:Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在 ...
- Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理
Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明:Java生鲜电商平台中,我们将进一步理解微服务架构的核心要点和实现原理,为读者的实践提供微服务的设计模式,以期让微服务 ...
- SpringCloud微服务框架复习笔记
SpringCloud微服务框架复习笔记 什么是微服务架构? 微服务是一种软件开发技术,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进 ...
- 微服务架构中API网关的角色
[上海尚学堂的话]:本文主要讲述了Mashape的首席技术执行官Palladino对API网关的详细介绍,以及API网关在微服务中所起的作用,同时介绍了Mashape的一款开源API网关Kong. A ...
- 微服务架构中APIGateway原理
背景 我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest ...
- 认证鉴权与API权限控制在微服务架构中的设计与实现(四)
引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...
- JWT如何在Spring Cloud微服务系统中在服务相互调时传递
转载请标明出处: http://blog.csdn.net/forezp/article/details/78676036 本文出自方志朋的博客 在微服务系统中,为了保证微服务系统的安全,常常使用jw ...
- kratos微服务框架学习笔记一(kratos-demo)
目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服务框架学习笔记一(kratos-demo) 今年大部分时间飘过去了,没怎么更博和githu ...
- 【CHRIS RICHARDSON 微服务系列】微服务架构中的进程间通信-3
编者的话 |本文来自 Nginx 官方博客,是微服务系列文章的第三篇,在第一篇文章中介绍了微服务架构模式,与单体模式进行了比较,并且讨论了使用微服务架构的优缺点.第二篇描述了采用微服务架构的应用客户端 ...
随机推荐
- FastAPI测试策略:参数解析单元测试
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长 探索数千个预构建的 AI 应用,开启你的下一个伟大创意 第一章:核心测试方法论 1.1 三层测试体系架构 # 第一层:模型级测试 def ...
- 什么是 IPv6,为什么我们还未普及?
在大多数情况下,已经没有人一再对互联网地址耗尽的可怕境况发出警告,因为,从互联网协议版本 4(IPv4)的世界到 IPv6 的迁移,虽然缓慢,但已经坚定地开始了,并且相关软件已经到位,以防止许多人预测 ...
- Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法
一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程. 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链 ...
- [python] 使用Python实现Markdown文档格式转换
本文主要介绍如何利用Python中的MarkItDown库将多种文件高效转换为Markdown文本,以及如何使用Python-Markdown库将Markdown文本转换为HTML(超文本标记语言)文 ...
- 【Linux】3.4 用户管理
用户管理 1. 基本用户管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用户的账号一方面可以帮助 ...
- Sql语句:条件限制语句
where select sname,sdept,sage from student where ssex = '男' or ssex = '女' and sage not between 20 an ...
- CoreOS 更新重启后, 所有容器服务全部停掉了
今天有几个服务出问题了,上去看了下,这台 CoreOS 下的所有容器服务竟然全部停掉了,好奇怪,启动容器时明明加了--detach参数了呀. 问题原因 想了想,会不是是 CoreOS 更新重启导致的, ...
- 青岛oj集训5
Floyd算法--全源最短路 cerr:标准输出错误流:不会输出到freopen制定的out文件中,而是会输出到错误文件中. 提交上去无论加不加freopen,哪怕是提交到洛谷,也只是比较out文件中 ...
- [设计模式/Java/多线程] 设计模式之单例模式【9】
0 序 此文系对最常见的设计模式----单例模式的最全总结. 1 概述:单例模式 模式定义 单例模式: 保证1个类有且仅有1个实例,并提供1个访问它的全局访问点. 1个类有且仅有1个实例,并自行实例化 ...
- 40+程序员亲历AI冲击,出路在何方?
关注[智践行],我们一起成长 技术革新从不以人的意志为转移,但却能因个人的选择而重铸职业轨迹,AI崛起的当下,程序员的命运之笔正握在自己手中. 今年春节前后,AI界热闹非凡,各种大模型的新突破.超强的 ...