微服务可用性设计
一、隔离
对系统或资源进行分割,实现当系统发生故障时能限定传播范围和影响范围。进一步的,通过隔离能够降低系统之间得耦合度,使得系统更容易维护和扩展。某些业务场景下合理使用隔离技巧也能提高整个业务的性能。我理解隔离本质就是一种解耦手段。
1.1 动静隔离
动静隔离本质上是根据资源的变化频率,对它们进行划分和隔离。本质上是加速/缓存变化频率小的数据,将它们与其它资源进行隔离,避免其它资源频繁变化影响到它们,从而提高性能
场景一: 将对象存储和业务服务隔离
对象存储费用低、存储量大,并且放入对象存储空间的资源变化频率也低。我们将对象存储作为一个单独的模块让所有业务服务共享,这样业务服务就无需考虑存储问题,比如空间不足、静态资源和业务数据在带宽上无法隔离造成业务卡顿等问题。
本质上是对静态资源(静态文件)和动态资源(动态业务数据)进行了隔离,将它们进行隔离提高了业务服务的带宽性能、每个业务服务也不需要考虑自身的存储空间以及数据之间的一致性问题,将业务服务变为一种无状态的服务,更方便扩缩容。
场景二:数据表字段的分离
针对一个业务设计了一张数据表,该表包括了一个对象的基本信息和统计信息。基本信息的变动频率往往很低(用户名、性别、状态、手机号、密码),而统计信息变化频率往往很高(点赞数、关注数、粉丝数、资产数)等等
我们可以将基本信息和统计信息进行分离,能够得到以下好处:
- 修改统计信息只会使得统计信息的缓存失效,不会使得基本信息的缓存失效
- 使得B+树叶子节点能够存放更多记录,从而降低树的高度,缓解单表数据量大导致读写操作慢的问题
场景三: 各种数据库的读写分离也借鉴了该思想
1.2 快慢隔离
把服务的吞吐想象成一个蓄水池,当突然洪流进来的时候,池子需要一定时间才能将其排放完,而这时候其它的小流量在池子里面待的时间取决于这个蓄水池的排放能力,为了提高排放能力(接口响应速度),我们可以对服务进行快慢隔离。
当我们请求一个接口时,它可能涉及到很多业务处理,有些业务轻处理快、有些重处理慢。在不影响用户体验的前提下,我们可以将这些重的业务特别是一些大的并发业务从上游解耦到消息队列的消费者端处理,提高整个api的响应速度,保证业务最终完成即可。
1.3 热点隔离
统计某个热点数据重访问频次最高TopKS数据进行缓存,或者将remoteCache升级为localCache,提升效率
1.4 物理隔离
- 线程池隔离
- 同一主机下使用cgroup隔离服务的cpu、内存
- 进程隔离、集群隔离等
二、超时控制
超时控制,通过限制请求在系统里停留的最长时间,避免请求长时间在系统中占用资源,降低系统的性能。(当用户发起一次请求过了2~3秒都没反应,用户往往会重试,上次的请求也就应该丢弃了,如果不设置超时时间它还会继续在系统中执行业务,消耗系统的资源)
超时控制应该具备传递功能,当上游服务已经返回超时错误时,下游服务不要再继续执行。Quota传递到下游服务中,应该继承超时策略
go-grpc框架中,会依赖gRPC Metadata Exchange,基于HTTP2的Headers传递grpc-timeout字段传递到下游,构建待timeout的context。
简单说,如果你调用grpc方法中传入的context携带timeout,那么grpc则会在http2的header frame中设置字段grpc-timeout为context.DeadLine(),而grpc server在接收请求时若发现grpc-timeout的存在,则会构造一个带timeout的context传给handler,从而实现grpc的超时传递
go-zero的超时控制实现
go-zero 中我们可以再BFF层配置Timeout字段设置接口的超时时间,它会帮我们完成超时传递
go-zero/core/fx/timeout.go:超时控制
package fximport ("context""fmt""runtime/debug""strings""time"
)var (// ErrCanceled is the error returned when the context is canceled.ErrCanceled = context.Canceled// ErrTimeout is the error returned when the context's deadline passes.ErrTimeout = context.DeadlineExceeded
)// DoOption defines the method to customize a DoWithTimeout call.
type DoOption func() context.Context// DoWithTimeout runs fn with timeout control.
func DoWithTimeout(fn func() error, timeout time.Duration, opts ...DoOption) error {parentCtx := context.Background()for _, opt := range opts {parentCtx = opt()}ctx, cancel := context.WithTimeout(parentCtx, timeout)defer cancel()// create channel with buffer size 1 to avoid goroutine leakdone := make(chan error, 1)panicChan := make(chan any, 1)go func() {defer func() {if p := recover(); p != nil {// attach call stack to avoid missing in different goroutinepanicChan <- fmt.Sprintf("%+v\n\n%s", p, strings.TrimSpace(string(debug.Stack())))}}()done <- fn()}()select {case p := <-panicChan:panic(p)case err := <-done:return errcase <-ctx.Done():return ctx.Err()}
}// WithContext customizes a DoWithTimeout call with given ctx.
func WithContext(ctx context.Context) DoOption {return func() context.Context {return ctx}
}
参考
小米技术团队:https://xiaomi-info.github.io/2019/12/30/grpc-deadline/
三、过载保护、限流
本质上是根据系统的情况限制请求接收的数量,将能力以外的请求快速响应失败,但是二者有一些区别
过载保护:在未达到阈值前尽可能的接收请求,当cpu达到阈值(一般为90%)时得到系统的最大负载,开始丢弃一些请求。但是由于这个时候已经接近满负载了并且丢弃请求本身也具有一丢丢的性能损耗,此时若请求仍大量进来还是会将服务打崩。
限流:限流算法从始至终都在限制请求接收的速率,弥补过载保护在极端条件的风险,使得服务更加稳健
过载保护
通过记录当前机器的各项性能指标,比如cpu、内存、响应延迟等信息判断是否过载,如果过载则开启过载保护,以过载的系统负载作为阈值,判断当前请求数量是否超过阈值。
负载统计:
const (// 250ms and 0.95 as beta will count the average cpu load for past 5 secondscpuRefreshInterval = time.Millisecond * 250allRefreshInterval = time.Minute// moving average beta hyperparameterbeta = 0.95
)func init() {go func() {cpuTicker := time.NewTicker(cpuRefreshInterval)defer cpuTicker.Stop()allTicker := time.NewTicker(allRefreshInterval)defer allTicker.Stop()for {select {case <-cpuTicker.C:threading.RunSafe(func() {curUsage := internal.RefreshCpu()prevUsage := atomic.LoadInt64(&cpuUsage)// cpu = cpuᵗ⁻¹ * beta + cpuᵗ * (1 - beta)//指数衰变算法 usage := int64(float64(prevUsage)*beta + float64(curUsage)*(1-beta))atomic.StoreInt64(&cpuUsage, usage)})case <-allTicker.C:printUsage()}}}()
}
过载保护:/core/load/adaptiveshedder.go
func (as *adaptiveShedder) shouldDrop() bool {if as.systemOverloaded() || as.stillHot() {if as.highThru() {flying := atomic.LoadInt64(&as.flying)as.avgFlyingLock.Lock()avgFlying := as.avgFlyingas.avgFlyingLock.Unlock()msg := fmt.Sprintf("dropreq, cpu: %d, maxPass: %d, minRt: %.2f, hot: %t, flying: %d, avgFlying: %.2f",stat.CpuUsage(), as.maxPass(), as.minRt(), as.stillHot(), flying, avgFlying)logx.Error(msg)stat.Report(msg)return true}}return false
}
分布式限流
参考go-zero的分布式限流实现:https://pandaychen.github.io/2020/09/21/A-DISTRIBUTE-GOREDIS-RATELIMITER-ANALYSIS/
四、熔断降级
五、重试、负载均衡
相关文章:
微服务可用性设计
一、隔离 对系统或资源进行分割,实现当系统发生故障时能限定传播范围和影响范围。进一步的,通过隔离能够降低系统之间得耦合度,使得系统更容易维护和扩展。某些业务场景下合理使用隔离技巧也能提高整个业务的性能。我理解隔离本质就是一种解…...

【扒代码】dave readme文档翻译
jerpelhan/DAVE (github.com) 摘要 低样本计数器估算选定类别对象的数量,即使在图像中只有少量或没有标注样本的情况下。目前最先进的技术通过对象位置密度图的总和来估算总数量,但这种方法无法提供单个对象的位置和大小,这对于许多应用来说…...

c语言---文件
这一节我准备分三个部分来带领大家了解文件 ——一、有关文件的基础知识 ————二、文件的简单操作 ————————三、文件结束的判定 ————————————四、文件缓冲区 一、文件的基础知识: 首先在了解文件之前,我们需要了解C/C程序内存…...

Windows系统下Go安装与使用
step1: 下载go语言SDK 下载地址:https://go.dev/dl/ 下载后选择合适位置安装即可,我选择D盘 在安装完成后,可以通过go env 命令检测是否安装成功。在“命令提示符”界面输入“go env”命令,如果显示如下类似结果则说明…...

day24-测试之接口测试基础
目录 一、接口的定义 二、接口的优点 三、API接口 四、接口测试流程 五、网络基础概念 六、HTTP和RURL 七、get和post请求 八、数据格式 九、状态码 十、restful风格 十一、接口工具 一、接口的定义 程序之间协作所要遵循的一套规范、标准 二、接口的优点 2.1.责任…...
TSN 交换机
TSN(Time-Sensitive Networking)交换机是一种支持时间敏感网络协议的网络交换设备,用于在以太网网络中实现低延迟、高确定性的数据传输。TSN 是一组 IEEE 802 标准的集合,旨在通过标准化的方式,将传统的以太网扩展到需…...

针对thinkphp站点的漏洞挖掘和经验分享
0x1 前言 浅谈 目前在学习和研究thinkphp相关漏洞的打法,然后最近对于thinkphp资产的收集方面有了一个简单的认识,然后写一篇新手看的thinkphp相关的漏洞收集和挖掘的文章来分享下。然后后面是给师傅们分享下后台文件上传,然后直接打一个ge…...

MySQL数据库入门,pycharm连接数据库—详细讲解
一.安装MySQL 1.常用MySQL5.7,首先安装MySQL, (一) (二) (三) (四) (五) 2.配置环境变量 打开MySQL安装路径,在其中找到…...

.bat文件快速运行vue项目
如何使用bat文件快速运行vue项目? 新建个文件,改名为serve.bat。 在文件中写入以下内容: # cd 项目路径 cd D:\projects\xxx npm run serve pausecd 项目所在的路径 npm run dev/serve ,取决于项目的启动方法,打…...

数据结构(邓俊辉)学习笔记】优先级队列 07——堆排序
1.算法 作为完全二叉堆的一个应用,这节来介绍堆排序算法。 是的,谈到优先级队列,我们很自然地就会联想到排序。因为就其功能而言,包括完全二叉堆在内的任何一种优先级队列都天生地具有选取功能,也就是选取其中的最大…...

npm install pnpm -g 报错的解决方法
npm install pnpm -g 报错的解决方法 npm error code ETIMEDOUT npm error errno ETIMEDOUT npm error network request to https://registry.npmjs.org/pnpm failed, reason: npm error network This is a problem related to network connectivity. npm error network In mo…...

集师知识付费小程序开发
智慧生活,从选择一款优质知识付费小程序起航 在这个信息爆炸的时代,知识成为了最宝贵的财富。我们渴望不断学习,提升自我,追求更高品质的生活。而一款优质的知识付费小程序,就如同照亮前行道路的明灯。 它是知识的宝库…...

前端开发提效工具——用户自定义代码片段
做开发总是会有大量的代码要写,但是有时候某些代码是非常基础但是很多,我们就可以把这一部分整合起来,使用一个很简短的关键字来快速唤出。 如何新建这样的代码段? 1.在VSCode当中找到Snippets,然后点击 2.之后会弹出…...

docker容器安全加固参考建议——筑梦之路
这里主要是rootless的方案。 在以 root 用户身份运行 Docker 会带来一些潜在的危害和安全风险,这些风险包括: 容器逃逸:如果一个容器以 root 权限运行,并且它包含了漏洞或者被攻击者滥用,那么攻击者可能会成功逃出容器…...

基于 Appium 的 App 爬取实战
除了运行 Appium 的基本条件外,还要一个日志输出库 安装: pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程,其首页分条显示了电影数据, 每个电影条目都包括封面,标题, 类别和评分 4…...
nvm与node安装
参考: 一文搞定NVM安装所有问题NVM UI解决nodejs下载慢问题 node_mirror: http://npmmirror.com/mirrors/node/ npm_mirror: http://registry.npmmirror.com/mirrors/npm/解决nvm list available报错问题 Could not retrieve https://npm.taobao.org/mirrors/node/…...

【电子通识】什么是MSL湿敏等级
潮敏失效是塑料封装表贴器件在高温焊接工艺中表现出来的特殊的失效现象。 造成此类问题的原因是器件内部的潮气膨胀后使得器件发生损坏。 MSL是“Moisture Sensitivity Level(湿气敏感性等级)”的缩写,针对需进行回流焊的产品设定了MSL基准。…...
【ARM 芯片 安全与攻击 5.4 -- Meltdown 攻击与防御介绍】
文章目录 什么是 Meltdown 攻击?Meltdown 攻击的基本原理Meltdown 攻击代码示例Meltdown 攻击在芯片中的应用应用场景Meltdown 攻击与瞬态攻击、测信道攻击的关系针对 Meltdown 攻击的防御硬件级防御Summary什么是 Meltdown 攻击? Meltdown 攻击是一种利用处理器乱序执行(o…...
Django 后端架构开发:分页器到中间件开发
🚀 Django 后端架构开发:分页器到中间件开发 🚀 🔹 应用样式:上下翻页 分页功能在处理大量数据时非常有用。通过上下翻页,我们可以让用户轻松浏览数据。以下是一个展示产品列表的分页示例: fr…...
亲测解决The client socket has failed to connect to
这个问题是因为深度学习的程序(服务)跟本地主机连接不上,解决方法是确认rank起始数为0。 报错原文 [W socket.cpp:663] [c10d] The client socket has failed to connect to [csdn-xiaohu]:12345 (errno: 22 - Invalid argument).解决方法 …...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...