prometheus PromSQL使用小技巧
前言
这个礼拜一面在找那个CrashLoopBackOff的原因,另一个是在尝试修复es报错Data too large的问题,还有一个任务就是解析告警规则了,因为新需求加了很多类型的告警,支持的维度也更多了,我们的告警使用的Prometheus + Alertmanager,之前的几篇博客也提到过,这里主要想记录一下我在解析规则这里,遇到的一些问题以及解法。
抛出问题
Counter类型计算过去一个时间段内的增量
举例问题:计算revision_request_count过去五分钟的请求次数?
问题分析:revision_request_count是queue-proxy上报的指标,用于记录knative创建的pod请求次数,熟悉Prometheus的同学都知道,prometheus有四种数据类型,其中counter是只增不减的,比如http请求次数,一分钟内请求一次是1,第二分钟再请求一次是2,然后第三分钟一直不请求,那么值就一直是2,这时候在第四分钟的时刻,计算过去一分钟内,请求的次数,就是0。首先遇到问题不要怕,翻开Promemtheus的官方手册可以看见有个函数叫做increase(),可以计算counter类型过去时间的增量
解法:
increase(revision_request_count{pod=~"api.*"}[5m])
PromSQL是支持正则的,因此可以使用正则表示式的语法,这里使用了约等于。同时需要注意一点的是,incease()函数是基于rate()函数得来的,因此这里可能会有小数点的情况,因此,可以使用round()函数进行取整:
round(increase(revision_request_count{pod=~"api.*"}[5m]))
Counter类型画增量折线图
举例问题:查询revision_request_count过去一小时内,每五分钟的请求次数?
分析:这个问题是可以在上一个问题的基础上引申,上面已经做到了对过去5分钟的请求次数,这里只需要为这个过去指定一个时刻,就可以计算出一个小段一个小段的值。promehteus的查询语句分为两种,一种是query,一种是query_range,query_range的语法:
curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s'
那么问题的答案也出来了
答案:
query_range?query=round(increase(revision_request_count{pod=~"api.*"}[5m]))&start=2021-02-27T16:00:00.000Z&end=2021-02-27T17:00:00.000Z&step=5m'
注意这里的step=5m需要和[5m]保持一值。
根据已有标签,按规则增加新的标签
举例问题:由于knative带有扩容特性,使用了kpa或者hpa都可以对pod按照cpu或者concurrency进行扩容,也就是会生成许多类似于如下这样的pod:
test-001-deployment-bf7dc8f95-xadjk
test-001-deployment-bf7dc8f95-gfd5b
test-001-deployment-bf7dc8f95-mgxtv
test-002-deployment-5fcfdbfc4-xx6cs
test-002-deployment-5fcfdbfc4-bw6rd
test-003-deployment-68f88c67c-6ng7n
test-003-deployment-68f88c67c-aferd
其中test为服务名称,001表示第一个版本,002表示第二个版本,003表示为第三个版本,deployment是自定义的后缀,第一个随机段是replicaset的标识,第二个随机段是pod的标识,
那么revison_request_count的值就会是这样的:
revision_request_count(pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(pod="test-003-deployment-68f88c67c-aferd", namespace="test")
需求是能够按照不同版本或者不同服务对revision_request_count进行聚合
分析:这里想到的第一个解决方式是使用group分组(Java的stream用的太多的后遗症),而prometheus也有相应用法,比如 sum by (namespace, pod)(),但这里by的是label,无法支持正则分组,因次此法不通。一度难倒我了,有点儿手足无措的感觉,不过还好我翻看prometheus官方文档的时候,找到这样一个函数label_replace(),可以将label按照正则表达式切分,然后取其中的一段,作为新的标签加入到指标中。举例:
label_replace(revision_request_count{namespace="test",container="user-container", pod=~"test.deployment.*|.*"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*")
解释一下,label_replace()函数,会对pod标签,按照 "(.*).[0-9]{3}.deployment.*"模式进行匹配,如果匹配不到,则无变化,如果匹配到了,那么就将service=$1(正则匹配的第一个串,这里是test)加入到label中,在本例中,也就是会增加service=test这个标签。细心的小伙伴会发现,pod=~“test.deployment.*|.*”,这里使用了竖线|这个语法是指或者的意思,约等于a,或者约定于b,取的是并集。同时支持正则,如果使用.*则标识所有,注意不是一个星*,而是.*,这里只是演示|的作用。
返回的结果:可以看见增加了一个标签
revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(service="test", pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(service="test", pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(service="test", pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(service="test", pod="test-003-deployment-68f88c67c-aferd", namespace="test")
以上是对服务进行聚合的,要对于服务的不同版本聚合,可以稍微更改一下正则表达式
label_replace(revision_request_count{namespace="test",container="user-container", pod=~"test.deployment.*|.*"}[5m]), "service","$1","pod","(.*).deployment.*")
数据就是这样的:可以看见增加了一个标签revision
revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(revision="test-002", pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(revision="test-002", pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(revision="test-003", pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(revision="test-003", pod="test-003-deployment-68f88c67c-aferd", namespace="test")
按照版本聚合
这里需要基于上面那个例子,不过指标名称可能会发生少许变化,revsion_request_count改成kube_pod_container_status_running,正在运行的实例数,细心的小伙伴会发现这里使用到了一个函数,max_over_time(),这里是取过去一段时间内最大的值,相应的还有max_over_time(),avg_over_time(),感兴趣的小伙伴可以可以参考官方文档
sum by(revision)(label_replace(max_over_time(kube_pod_container_status_running{namespace="test", pod=~"test.[0-9]{3}.deployment.*|.*"}[5m]), "revison","$1","pod","(.*).deployment.*"))
按照服务聚合
这时候就可以按照服务名进行聚合了,比如:
sum by(service)(label_replace(max_over_time(kube_pod_container_status_running{namespace="test", pod=~"test.[0-9]{3}.deployment.*|.*"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*"))
后记
其实knative中还有许许多多的指标,比如:
可以按照http状态码拿到不同服务的访问次数:
sum by (revision_name)(sum_over_time(revision_request_count{namespace="test",service_name=~"test",revision_name=".*", response_code=~"302|304"}[5m]))
拿到服务过去5分钟内的由于oom导致的重启次数:
sum by (service)(label_replace(sum_over_time(kube_pod_container_status_terminated_reason{namespace=~test,pod=~".*",container="user-container",reason="OOMKilled"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*"))
拿到某服务某版本过去5m cpu使用率:
sum by (revision)(label_replace(max_over_time(pod_cpu_limit_usage{namespace="test",pod=~".*"}[5m]),"revision","$1", "pod","(.*).deployment.*"))
拿到某服务某版本过去5m memory使用率:
sum by (revision)(label_replace(max_over_time(pod_memory_limit_usage{namespace="test",pod=~".*"}[5m]),"revision","$1", "pod","(.*).deployment.*"))
prometheus能拿到的信息简直是太多了,我这里只是列举了我工作中常用到的一些指标,希望对大家有所帮助。
prometheus PromSQL使用小技巧相关推荐
- 细说接口性能优化的11个小技巧
前言 接口性能优化对于从事后端开发的同学来说,肯定再熟悉不过了,因为它是一个跟开发语言无关的公共问题. 该问题说简单也简单,说复杂也复杂. 有时候,只需加个索引就能解决问题. 有时候,需要做代码重构. ...
- 详细的聊聊接口性能优化的11个小技巧 不收藏对不起我
前言 接口性能优化对于从事后端开发的同学来说,肯定再熟悉不过了,因为它是一个跟开发语言无关的公共问题. 该问题说简单也简单,说复杂也复杂. 有时候,只需加个索引就能解决问题. 有时候,需要做代码重构. ...
- 聊聊接口性能优化的11个小技巧
点击下方"IT牧场",选择"设为星标" 前言 接口性能优化对于从事后端开发的同学来说,肯定再熟悉不过了,因为它是一个跟开发语言无关的公共问题. 该问题说简单也简 ...
- Prometheus PromSQL
Prometheus PromSQL tags: prometheus 文章目录 Prometheus PromSQL 1. 简介 2. 目标 3. 架构 4. 场景 4.1 临时查询 4.2 仪表盘 ...
- latex 公式不居中_LaTex小技巧,祝你论文一臂之力!
LaTex作为常用的排版系统,已深入到大家的工作和学业中.但是很多小伙伴反馈说:LaTex公式编辑复杂.表格处理麻烦等.为此,我们特别收集了一些LaTex的小技巧,希望大家都可以get到! 公式篇 首 ...
- 中文 查询_查询商标,商标注册通过分析的几个小技巧
前面我们说到了商标注册前,通常情况下一定要进行商标查询,要进行注册通过可行性分析.只有这样才能保证基本的商标注册通过率,不至于无畏的浪费我们的时间和金钱. 1.我们在进行商标查询,输入要查询的商标时, ...
- 日常安排php,PHP日常开发小技巧
PHP日常开发小技巧 导语:PHP语言中,如果你懂得一些开发技巧,那么对你学PHP,会有很大的帮助.下面的是百分网小编为大家整理的PHP日常开发小技巧,希望对你能有所帮助. PHP批量取得checkb ...
- 敲代码括号技巧_阅码神奇Souceinsight使用小技巧总结
/****与SI的初遇****/ 对于大部分人第一次使用SI来说应该是对原IDE集成开发环境有很大的抱怨吧,确实我也一样,对于做嵌入式开发使用各种集成开发工具,比如说Keil,IAR等等,可能还有更加 ...
- eplan文本怎么换行_EPLAN几个使用的小技巧,非常有用
Eplan P8 的一些小技巧 1. 页名后缀由字母变数字 ? 选项 - 设置 - 项目 - 管理 - 页 - 页名 - 子页标识 2. 修改自动连接电缆颜色 ? 选项 - 层管理 - 符号图形 3. ...
最新文章
- 配置文件http://www.cnblogs.com/Jevon-ran/p/7112007.html
- Android(五)——dex文件动态调试
- Android7.0 Doze模式分析(一)Doze介绍 amp; DeviceIdleController
- LeetCode String Compression
- 如何利用ide进行跟踪调试_使用调试器进行事后跟踪
- viper4android最新版卡刷包,viper4android fx音效驱动
- 基于SpringCloud开发的分布式系统,遇到爬虫、接口盗刷怎么办?
- 如何获取一个需要登录页面的HTML代码
- java socket 出现丢包_Java知识——网络编程、三次握手四次挥手
- iOS测试技巧:GPX文件修改经纬度
- php酒店系统论文,PHP酒店网站管理系统毕业论文
- cf黑机器多久解除_CF永久解除机器码|CF机器码硬解封详细步骤教程+工具|CF辅助-QQ知啦娱乐网...
- Magic Cube
- 网络语言2019流行语C位解,最新骂人网络语言 2019网络骂人流行语大全
- laravel5.5利用网易邮箱发送邮件
- 记录高德地图H5导航
- 区块链游戏的抢滩之战
- 体验移动100M宽带
- 163邮箱不需要手机号,群发邮件工具,邮件营销工具
- 什么是空气质量自动监测系统
热门文章
- 攻防世界 re insanity
- 我的世界网易服务器修改世界,我的世界:1.16改变两个版本更新频率?网易版异常乱封大批账号?...
- div 设置a4大小_javascript – 拉伸div到A4大小
- 为什么计算机桌面下面没有显示不出来,电脑底下一排图标没了,桌面底部任务栏不见了...
- Windows桌面任务栏上面无线网显示不见了如何解决
- 两次考研失利!但这一次「我没输」
- 回溯法求解0-1背包问题
- 神一样的编程语言? -- 发现一个编程语言“shen”
- win10下node.js升级
- 车牌识别(一)——车牌定位(附详细代码及注释)