Prometheus 是由 SoundCloud 开源监控告警解决方案。一个开源的服务监控系统和时间序列数据库。
Prometheus会将所有采集到的样本数据以时间序列(time-series)的方式保存在内存数据库中,并且定时保存到硬盘上。
时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:
指标(metric):指标名和描述当前样本特征的标签集;
时间戳(timestamp):一个精确到毫秒的时间戳;
样本值(value): 一个float64的浮点型数据表示当前样本的值。
时间序列是按照时间戳和值顺序存放的。
瞬时向量,你可以看一个时间点的时序序列,它反映的是一个时间点不同标签的值组成的时间序列,如:
http_server_requests_seconds_count
范围向量,你可以看做带有中括号时间限制的时序序列,它反映的是一段时间范围内的值组成的时间序列,时间单位可以是:s、m、h、d、w、y,如:
http_server_requests_seconds_count[5m]
纯量只有一个数字,没有时序,例如:count(http_server_requests_seconds_count)
一个简单的字符串值
直接使用字符串,作为PromQL表达式,则会直接返回字符串。
Prometheus的客户端软件包中提供了4 种核心的指标类型,这四种类型仅仅在客户端存在区别,在服务端存储时转换为无类型的时间序列。
累加器或者称作计数器,统计的指标值只能增加,不能减少(除非系统发生重置),增加值不一定为1,可以用于请求的总数、访问时间的总和。
常见的监控指标,如 http_requests_total,node_cpu 都是 Counter 类型的监控指标。
指数器,可增可减的仪表盘,侧重于反应系统的当前状态,指示当前统计的指标值的大小,值可以增大也可以减小,主要用户统计当前cpu 的温度、最近一次访问的耗时。
常见指标如:node_memory_MemFree(主机当前空闲的内容大小)、node_memory_MemAvailable(可用内存大小)都是Gauge类型的监控指标。
对于Gauge类型的监控指标,通过PromQL内置函数delta()可以获取样本在一段时间返回内的变化情况。例如,计算CPU温度在两个小时内的差异:
delta(cpu_temp_celsius{host="a"}[2h])
还可以使用deriv()计算样本的线性回归模型,甚至是直接使用predict_linear()对数据的变化趋势进行预测。例如,预测系统磁盘空间在4个小时之后的剩余情况:
predict_linear(node_filesystem_free{job="node"}[1h], 4 * 3600)
主用用于统计和分析样本的分布情况
直方图,统计指标值分散在不同区间的个数。相当于针对Gauge 做了一次再加工,统计的时候就将分散在不同区间的个数统计好了。比如统计每次访问耗时的数据分布情况,用Histogram 可以统计小于200 ms的访问次数,小于300 毫秒的次数,小于500 毫秒的次数等等
主用用于统计和分析样本的分布情况
概述,它的作用我们通过一个例子来说明:比如我们监测的指标值为每次请求的响应时间,用Summary 可以统计5min 内95% 的请求的响应平均用时,5min 内80% 的请求的响应用时……。我们也可以统计10 min内60% 的请求的响应的平均用时……其实Summary 也是针对Counter 或者 Gauge 做的再次加工,只是在记录到数据库之前它计算好了再存入数据库。它和Histogram 针对同一监测指标的区别是Summary 将次数作为横坐标, Histogram 是将次数作为纵坐标。
都包含 < basename> _sum,< basename>_count
Histogram通过histogram_quantile函数是在服务器端计算的分位数。 而Sumamry的分位数则是直接在客户端计算完成。因此对于分位数的计算而言,Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。反之对于客户端而言Histogram消耗的资源更少。
=~:选择匹配正则表达式的标签(或子标签)
例:
http_server_requests_seconds_sum{ uri=~'.*admin.*' } # 包含admin的uri
所有的PromQL表达式都必须至少包含一个指标名称(例如http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如{code=“200”})。
查询指标http_server_requests_seconds_count:
http_server_requests_seconds_count
查询指标http_server_requests_seconds_count,且状态=4xx:
http_server_requests_seconds_count{status=~"4.."}
查询指标http_server_requests_seconds_count,且job以server结尾的5分钟内的所有样本数据:
http_server_requests_seconds_count{status=~"4.."}[5m]
查询指标http_server_requests_seconds_count,且job以server结尾的5分钟内的数据比率:
rate(http_server_requests_seconds_count{status=~"4.."}[5m])
访问数前十:
topk(10,http_server_requests_seconds_count)
一些表达式:
接口请求异常
http_server_requests_seconds_count{exception!="None",profile="$profile", application=~"$application", instance=~"$instance"}
应用CPU占比
process_cpu_usage{job=" $ {app}"} * 100 > $ {value}
JVM堆内存使用率监控
sum(jvm_memory_used_bytes{job=" $ {app}", instance=" $ {instance}", area="heap"})*100/sum(jvm_memory_max_bytes{job=" $ {app}",instance=" $ {instance}", area="heap"}) >${value}
全局CPU使用率监测
100 - ((avg by (instance,job,env)(irate(node_cpu_seconds_total{mode="idle"}[30s]))) *100) > ${value}
内存使用率
((node_memory_MemTotal_bytes -(node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes) )/node_memory_MemTotal_bytes ) * 100 > ${value}
注:任意一个独立的数据源(target)称之为实例(instance)。
包含相同类型的实例的集合称之为作业(job)。
rate、irate计算范围向量中时间序列的每秒即时增长率,即计算每秒的平均增加数
注意这里要配合时间来用。
rate取的是指定时间范围内所有数据点,适合缓慢变化的计数器(counter)
irate取的是在指定时间范围内的最近两个数据点来算速率,适合快速变化的计数器(counter),可以避免在时间窗口范围内的“长尾问题”。
increase函数获取区间向量中的第一个后最后一个样本并返回其增长量。
increase(node_cpu_seconds_total[2m]) / 120
这里通过node_cpu_seconds_total[2m]获取时间序列最近两分钟的所有样本,increase计算出最近两分钟的增长量,最后除以时间120秒得到node_cpu_seconds_total样本在最近两分钟的平均增长率。并且这个值也近似于主机节点最近两分钟内的平均CPU使用率。
约等于:
rate(node_cpu_seconds_total[2m])
避免在时间窗口范围内的“长尾问题”,计算瞬时增长率:
irate(node_cpu_seconds_total[2m])
注:长尾问题:如果大多数 API 请求都维持在 100ms 的响应时间范围内,而个别请求的响应时间需要 5s,那么就会导致某些 WEB 页面的响应时间落到中位数的情况
alert: name #告警名
expr: count(sum(irate(http_server_requests_seconds_sum[5m])) by (job,uri)/sum(irate(http_server_requests_seconds_count[5m])) by (job,uri) >3)>0 #表达式
for: 1h #评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。
labels:
serverity: warning #自定义标签
annotations: #用于指定一组附加信息,
summary: 'api {{ $labels.uri}}' #自定义摘要
description: '' #自定义具体描述
参考:
https://yunlzheng.gitbook.io/prometheus-book/
https://izoyo.cn/index.php/archives/40/
https://shared-code.com/article/84
https://www.jianshu.com/p/f77047fd8dca
https://www.bookstack.cn/books/prometheus_practice
http://devgou.com/article/Prometheus/