Prometheus

Prometheus 是由 SoundCloud 开源监控告警解决方案。一个开源的服务监控系统和时间序列数据库。

1、数据类型

Prometheus会将所有采集到的样本数据以时间序列(time-series)的方式保存在内存数据库中,并且定时保存到硬盘上。
时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:
指标(metric):指标名和描述当前样本特征的标签集;
时间戳(timestamp):一个精确到毫秒的时间戳;
样本值(value): 一个float64的浮点型数据表示当前样本的值。
时间序列是按照时间戳和值顺序存放的。

瞬时数据(Instant vector )

瞬时向量,你可以看一个时间点的时序序列,它反映的是一个时间点不同标签的值组成的时间序列,如:

http_server_requests_seconds_count
区间数据(Range vector )

范围向量,你可以看做带有中括号时间限制的时序序列,它反映的是一段时间范围内的值组成的时间序列,时间单位可以是:s、m、h、d、w、y,如:

http_server_requests_seconds_count[5m]
纯量数据(Scalar [ˈskeɪlə( r )])

纯量只有一个数字,没有时序,例如:count(http_server_requests_seconds_count)

字符串(String)

一个简单的字符串值
直接使用字符串,作为PromQL表达式,则会直接返回字符串。

2、指标类型

Prometheus的客户端软件包中提供了4 种核心的指标类型,这四种类型仅仅在客户端存在区别,在服务端存储时转换为无类型的时间序列。

Counter

累加器或者称作计数器,统计的指标值只能增加,不能减少(除非系统发生重置),增加值不一定为1,可以用于请求的总数、访问时间的总和。
常见的监控指标,如 http_requests_total,node_cpu 都是 Counter 类型的监控指标。

Gauge[ɡeɪdʒ]

指数器,可增可减的仪表盘,侧重于反应系统的当前状态,指示当前统计的指标值的大小,值可以增大也可以减小,主要用户统计当前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)
Histogram

主用用于统计和分析样本的分布情况
直方图,统计指标值分散在不同区间的个数。相当于针对Gauge 做了一次再加工,统计的时候就将分散在不同区间的个数统计好了。比如统计每次访问耗时的数据分布情况,用Histogram 可以统计小于200 ms的访问次数,小于300 毫秒的次数,小于500 毫秒的次数等等

Summary

主用用于统计和分析样本的分布情况
概述,它的作用我们通过一个例子来说明:比如我们监测的指标值为每次请求的响应时间,用Summary 可以统计5min 内95% 的请求的响应平均用时,5min 内80% 的请求的响应用时……。我们也可以统计10 min内60% 的请求的响应的平均用时……其实Summary 也是针对Counter 或者 Gauge 做的再次加工,只是在记录到数据库之前它计算好了再存入数据库。它和Histogram 针对同一监测指标的区别是Summary 将次数作为横坐标, Histogram 是将次数作为纵坐标。

Histogram vs Summary

都包含 < basename> _sum,< basename>_count
Histogram通过histogram_quantile函数是在服务器端计算的分位数。 而Sumamry的分位数则是直接在客户端计算完成。因此对于分位数的计算而言,Summary在通过PromQL进行查询时有更好的性能表现,而Histogram则会消耗更多的资源。反之对于客户端而言Histogram消耗的资源更少。

3、PromQL

=~:选择匹配正则表达式的标签(或子标签)
例:

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)。

4、函数

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 页面的响应时间落到中位数的情况

5、告警:
    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/

你可能感兴趣的:(Java)