使用 Spring Boot ✕ Prometheus ✕ Grafana 对应用程序进行监控
我开始考虑监控Spring Boot应用程序。
关于监控,我几乎是一个新手状态…
我們這次想要監控的項目不是系統相關的項目,如內存、線程等,而是與應用程序相關的值(例如每個API的吞吐量和調用次數)。因此,我們研究了具有完善的客戶端庫且能夠輸出與應用程序相關的監控項目的Prometheus和Spring Boot的組合。(另外,我們還結合了Grafana作為可視化工具。)
环境
我的环境如下。
-
- OS: macOS Sierra 10.12.6
-
- Java: 1.8.0_102
-
- Spring Boot: 1.5.10.RELEASE
-
- Docker For Mac: 17.12.0-ce-mac49
-
- Prometheus: v2.1.0
- Grafana: 5.0.0-beta4
关于普罗米修斯
普罗米修斯出现在官方网页的顶部。
从指标到洞察力。用领先的开源监控解决方案提供动力给您的指标和警报功能。
就像文中所写的那样,这是一个开源的监控工具。
我认为Prometheus最独特的特点是采用了Pull方式作为度量收集方法。其次,我认为它与Kubernetes相容性很好。关于其他特点和详细说明,请参考这篇文章以获取更多信息。[链接](https://developers.cyberagent.co.jp/blog/archives/3814/)
Prometheus有许多客户端库,支持主要的编程语言。(虽然可能并非官方支持…)
https://prometheus.io/docs/instrumenting/clientlibs/
此外,Java客户端库还支持Spring和Spring Boot。
这次我们使用Java客户端库和Spring Boot来设置监控并确认可以可视化WEB应用程序的API的吞吐量等数据。
这次的目标是WEB应用程序,不包括短期处理如批处理等。
批处理等需要使用Prometheus的pushgateway机制,但这次不包括在内。
如何将Prometheus客户端配置到Spring Boot应用程序中。
Prometheus使用了Pull方式进行度量收集,因此,在Spring Boot应用程序中,Prometheus客户端的作用是获取应用程序的度量并将其公开为端点。
实现这一目标的是simpleclient_spring_boot库。
在这里,我将对simpleclient_spring_boot库的内部和使用方法进行说明。
简化的客户端_春季启动
设置步骤
需要事先创建一个Spring Web应用程序。在这里,需要将spring-boot-starter-web添加到Maven的依赖关系中。
此外,还需要添加Spring Boot用的Prometheus客户端库到依赖关系中。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Prometheus library for spring boot-->
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_spring_boot</artifactId>
<version>0.2.0</version>
</dependency>
图书馆提供了两种注释选项。
-
- @EnablePrometheusEndpoint
- @EnableSpringBootMetricsCollector
将这些注释设置在应用程序端。
@SpringBootApplication
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
public class SpringBootPrometheusGrafanaSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootPrometheusGrafanaSampleApplication.class, args);
}
}
只需这样做,Spring所提供的指标就会显示在/prometheus的端点上。以下是关于该库更详细的说明。
@EnablePrometheusEndpoint -> 启用Prometheus端点
在Spring的Web应用程序中,用于注册/prometheus端点的注解。
独立使用时,只会显示空的指标(空响应)在/prometheus端点上。
需要单独追加指标,以及添加设置日志和垃圾回收等到此终结点中的指定地方。
(因此,@EnablePrometheusEndpoint是必需的,但@EnableSpringBootMetricsCollector只有在需要指标时才需要添加,不一定必须附加。)
课程的顺序是简单明了的。
我也已经总结了处理概要。
/prometheus
エンドポイントの追加。PrometheusMvcEndpoint/prometheus
エンドポイントの呼び出し処理。レスポンスのフィルターを行う。确认可以通过以下形式进行响应筛选。
如果不进行筛选,将输出所有项目。
http://localhost:8080/prometheus?name[]=jvm_threads_daemon&name[]=jvm_memory_bytes_used
启用Spring Boot指标收集器
增加Spring Actuator中的度量标准。
增加实现了(确保已注册Bean的)PublicMetrics接口的组件。
例如:TomcatPublicMetrics、SystemPublicMetrics。
以下是课程的顺序和处理概述。
添加Log Metrics
可以在Metrics中添加按Log级别的聚合。
# HELP logback_appender_total Logback log statements at various log levels
# TYPE logback_appender_total counter
logback_appender_total{level="debug",} 0.0
logback_appender_total{level="warn",} 0.0
logback_appender_total{level="trace",} 0.0
logback_appender_total{level="error",} 0.0
logback_appender_total{level="info",} 49.0
以下是設定。
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_logback</artifactId>
<version>0.2.0</version>
</dependency>
在resources/logback-spring.xml中添加InstrumentedAppender和根级别的METRICS日志。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="METRICS" class="io.prometheus.client.logback.InstrumentedAppender" />
<root level="INFO">
<appender-ref ref="METRICS" />
</root>
</configuration>
垃圾回收、内存池、JMX、类加载、线程计数的增加。
有些配置与Spring Actuator中的指标值重叠,但设置如下。
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.2.0</version>
</dependency>
在初始处理中调用DefaultExports.initialize()。
@SpringBootApplication
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
public class SpringBootPrometheusGrafanaSampleApplication {
public static void main(String[] args) {
DefaultExports.initialize();
SpringApplication.run(SpringBootPrometheusGrafanaSampleApplication.class, args);
}
}
增加方法单位的时间度量指标
使用Spring AOP可以通过方法级别来获取日志。
添加@EnablePrometheusTiming。
@SpringBootApplication
@EnablePrometheusEndpoint
@EnableSpringBootMetricsCollector
@EnablePrometheusTiming
public class SpringBootPrometheusGrafanaSampleApplication {
}
在方法上添加@PrometheusTimeMethod注解。
@RestController
public class HelloController {
@GetMapping("/hello")
@PrometheusTimeMethod(name = "hello_controller_say_hello_duration_seconds", help = "Some helpful info here")
public String sayHello() {
return "hello";
}
}
使用AOP,需要注意的是在同一类内部的方法调用和静态方法等不会受到@PrometheusTimeMethod的影响。
个别实施
如果上述只能通过设置来获取指标,但如果有某些应用程序的值无法通过设置获取,就需要在此介绍个别实现。
Prometheus提供了四种度量类型:Counter(计数器)、Gauge(仪表)、Summary(摘要)、Histogram(直方图)。请参考官方页面了解每种类型的详细信息。
我做了一个关于计数器实现的示例。
@RestController
public class CounterController {
private static int num = 0;
private static final Counter requests = Counter.build().name("count_requests_total").help("Total count requests.").register();
@GetMapping("count")
public int count() {
requests.inc();
return ++num;
}
}
如果有请求,它是一个控制器,会增加次数并返回,同时将该次数保存为指标。
Prometheus和Grafana的配置设置。
Grafana是一款开源的可视化工具,官方推荐在Prometheus的官方网站上使用Grafana。
https://prometheus.io/docs/visualization/grafana/
这里使用Docker构建了一个Spring Boot应用程序,Prometheus和Grafana。
虽然不会进行详细说明,但Dockerfile和docker-compose.yml如下所示。
FROM maven:3.5.2-jdk-8-alpine
ADD . /code
WORKDIR /code
RUN mvn clean package -DskipTests=true
CMD mvn spring-boot:run
version: '3'
services:
web:
build: .
ports:
- 8080:8080
volumes:
- .:/code
prometheus:
image: prom/prometheus
container_name: prometheus
volumes:
- ./env/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- 9090:9090
grafana:
image: grafana/grafana
container_name: grafana
ports:
- 3000:3000
env_file:
- ./env/grafana.env
由于Grafana的配置不需要特定的设置,故准备了grafana.env作为用于修改Grafana配置的文件,但是由于没有必要进行任何配置,因此它是一个空文件。
prometheus.yml – Prometheus配置文件.
几乎是从“入门指南”中获取的信息…
抱歉,我对Prometheus的设置不太熟悉…
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'codelab-monitor'
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
# sample
scrape_configs:
- job_name: 'sample-random'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
metrics_path: /prometheus
static_configs:
- targets: ['web:8080']
简单补充一下,’job_name: ‘prometheus’部分是Prometheus自身的监控,’job_name: ‘sample’部分是针对本次WEB应用程序的配置部分。
请注意的要点有两个,
-
- Prometheusがモニタリングするデフォルトのエンドポイントは/metricsのため、変更のためmetrics_path: /prometheusを追加
- WEBアプリケーションがDocker内のため、targetsのURLにDockerのnameを使っている
普罗米修斯的图形用户界面确认
Prometheus的默认端口是9090,所以当访问http://localhost:9090/时,会显示Prometheus。
在本地9090端口的图形界面中可以进行基本的显示。
比如,可以根据日志级别显示日志数量。
只需要从下拉列表中选择[logback_appender_total],然后点击[执行]即可。


请确认Grafana的图形用户界面。
如果没有特别设置的话,默认情况下Grafana的端口是3000,可以通过访问http://localhost:3000/来进行访问。如果没有设定特别的情况下,可以使用admin/admin进行登录。

以下是数据源的设定。

选择[创建] -> [仪表盘] -> [图表](根据要显示的内容进行更改)。

选择显示的图表,并选择[编辑]。

只要添加一个表格,图形就会显示出来。

感受
通过使用Prometheus,在稍微修改客户端源代码的前提下,可以获取到在应用程序监控中所需的信息。
由于修改量不大,所以易于使用。
特别是对于Spring Boot应用程序来说,能够立即使用是非常具有吸引力的。
然而,在其他监控工具中也有能够获取应用程序信息的工具。
例如,如果是使用New Relic APM,就可以显示每个事务的吞吐量。
因此,将来可能会需要与其他监控工具进行比较。
GitHub → GitHub是一个版本控制和协作平台。
这次的示例源代码像往常一样在GitHub上公开。
https://github.com/aha-oretama/spring-boot-prometheus-grafana-sample
在汉语中,只需要一种选项来转述以下内容:“参考”。
-
- https://prometheus.io/
-
- https://github.com/prometheus/client_java
- http://www.baeldung.com/spring-boot-actuators