您的位置:

PrometheusJava:Go语言编写的开源监控系统的Java客户端

  在现代化互联网应用的监控与运维领域,开源监控系统从以前的Nagios、Zabbix,逐渐地演化到了Prometheus。Prometheus是一款开源的监控告警系统,它由Google开发并开源出来,得到了很多公司和社区的支持。PrometheusJava是Prometheus监控系统的Java客户端,它是一款简易的开源Java客户端,可以在Java应用中启动一个HTTP服务,供Prometheus服务器进行查询。

一、容易上手

PrometheusJava使用起来相当简单。其最简单的使用场景就是在Java应用中启动一个HTTP服务,在prometheus.yml配置文件中定义好该服务的地址和端口,然后向该服务发送HTTP请求以获取数据。Prometheus server会定期去查询这个HTTP服务,获取指标相关数据。下面是一个使用示例:


Prometheus prometheus = new Prometheus();
prometheus.start(1234);

Gauge gauge = Gauge.build()
                     .name("cpu_temperature")
                     .help("Temperature of the cpu.")
                     .register();
gauge.set(65.3);

上述代码开启了一个HTTP服务并暴露了一个Gauge指标,对应的指标名为cpu_temperature。我们可以通过该指标来监控CPU温度。由于Prometheus偏爱push,因此我们不需要主动去访问Prometheus服务器来获取该指标。Prometheus服务器会自动定期向该服务发起HTTP请求,获取该指标相关数据。当然,在上述代码中,第一行通过prometheus.start(1234)启动了一个端口为1234的HTTP服务。

二、灵活的指标管理

PrometheusJava灵活地支持不同类型的指标。在Prometheus中,主要分为以下几种指标类型:Gauge、Counter、Histogram、Summary以及Custom。PrometheusJava支持以下几种指标类型:

  1. Gauge: 记录一个可变数值。
  2. Counter:表示一个可以增长的累计值。
  3. Histogram:表示一组采样数据的统计分布。
  4. Summary:用于记录持续时间或者大小的指标。
  5. Custom:自定义指标,满足特定的监控需求。

除此之外,PrometheusJava还提供了具有良好封装度的API。通过API,我们可以轻松创建指标和修改指标的值。下面是一些具体的例子:

1. Gauge指标:


Gauge gauge = Gauge.build()
                     .name("cpu_temperature")
                     .help("Temperature of the cpu.")
                     .register();
gauge.set(65.3);

该代码创建了一个名为cpu_temperature的Gauge类型指标,它的帮助文档信息为"Temperature of the cpu" 。并将其初始值设置为65.3。

2. Counter类型指标:


Counter counter = Counter.build()
                         .name("api_http_requests_total")
                         .help("Total number of HTTP requests made.")
                         .register();
counter.inc();

该代码创建了一个名为api_http_requests_total的Counter类型指标,其帮助文档信息为"Total number of HTTP requests made." 。并将其初始值设置为0。每次请求时,将其增加1。

3. Histogram类型指标:


Histogram histogram = Histogram.build()
                               .name("http_request_duration_seconds")
                               .help("Request latency in seconds.")
                               .register();
histogram.observe(4.7);

该代码创建了一个名为http_request_duration_seconds的Histogram类型指标,其帮助文档信息为"Request latency in seconds." 。Histogram类型指标存储一些有序的桶(bucket),每个桶标识一定范围内的数据。在上述代码中调用了observe方法,将值4.7记录到对应的桶中去。

4. Summary类型指标:


Summary summary = Summary.build()
                        .name("http_request_size_bytes")
                        .help("The request size in bytes.")
                        .register();
summary.observe(1024);

该代码创建了一个名为http_request_size_bytes的Summary类型指标,其帮助文档信息为"The request size in bytes." 。调用observe方法,将大小为1024字节的请求记录到相关数据中。

5. 自定义指标:


Gauge gauge = Gauge.build()
                     .name("user_sign_up")
                     .help("The number of users signed up.")
                     .labelNames("channel", "pay_method")
                     .register();
gauge.labels("appstore", "wechat_pay").inc();
gauge.labels("googleplay", "alipay").inc(2);

该代码通过Gauge.build()方法创建了一个名为user_sign_up的Gauge类型指标。Gauge.define()方法的labelNames定义了该指标具有的标签(不同标签值的组合可以识别不同的全局衡量的维度)。该定义将产生一些维度,例如,我们通过appstore渠道,使用wechat_pay支付方式的用户注册人数将会成为该Gauge类型指标的一个切片(slice)。我们可以多次调用inc方法,将标签值不同的事件统计到不同的切片中去。例如,上述代码中,对于appstore和使用wechat_pay支付方式的用户注册事件,我们调用inc方法,将该事件的计数增加了1。而对于googleplay和alipay这两个标签组合所对应的展示计数器,我们调用inc方法,将该事件计数增加了2。

三、Java SDK

PrometheusJava还提供了Java SDK,用户可以通过Java SDK来编写Java中的代码,直接向Prometheus服务器发送查询请求,从而得到监控数据。PrometheusJava的Java SDK,封装与Prometheus通讯相关的所有底层操作,使客户端能够轻松生成Prometheus服务器可以识别的格式。其提供了以下三个主要功能:

1. 标准PrometheusJava客户端:


PrometheusClient client = new PrometheusClient(new URL("http://localhost:9090"));

Map< String, Double > values =
         client.query(
                 "http_request_duration_seconds",
                 "job", "my-service",
                 "instance", "my-service:80"
         );

System.out.println(values);

该代码使用Prometheus Java SDK标准客户端来查询名为http_request_duration_seconds的指标。命令行参数指定了job和instance标签,对应的值分别为my-service和my-service:80。客户端将返回包含所有标签的数据映射。

2. 获取Series:


PrometheusClient client = new PrometheusClient(new URL("http://localhost:9090"));

List< Series > series =
          client.series(Collections.singletonList("http_request_duration_seconds"));

System.out.println(series);

该代码使用Prometheus Java SDK客户端获取指标的所有Series。Prometheus服务器将返回一个Series列表,其中每个Series表示相同标签的所有时间序列。这样的Series可以是相同的,仅标签名称或值不同,也可以彼此独立,因为它们有不同的标签集。

3. Range查询:


PrometheusClient client = new PrometheusClient(new URL("http://localhost:9090"));

Map
   > rangeResult =
        client.queryRange(
                "http_request_duration_seconds",
                "job", "my-service",
                "instance", "my-service:80",
                Instant.now().minusSeconds(24 * 3600),
                Instant.now(),
                600 /* step in seconds */
        );

for (String seriesName : rangeResult.keySet()) {
  for (Sample sample : rangeResult.get(seriesName)) {
     System.out.println(sample.toString());
  }
}

   

以上代码使用Prometheus Java SDK客户端执行范围查询。我们执行带有job标签和instance标签的http_request_duration_seconds指标。我们将查询时间范围限制在现在一天之前到现在,我们每10分钟提取一次样本。查询结果返回的样本可列表,每个样本都包含标签,时间戳和值。

结论

PrometheusJava提供了一系列关于Prometheus的监控的API,用户可以通过简单的代码,实现进程中服务的各种监控以及统计。PrometheusJava API易于使用,所有人都可以快速上手。它为监控提供了底层组件,从而让详细的,精确的,准确的监视数据条目变得容易。PrometheusJava库是漂亮的组件,它为任何Java应用程序提供了一个专业的统计查询系统。