k8s API限流——server级别整体限流和客户端限流
1. 背景
为了防止突发流量影响apiserver可用性,k8s支持多种限流配置,包括:
- MaxInFlightLimit,server级别整体限流
- Client限流
- EventRateLimit, 限制event
- APF,更细力度的限制配置
1.1 MaxInFlightLimit限流
- apiserver默认可设置最大并发量(集群级别,区分只读与修改操作)
- 通过参数–max-requests-inflight代表只读请求
- –max-mutating-requests-inflight代表修改请求
- 可以简单实现限流。
1.1.1 源码解读
-
入口 GenericAPIServer.New中的添加hook
// FlowControl为nil ,代表未启用 APF,API 服务器中的整体并发量将受到 kube-apiserver 的参数 --max-requests-inflight 和 --max-mutating-requests-inflight 的限制。if c.FlowControl != nil {const priorityAndFairnessFilterHookName = "priority-and-fairness-filter"if !s.isPostStartHookRegistered(priorityAndFairnessFilterHookName) {err := s.AddPostStartHook(priorityAndFairnessFilterHookName, func(context PostStartHookContext) error {genericfilters.StartPriorityAndFairnessWatermarkMaintenance(context.StopCh)return nil})if err != nil {return nil, err}}} else {const maxInFlightFilterHookName = "max-in-flight-filter"if !s.isPostStartHookRegistered(maxInFlightFilterHookName) {err := s.AddPostStartHook(maxInFlightFilterHookName, func(context PostStartHookContext) error {genericfilters.StartMaxInFlightWatermarkMaintenance(context.StopCh)return nil})if err != nil {return nil, err}}}// StartMaxInFlightWatermarkMaintenance starts the goroutines to observe and maintain watermarks for max-in-flight // requests. func StartMaxInFlightWatermarkMaintenance(stopCh <-chan struct{}) {startWatermarkMaintenance(watermark, stopCh) }// startWatermarkMaintenance starts the goroutines to observe and maintain the specified watermark. func startWatermarkMaintenance(watermark *requestWatermark, stopCh <-chan struct{}) {// 定期更新inflight使用指标go wait.Until(func() {watermark.lock.Lock()readOnlyWatermark := watermark.readOnlyWatermarkmutatingWatermark := watermark.mutatingWatermarkwatermark.readOnlyWatermark = 0watermark.mutatingWatermark = 0watermark.lock.Unlock()metrics.UpdateInflightRequestMetrics(watermark.phase, readOnlyWatermark, mutatingWatermark)}, inflightUsageMetricUpdatePeriod, stopCh)// 定期观察watermarks。这样做是为了确保他们不会落后太多。当他们//落后太多时,在响应接收到的下一个请求时会有很长的延迟,而观察者//会赶上来。go wait.Until(func() {watermark.readOnlyObserver.Add(0)watermark.mutatingObserver.Add(0)}, observationMaintenancePeriod, stopCh) } -
WithMaxInFlightLimit代表限流处理函数
调用入口: staging\src\k8s.io\apiserver\pkg\server\config.go
DefaultBuildHandlerChain中,判断FlowControl为nil就开启WithMaxInFlightLimit,
if c.FlowControl != nil {requestWorkEstimator := flowcontrolrequest.NewWorkEstimator(c.StorageObjectCountTracker.Get)handler = filterlatency.TrackCompleted(handler)handler = genericfilters.WithPriorityAndFairness(handler, c.LongRunningFunc, c.FlowControl, requestWorkEstimator)handler = filterlatency.TrackStarted(handler, "priorityandfairness")} else {handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.LongRunningFunc)}func WithMaxInFlightLimit(handler http.Handler,nonMutatingLimit int,mutatingLimit int,longRunningRequestCheck apirequest.LongRunningRequestCheck,
) http.Handler {// 如果limit num为0就不开启限流了if nonMutatingLimit == 0 && mutatingLimit == 0 {return handler}var nonMutatingChan chan boolvar mutatingChan chan bool// 构造限流的chan,类型为长度=limit的 bool chanif nonMutatingLimit != 0 {nonMutatingChan = make(chan bool, nonMutatingLimit)klog.V(2).InfoS("Initialized nonMutatingChan", "len", nonMutatingLimit)} else {klog.V(2).InfoS("Running with nil nonMutatingChan")}if mutatingLimit != 0 {mutatingChan = make(chan bool, mutatingLimit)klog.V(2).InfoS("Initialized mutatingChan", "len", mutatingLimit)} else {klog.V(2).InfoS("Running with nil mutatingChan")}initMaxInFlight(nonMutatingLimit, mutatingLimit)// 发起请求return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {ctx := r.Context()requestInfo, ok := apirequest.RequestInfoFrom(ctx)if !ok {handleError(w, r, fmt.Errorf("no RequestInfo found in context, handler chain must be wrong"))return}// 检查是否是长时间运行的请求if longRunningRequestCheck != nil && longRunningRequestCheck(r, requestInfo) {handler.ServeHTTP(w, r)return}。。。。。。。。
}// LongRunningRequestCheck is a predicate which is true for long-running http requests.
type LongRunningRequestCheck func(r *http.Request, requestInfo *RequestInfo) bool
使用BasicLongRunningRequestCheck检查是否是watch或者pprof debug等长时间运行的请求,因为这些请求不受限制,位置
func BasicLongRunningRequestCheck(longRunningVerbs, longRunningSubresources sets.String) apirequest.LongRunningRequestCheck {return func(r *http.Request, requestInfo *apirequest.RequestInfo) bool {if longRunningVerbs.Has(requestInfo.Verb) {return true}if requestInfo.IsResourceRequest && longRunningSubresources.Has(requestInfo.Subresource) {return true}if !requestInfo.IsResourceRequest && strings.HasPrefix(requestInfo.Path, "/debug/pprof/") {return true}return false}
}
检查是只读操作还是修改操作,决定使用哪个chan限制
var c chan boolisMutatingRequest := !nonMutatingRequestVerbs.Has(requestInfo.Verb)if isMutatingRequest {c = mutatingChan} else {c = nonMutatingChan}
如果队列未满,有空位置,则更新排队数字
- 使用select 向c中写入true,如果能写入到说明队列未满
- 记录下对应的指标
select {case c <- true:// We note the concurrency level both while the// request is being served and after it is done being// served, because both states contribute to the// sampled stats on concurrency.if isMutatingRequest {watermark.recordMutating(len(c))} else {watermark.recordReadOnly(len(c))}// default代表队列已满defer func() {<-cif isMutatingRequest {watermark.recordMutating(len(c))} else {watermark.recordReadOnly(len(c))}}()handler.ServeHTTP(w, r)
但是如果请求的group中含有 system:masters,则放行, 因为apiserver认为这个组是很重要的请求,不能被限流.
- group=system:masters 对应的clusterRole 为cluster-admin, 队列已满,如果请求的group中没有 system:masters,则返回http 429错误,并且丢弃请求
// at this point we're about to return a 429, BUT not all actors should be rate limited. A system:master is so powerful// that they should always get an answer. It's a super-admin or a loopback connection.if currUser, ok := apirequest.UserFrom(ctx); ok {for _, group := range currUser.GetGroups() {if group == user.SystemPrivilegedGroup {handler.ServeHTTP(w, r)return}}}
- http 429 代表当前有太多请求了,请重试,并设置 response 的header Retry-After =1
// We need to split this data between buckets used for throttling.metrics.RecordDroppedRequest(r, requestInfo, metrics.APIServerComponent, isMutatingRequest)metrics.RecordRequestTermination(r, requestInfo, metrics.APIServerComponent, http.StatusTooManyRequests)tooManyRequests(r, w)func tooManyRequests(req *http.Request, w http.ResponseWriter) {// Return a 429 status indicating "Too Many Requests"w.Header().Set("Retry-After", retryAfter)http.Error(w, "Too many requests, please try again later.", http.StatusTooManyRequests)
}
1.2 Client限流
client-go默认的qps为5,但是只支持客户端限流,只能由各个发起端限制
- 集群管理员无法控制用户行为。
相关文章:
k8s API限流——server级别整体限流和客户端限流
1. 背景 为了防止突发流量影响apiserver可用性,k8s支持多种限流配置,包括: MaxInFlightLimit,server级别整体限流Client限流EventRateLimit, 限制eventAPF,更细力度的限制配置 1.1 MaxInFlightLimit限流 apiserver…...
在华为做了三年软件测试被裁了,我该怎么办
近年来,随着经济环境的变化和企业战略的调整,员工被裁员的情况变得越来越普遍。无论是因为企业经营困难还是因为业务调整,员工们都可能面临被裁员的风险。如果你也遇到了这样的情况,那么你应该怎么办呢? 首先…...
Spring cloud 限流的多种方式
在频繁的网络请求时,服务有时候也会受到很大的压力,尤其是那种网络攻击,非法的。这样的情形有时候需要作一些限制。本文主要介绍了两种限流方法,感兴趣的可以了解一下 目录 一、实战基于 Spring cloud Gateway 的限流 二、基于阿…...
Linux命令·top
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止…...
springmvc之系列文章
springmvc之编程步骤 springmvc初始化过程 用WebServlet和WebFilter干掉web.xml 没有web.xml怎么写web程序 一次GET请求在springmvc中是的处理流程 springMVC的handler都有哪些类型 springmvc主要组件简单介绍 springmvc 的Servlet WebApplicationContext springmvc 的…...
Matlab实现深度学习(附上完整仿真源码)
文章目录简单案例完整仿真代码下载简单案例 深度学习是一种能够自动学习和提取数据特征的机器学习方法,它已经在图像识别、语音识别、自然语言处理等领域取得了显著的成果。而Matlab作为一个强大的数学计算工具,也提供了丰富的深度学习工具箱࿰…...
我的谷歌书签
Form 表单 | Element Plusa Vue 3 based component library for designers and developershttps://element-plus.gitee.io/zh-CN/component/form.html#%E5%AF%B9%E9%BD%90%E6%96%B9%E5%BC%8F three.js exampleshttp://www.yanhuangxueyuan.com/threejs/examples/#software_geo…...
day3 数据库技术考点汇总
一、重点知识点 基本概念:三级模式-两级映像、数据库设计数据库模型:E-R模型、关系模型、关系代数(结合SQL语言)规范化:函数依赖、健与约束、范式、模式分解事务并发:并发三种问题、三级封锁协议数据库新技…...
学剪辑难吗 如何使用会声会影2023做剪辑视频
很多剪辑初学者都问过一个问题,学剪辑难吗?其实不论学什么,只要用心学都不难,今天我们就来讲讲如何学做剪辑视频,感兴趣的小伙伴们不要走开!一、学剪辑难吗 其实学剪辑并不是件难事,但是需要掌握…...
django学习日记
1、虚拟环境 virtualenv "加虚拟环境名字" 在当前目录下创建一个虚拟环境 进入虚拟环境执行activate进入该虚拟环境,再执行deactivate退出虚拟环境 安装一个包来管理虚拟环境,每次创建虚拟环境都放到同一位置,以及在任意位置都可…...
在线教学视频课程如何防止学员挂机?
阿酷TONY / 2023-3-31 / 长沙 / 原创 / 要不?交个朋友吧? 在线教学视频课程如何防止学员挂机?siri:这是个有意思的问题哈~~~在线教育、在线企业培训机构通常是如何处理的呢? 答:在视频播放过程中,弹出问题…...
【Redis】安装配置
文章目录Redis简介Redis版本迭代Redis安装配置官网地址操作系统环境基础查看本地redis版本修改配置文件docker容器安装redis测试linux版Redis简介 简介 与传统数据库关系(mysql),Redis是key-value数据库(NoSQL一种),mysql是关系数据库。Redis数据操作主要…...
ChatGPT批量生成文章-ChatGPT文章生成器
ChatGPT:一键批量生成高质量文章,提高生产效率! 随着信息爆炸的时代,文本生产成为了各个行业必不可少的一部分。但面对高强度的生产需求,人力资源却难以跟上步伐。现在,我们有一款基于人工智能和自然语言处…...
Linux命令 ——sed
介绍 sed 是一种流式文本编辑器,常用于在 Unix 和类 Unix 系统中对文本进行处理。它可以将文本从标准输入或文件中读取,对其进行修改,然后将修改后的文本输出到标准输出或文件中。sed 是 “stream editor” 的缩写。 语法 sed 的基本语法为…...
C++常用字符串string方法
文章目录字符串string操作方法1. 类方法使用示例2. 头文件cstring方法使用示例字符串string操作方法 1. 类方法 在C中,引入string.h头文件可以使用C语言中的字符串操作函数。然而,C提供了一个更加方便的字符串类string,不需要引入string.h头…...
XML树结构和语法
文章目录一、XML 树结构二、XML 语法规则总结一、XML 树结构 XML 树结构 XML 文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶"。 一个 XML 文档实例 XML 文档使用简单的具有自我描述性的语法: <?xml vers…...
【Qt】Qt单元测试详解(四):Google Test 断言
1、创建测试工程 【Qt】Qt单元测试详解(一):通过QtCreator创建测试工程 2、添加测试代码 2.1 默认生成的代码 1)项目工程pro include(gtest_dependency.pri)TEMPLATE = app CONFIG += console c++14 CONFIG -= app_bundle CONFIG += thread CONFIG -= qtHEADERS += \t…...
句柄和指针的区别
句柄和指针都是一种数据结构,都常用于访问内存,下面介绍他们的一些不同点。 1 数据结构类型不同 指针的数据类型是无符号整数,占用4或8个字节(在32位和64位系统中),它就像一个变量一样,这个变量…...
Linux 网络编程学习笔记——十四、多线程编程
目录 早期 Linux 不支持线程,直到 1996 年,Xavier Leroy 等人才开发出第一个基本符合 POSIX 标准的线程库 LinuxThreads 。但 LinuxThreads 效率低而且问题很多。自内核 2.6 开始,Linux 才真正提供内核级的线程支持,并有两个组织…...
JS 获取时区
JS 获取时区 啥是时区? 时区是地球上的区域使用同一个时间定义。以前,人们通过观察太阳的外置(时角)决定时间,这就使得不同经度的地方的时间各有不同,为了统一使用同一个时间,就引入了时区的概…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...
