0%

使用Prometheus监控SpringBoot应用的状态

一直关注于业务实现及业务架构设计,很少去关注一些运营方面的东西,但是面试架构师所需要的正是运营方面的知识,这样的短板会让我在面试的时候很尴尬。

业务架构师封神,运营架构师则是猪一般,真不应该。

一、前言

我们都喜欢使用SpringBoot来开发Java Application,随着使用中间件越来越多,Application的健康状态及用量状态变成了我们所关心的事情,因为其中任何一个连接中间件的状态都反应着Application的健康,影响着应用的正常运行。

所以,SpringBoot提供了相关的Starter来实现这个功能,结合Prometheus和Grafana,即可方便地监控应用的工作状态。

二、SpringBoot Actuator - 应用状态支持

Actuator提供了监控SpringBoot Application状态的功能,并提供一些Endpoint来访问这些状态。

集成Actuator

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

这时访问http://localhost:8080/actuator 则可访问应用的状态综合信息,表现为一些信息的链接地址:

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
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
"health-path": {
"href": "http://localhost:8080/actuator/health/{*path}",
"templated": true
},
"info": {
"href": "http://localhost:8080/actuator/info",
"templated": false
},
"prometheus": {
"href": "http://localhost:8080/actuator/prometheus",
"templated": false
},
"metrics": {
"href": "http://localhost:8080/actuator/metrics",
"templated": false
},
"metrics-requiredMetricName": {
"href": "http://localhost:8080/actuator/metrics/{requiredMetricName}",
"templated": true
}
}
}

可以通过/actuator/health查看应用的健康状态,通过/actuator/info查看应用的相关信息,通过/actuator/metrics查看应用的相关指标信息。

默认情况下,SpringBoot仅支持infohealth两个Endpoint,如果要增加更多的Endpoint,那需要在application.yaml中配置更多的Endpoint:

1
2
3
4
5
management:
endpoints:
web:
exposure:
include: metrics,info,health,prometheus

1. /actuator/health 应用健康状态

默认仅只显示应用的总状态:

1
2
3
{
"status": "UP"
}

但是有时statusDOWN的时候,我们需要查看更为详细的信息,则需要配置appliation.yaml文件,加入下面的配置:

1
2
3
4
management:
endpoint:
health:
show-details: always

由它输出了应用的总状态及各子状态,通过根下的status,可以判断应用现在是否全部状态健康,任何一个子状态为DOWN都会影响整个应用状态为DOWN,只有全部子状态为UP的时候,总状态才为UP

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
{
"status": "DOWN",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 1023966232576,
"free": 933139533824,
"threshold": 10485760
}
},
"fuck": {
"status": "UP",
"details": {
"target": "Linux",
"times": 20
}
},
"ping": {
"status": "UP"
},
"redis": {
"status": "DOWN",
"details": {
"error": "org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379"
}
}
}
}

2. /actuator/info 应用信息

输出JSON如下:

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
{
"author": "kut@sanlea.cn",
"name": "actuator-study",
"git": {
"branch": "master",
"commit": {
"id": "7cd87ca",
"time": "2019-12-25T09:26:41Z"
}
},
"build": {
"encoding": {
"reporting": "UTF-8",
"source": "UTF-8"
},
"version": "1.0",
"artifact": "actuator-study",
"java": {
"source": "13",
"target": "13"
},
"name": "actuator-study",
"time": "2019-12-25T10:36:50Z",
"group": "com.sanlea.study"
}
}

我们会看到一些应用相关的信息,例如git、build。

上面的信息需要进行配置才能显示出来,否则默认为空:

1
{}

应用信息配置

我们需要修改application.yaml来实现,只需要一个infokey即可:

1
2
3
info:
author: kut@sanlea.cn
name: ${spring.application.name}

构建信息配置

我们需要对pom.xml进行配置,由maven在构建时生成/META-INF/build-info.properties,从而实现信息输出:

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
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>

<!-- 配置在这里 -->
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<additionalProperties>
<time>${maven.build.timestamp}</time>
<encoding.source>UTF-8</encoding.source>
<encoding.reporting>UTF-8</encoding.reporting>
<java.source>${maven.compiler.source}</java.source>
<java.target>${maven.compiler.target}</java.target>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

GIT 信息

我们需要对pom.xml进行配置,由maven在构建时生成/META-INF/git.properties,从而实现信息输出:

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
</plugins>
</build>

在上面的配置后,我们的/actuator/info列出我们想要的应用信息。

3. /actuator/metrics 应用指标状态

一般我们还需要了解应用的指标状态,诸如以下的指标也是我们所关心的:

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
"jvm.threads.states", 
"process.files.max",
"jvm.gc.memory.promoted",
"http.server.requests",
"jvm.memory.max",
"jvm.memory.used",
"system.load.average.1m",
"jvm.gc.max.data.size",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"jvm.gc.pause",
"jvm.buffer.memory.used",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"jvm.threads.live",
"jvm.threads.peak",
"process.uptime",
"process.cpu.usage",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"jvm.gc.live.data.size",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"process.start.time"

这些状态反映了应用占用资源、GC等状态,我们可以知道应用所占用的资源。我们可以按时间重复轮询这个Endpoint就可以得到应用的资源状态变更。

到此,我们就让SpringBoot有了各种获取状态信息的EndPoint,但是我们获取状态的方式太过简陋了,只能通过HTTP访问来看,如果有办法将它图表化就好了。

那么,这时Prometheus和Grafana就出场了,Prometheus负责向SpringBoot Application收集状态信息,并存储。Grafana则是从Prometheus获取数据,输出漂亮的图表。

下面继续讲。

三、配置Prometheus

Prometheus负责向SpringBoot Application收集状态信息,并存储,对外提供数据源。

我们需要先在SpringBoot Application中进行配置以输出能让Prometheus读取的数据结构:

pom.xml

1
2
3
4
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

这时,应该会有一个叫/actuator/prometheus的Endpoint。

然后我们需要创建一个Prometheus的配置文件:

config.yaml

1
2
3
4
5
6
7
8
9
10
11
12
global:
scrape_interval: 5s
evaluation_interval: 5s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['127.0.0.1:9090']
- job_name: 'spring-actuator'
metrics_path: '/actuator/prometheus'
scrape_interval: 5s
static_configs:
- targets: ['192.168.1.183:8080', '192.168.1.183:8081']

这个配置其实很简单:

  1. global配置了全局信息,主要配两个刷新间隔时间
  2. scrape_configs配置了抓取任务信息,第一个配的是抓取自身的信息,第二个定义了抓取SpringBoot Application的任务,targets定义了SpringBoot Application的地址和端口信息。

然后我们使用docker部署它:

1
$ docker run -d --name infra.prometheus -p 19090:9090 -v /Users/kut/DockerData/prometheus/config.yaml:/etc/prometheus/prometheus.yml prom/prometheus --config.file=/etc/prometheus/prometheus.yml

访问http://localhost:19000即可访问刚刚部署好的Prometheus,并且能通过expression查看到SpringBoot Application的状态数据。

四、配置 Grafana

Grafana从Prometheus获取数据,输出漂亮的图表。

通过Docker部署:

1
$ docker run -d --name infra.grafana -p 13000:3000 grafana/grafana

然后访问http://localhost:13000访问。

创建数据源

创建仪表盘

最后结果是这样:

五、总结

  1. 因为懒,所以都没有截图,图片是别人家的。
  2. Grafana和Prometheus应该还有更深的一层可挖,如果K8S每一个Namespace都要有这么一个Dashboard,那该如何去做呢?这个需要去探究,为将来的SaaS提供支持。
  3. 这个东西挺有趣。

六、参考资料

Spring Boot Actuator:健康检查、审计、统计和监控
https://bigjar.github.io/2018/08/19/Spring-Boot-Actuator-%E5%81%A5%E5%BA%B7%E6%A3%80%E6%9F%A5%E3%80%81%E5%AE%A1%E8%AE%A1%E3%80%81%E7%BB%9F%E8%AE%A1%E5%92%8C%E7%9B%91%E6%8E%A7/

Spring Boot Metrics监控之Prometheus&Grafana
https://bigjar.github.io/2018/08/19/Spring-Boot-Metrics%E7%9B%91%E6%8E%A7%E4%B9%8BPrometheus-Grafana/