1. prometheus 介绍
Prometheus 是一种开源的系统监控和警报工具,最初由 SoundCloud 开发,现在由 Cloud Native Computing Foundation (CNCF) 维护。它专门设计用于在动态环境中监控大规模的分布式系统。
以下是 Prometheus 的一些主要特点和功能:
多维数据模型:Prometheus 使用多维数据模型来存储时间序列数据,每个时间序列由指标名称和一组标签组成,使得数据可以灵活地被查询和聚合。
灵活的查询语言:PromQL 是 Prometheus 的查询语言,它允许用户对时间序列数据进行高级查询、聚合和操作,以生成自定义的监控指标和警报条件。
持久化存储:Prometheus 使用本地存储引擎来持久化时间序列数据,可以配置多种存储后端,包括本地磁盘、远程对象存储等。
2. prometheus 如何接入及示例代码
maven依赖
1 2 3 4 5 6 7 8 9 10 11 <dependency > <groupId > io.prometheus</groupId > <artifactId > simpleclient</artifactId > <version > 0.11.0</version > </dependency > <dependency > <groupId > io.prometheus</groupId > <artifactId > simpleclient_httpserver</artifactId > <version > 0.11.0</version > </dependency >
指标项
计数器(Counter):
用途:计数器用于累积值,通常用于表示累积事件的总数,如请求数、任务完成数等。计数器的值只能增加,不能减少或重置。
示例:表示请求数的总数。
计量器(Gauge):
用途:计量器用于表示可变值,它可以增加、减少或重置。通常用于表示动态变化的数据,如内存使用量、并发连接数等。
示例:表示当前活跃用户数。内存占用数等
直方图(Histogram):
用途:直方图用于度量观察值的分布情况,并提供一组用于汇总这些观察值的统计信息,如总数、均值、分位数等。
示例:表示请求延迟的分布情况。
摘要(Summary):
用途:摘要与直方图类似,也用于度量观察值的分布情况。不同之处在于,摘要提供一组用于汇总这些观察值的统计信息,如总数、平均值、标准差等。
示例:表示响应时间的摘要信息。p99耗时统计等
指标项Counter
java代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import io.prometheus.client.CollectorRegistry;import io.prometheus.client.Counter;import io.prometheus.client.exporter.HTTPServer;import java.io.IOException;public class Main { private static final Counter requestsTotal = Counter.build() .name("myapp_requests_total" ) .help("Total number of requests." ) .labelNames("name" ) .register(); public static void main (String[] args) throws IOException { HTTPServer server = new HTTPServer (9090 ); simulateRequest(); server.stop(); } private static void simulateRequest () { requestsTotal.labels("simulate" ).inc(); } }
这代码中count就是一直增加,在未来图表中,可以用当前时间的数字减去1分钟前的数字,就能得到当前1分钟内请求数。
另外需要注意的是labelNames()
函数和labels()
函数。这两个是配合使用的。这里可以增加任意的维度。未来搜索或者作图可以更好地展现。
例如,我希望统计不同路径的访问请求。
那么我在labels('不同的path')
, 这样就能分路径进行统计了。
如果你想统计不同的路径,不同的客户端请求数量。那么在注册Counter时,需要这样调用
1 2 3 4 5 6 7 8 9 10 private static final Counter requestsTotal = Counter.build() .name("myapp_requests_total" ) .help("Total number of requests." ) .labelNames("path" , "clientType" ) .register(); .... requestsTotal.labels("请求的URI" , "iOS" ).inc(); requestsTotal.labels("请求的URI" , "Android" ).inc();
指标项Gauge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import io.prometheus.client.exporter.HTTPServer;import io.prometheus.client.Gauge;import java.io.IOException;public class MyApp { static final Gauge myGauge = Gauge.build() .name("my_gauge" ) .help("Example of a Gauge metric" ) .labelNames("label1" , "label2" ) .register(); public static void main (String[] args) throws IOException { HTTPServer server = new HTTPServer (8080 ); updateMetrics(); } static void updateMetrics () { while (true ) { myGauge.labels("value1" , "value2" ).set(42 ); try { Thread.sleep(5000 ); } catch (InterruptedException e) { e.printStackTrace(); } } } }
指标项Histogram
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import io.prometheus.client.exporter.HTTPServer;import io.prometheus.client.Histogram;import java.io.IOException;public class MyApp { static final Histogram requestDuration = Histogram.build() .name("http_request_duration_seconds" ) .help("HTTP request duration in seconds" ) .buckets(0.1 , 0.5 , 1 , 2 , 5 ) .register(); public static void main (String[] args) throws IOException { HTTPServer server = new HTTPServer (8080 ); handleRequest(); } static void handleRequest () { while (true ) { long startTime = System.currentTimeMillis(); long duration = System.currentTimeMillis() - startTime; requestDuration.observe(duration / 1000.0 ); } } }
这里的buckets定义了不同桶
[0, 0.1), [0.1, 0.5), [0.5, 1), [1, 2), [2, 5) [5, 正无穷)
当耗时0.3秒被记录时,Prometheus将增加[0, 0.1), [0.1, 0.5)
两个桶的值。
指标项Summary
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import io.prometheus.client.Summary;import io.prometheus.client.CollectorRegistry;Summary requestLatency = Summary.build() .name("http_request_duration_seconds" ) .help("HTTP request latency in seconds." ) .quantile(0.5 , 0.05 ) .quantile(0.9 , 0.01 ) .quantile(0.99 , 0.001 ) .register(); Summary.Timer requestTimer = requestLatency.startTimer(); requestTimer.observeDuration(); requestLatency.observe(cost_in_seconds)
3. prometheus 检查是否成功
这其实要看设置的监听端口是多少。例如
1 2 3 import io.prometheus.client.exporter.HTTPServer;... HTTPServer server = new HTTPServer (8080 );
那么上述代码的启动后,且有指标生成后,访问http://localhost:8080/metrics
就能看到相应的指标。
4. 使用注意事项
labels("value1", "value2")
中的value1
和value2
需要可数,不一定是枚举类型,但是数量是有限的。
buckets(0.1, 0.5, 1, 2, 5)
, 这里的值越多,统计性能就越低,占用的内存就越大
Histogram用于统计分布,Summary用来统计多少分位的数据。
Counter每次放入的是inc()或者inc(number),放入的是增量。 Gauge每次放入的是当前的数据。