k8s clientset 出现 Throttling request took 限流的解决方法
前言
又是一个月的忙忙碌碌,但是没啥很大的收获。但是在忙碌过程中,还是出现了一些小问题,特此记录一下。由于我们是做nocalhost开发的,也就是开发一个k8s开发工具, 所以不断的和k8s打交道,然后有个需求是获取资源树结构,也就是
- cluster- namespace- application- workloads- pod- deployment- statefulset- replicaset...- networks- service- ingress...
做这个需求是需要快速返回结果,插件端会不断的刷新这个树,所以很自然的用到的informer去做,也就是本地开informer,缓存不同类型的资源和数据。其实这一套informer已经写好了,并且速度也还可以
,但是突然有一天,大佬说是树展不开了,也就是获取资源卡住了,然后要来了kubeconfig,就开始了排错之旅。
分析
由于这块儿逻辑都是我写的,所以比较熟悉。单步调试后,到了 ServerPreferredResources
这里,卡住了。
func TestGetResource(t *testing.T) {kubeconfigBytes, _ := ioutil.ReadFile(clientcmd.RecommendedHomeFile)
config, _ := clientcmd.RESTConfigFromKubeConfig(kubeconfigBytes)
clientset, _ := kubernetes.NewForConfig(config)
restMappingList, _ := clientset.ServerPreferredResources()
fmt.Println(len(restMappingList))
}
这里跑了近30s,经过一顿操作,最终定位到是由于,k8s中有个apiserivce不可用导致的。
kubectl get apiservice --kubeconfig=aa
NAME SERVICE AVAILABLE AGE
...
v1beta1.discovery.k8s.io Local True 234d
v1beta1.events.k8s.io Local True 234d
v1beta1.extensions Local True 234d
v1beta1.external.metrics.k8s.io keda/keda-operator False (ServiceNotFound) 2d14h
v1beta1.getambassador.io Local True 35d
v1beta1.metrics.k8s.io kube-system/hpa-metrics-service True 38d
v1beta1.networking.istio.io Local True 3d16h
v1beta1.networking.k8s.io Local True 234d
...
然后我手动删除了这个apiservice,就恢复,方法 ServerPreferredResources
就很快返回了,也没有报错。
问题就这样解决了?
但是用户的集群资源,是不可以删除的。因此还得自己想办法。分析一下,apiservice是有aggregate
server创建的资源,目的是标识注册的服务,通过将对应类型的服务,转发到后端的service,进行查询和汇聚(不知道理解的对不对,欢迎大佬指正)
,而如果某个apiservice不可用了,那么其后台的服务应该也就不可以用了,那么请求这个apiservice可能就会超时。并且看了一眼方法 ServerPreferredResources
的输出
...
I0828 10:02:54.754702 91039 request.go:655] Throttling request took 1.152816427s, request: GET:https://cls-23a4ww3k.ccs.tencent-cloud.com/apis/custom.metrics.k8s.io/v1beta1?timeout=32s
I0828 10:02:58.754702 91039 request.go:655] Throttling request took 6.245363456s, request: GET:https://cls-23a4ww3k.ccs.tencent-cloud.com/apis/custom.metrics.k8s.io/v1beta1?timeout=32s
...
也就是被限速了,神奇了,然后全局搜索了一下 关键字 Throttling request took
, vendor/k8s.io/client-go/rest/request.go:580
, 发现
func (r *Request) tryThrottle(ctx context.Context) error {if r.rateLimiter == nil {return nil
}now := time.Now()err := r.rateLimiter.Wait(ctx)latency := time.Since(now)
if latency > longThrottleLatency {klog.V(3).Infof("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String())
}
if latency > extraLongThrottleLatency {// If the rate limiter latency is very high, the log message should be printed at a higher log level,
// but we use a throttled logger to prevent spamming.
globalThrottledLogger.Infof("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String())
}
metrics.RateLimiterLatency.Observe(r.verb, r.finalURLTemplate(), latency)return err
}
原来这里有个 RateLimiter
, 也就是限流器。然后一顿引用查看,最后找到,原来restclient.Config
是可以设置 RateLimiter
的
type Config struct {...
// QPS indicates the maximum QPS to the master from this client.
// If it's zero, the created RESTClient will use DefaultQPS: 5
QPS float32// Maximum burst for throttle.
// If it's zero, the created RESTClient will use DefaultBurst: 10.
Burst int// Rate limiter for limiting connections to the master from this client. If present overwrites QPS/Burst
RateLimiter flowcontrol.RateLimiter
...
}
可以从注释中看到,默认 QPS 是5,最大 QPS 是10,如果设置了 RateLimiter,将会覆盖 QPS 和 Burst 参数。所以果断覆盖
func TestGetResource(t *testing.T) {kubeconfigBytes, _ := ioutil.ReadFile(filepath.Join(homedir.HomeDir(), ".kube", "aa"))
config, _ := clientcmd.RESTConfigFromKubeConfig(kubeconfigBytes)
// 可以设置 RateLimiter
config.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(1000, 1000)
clientset, _ := kubernetes.NewForConfig(config)
}
而不过不设置这个参数,那么默认就是 然后就设置了一个1000 QPS的限流器,发现就没有限流提示,并且速度也很快了。终于是找到了一个两全奇美的办法啦,赞
k8s clientset 出现 Throttling request took 限流的解决方法相关推荐
- 限流是解决高并发大流量的一种方案,至少是可以保证应用的可用性
# 限流算法 推荐微信公众号:[矿洞程序员]文章由高端社区fameLink联合创始人陶德与我及其他社区大佬联合发表.关注[矿洞程序员]可获得大咖陶德的私人微信. 限流是解决高并发大流量的一种方案,至少 ...
- 使用nginx做反代时遇到413 Request Entity Too Large的解决方法
使用nginx做反代时遇到413 Request Entity Too Large的解决方法 参考文章: (1)使用nginx做反代时遇到413 Request Entity Too Large的解决 ...
- 亿级流量架构之服务限流思路与方法
为什么要限流 日常生活中,有哪些需要限流的地方? 像我旁边有一个国家AAAA景区,平时可能根本没什么人前往,但是一到五一或者春节就人满为患,这时候景区管理人员就会实行一系列的政策来限制进入人流量, 为 ...
- 抖音被限流怎么办,抖音被限流了解决办法介绍:国仁网络资讯
我们都知道现在是短视频的流量风口,所以很多人都想抓住短视频的红利了,可是往往事与愿违,为什么发布了那么久的视频内容,账号就莫名其妙的就被限流了,很多人在耗费了许多人力.物力.财力的情况下,得到的结果却 ...
- Nginx出现“413 Request Entity Too Large”错误解决方法
今天使用phpmyadmin的导入功能的时候,由于sql文件过大,服务器出现错误提示了,413 Request Entity Too Large,google了一下,发现是Nginx的错误提示. 解 ...
- MVC中提示错误:从客户端中检测到有潜在危险的 Request.Form 值的详细解决方法...
今天往MVC中加入了一个富文本编辑框,在提交信息的时候报了如下的错误:从客户端(Content="<EM ><STRONG ><U >这是测试这...&q ...
- ASP中 Request.Form中文乱码的解决方法
分享下解决方法 直接用request.Form()获取的是所有数据所以会有乱码(具体原因不祥) 用 VBScript code Foreachobj in Request.Form Response. ...
- 400 bad request的原因意思和解决方法
我们的电脑在使用的过程中,有的小伙伴在上网的时候可能就遇到过系统提示:400 bad request的情况.据小编所知这种情况,大致意思就是出现了错误的请求或者请求不能满足.原因是因为我们请求的语法格 ...
- 服务器返回431 Request Header Fields Too Large解决方法
访问服务器,出现这个问题 431 Request Header Fields Too Large 解决:清空浏览器的cookie缓存重新加载. 或者在nginx的HTTP模块中,修改 client_h ...
最新文章
- PHP性能如何实现全面优化?
- 视频讲解——零基础玩转微信小程序
- 给一个元素插入一段HTML
- centos svn 的搭建
- 汇编语言学习笔记(五)
- Sql Server 中存储过程的output return的区别
- 世界级数学家加入华为,曾获菲尔兹奖 网友:终于知道数理化的重要了
- golang | 变量-字符串练习
- lepus监控oracle数据库_数据库监控软件Lepus之修改admin密码
- bind函数怎么用JAVA_面试官:能解释一下javascript中bind、apply和call这三个函数的用法吗...
- svn中文语言包安装(内含语言包路径)
- 数据结构1800题-错题集-第二章
- win10声卡驱动问题:未检测到任何音频设备
- google 能翻译104个语言 youtube 仅仅不支持其中的15个语言 分别是这些
- 逻辑思维题总结与例题分析
- 后台Base64解码图片变小的坑
- java IO流基础 万字详解(从拷贝文件到模拟上传头像)
- VC语言文件正文分析器--支持格式常用文件格式
- XSS安全漏洞修复解决方案
- IDEA中对代码进行commit时,git报Unable to create ‘E:/blog/.git/index.lock‘: File exists问题解决