Prometheus + Grafana 监控 SpringBoot项目监控系统
来源:性能与架构
整体结构
SpringBoot 的 actuator 提供了监控端点。
Prometheus 是监控系统,可以从 Springboot 获取监控数据,以时序数据的形式存储,并提供了监控数据的查询服务。
Grafana 是专业的 UI 仪表盘系统,支持非常多的数据源,其中就包括 # / y a Pr) , nometheus,可以便利的从中获取数据,使用仪表盘展示出来。
springboot 2 中引入了 micrometer,它可以更方便的对接各种监控系统,包括 Prometheus。
所以整体的结构就是:
- springboot(micrometer)产生监控数据。
- Prometheus 获取 springb( q j | ; -oo% | 5 Jt 应用的监控数据,存储,并提供T U f P f M /数据查询服务。
- Grafana 对接 Prometheus 数据源,x { s Y调用其数据查询服务,用专业的仪表盘 UI 进行展示。
实践步骤
- 创建应用 -- 作为监控目标,产生监L s = 2控数据。
- 集成度量库 micrometer -- 以便对接监控系统 Prometheus。
- 部L W * f r署 prometheus
- 配置 prometheus -- 监控之前创建的 springboot 应用,了解 Prometheus 的查询服务。
- 部署 Grafana
- 添加 Prometheus 数据源
- 添加 JVM 监控仪表盘 -- 展示之前 springboot 应用的 JVM 状态。
- 自定义监控指标 -- 自有的监控指标都是底层基础数据,业务相关指标需要我们自己写代码。
- 动态变更监控目标 -- 如果监控目标发 R P & %生变动就1 % 9 G改一次 Prometheus 的配置文件,并重新启动,这是不l - ; , Q O G W e适合的,需要使用动态配置的方式。
1. 创建应用 集成 micrometer
创建一个最简的 springboot 应用,添加 micrometer 依赖。
pom.xml :
<?W X L Pxml version=\"1.0\" encodingT { ` (=4 ` E e c\"UTF-8\"?>
<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http:/@ C E l N B I P/www.w3.org/2001/XMLSchemm { 9 pa-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\j 2 U _ z">
<modelVersioo 5 ? R iption>De$ m Cmo project for Spring Boot</description>
<properties>
<s 3 A F q g *;jav[ N Z @ J f y E ya.version>1.8</java.version>
</properties>
<dependencies>
<dependenX ~ 0 gcy| L # .>
<? N ` A U w 8 G;groupId>org.springframewor( Y ( O q | Ik.boot</gro9 o a . Y uupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>z Q _ S r @;spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometem K $ u / C T = cr-registry-promD O L b b { retheus</artifactId- l ^ & Y z e 8 >
<version>1.1.4</ve, 5 [ v brsion&L O 2 v Q } ^gt;
</dependency>
&lR $ ? l 5 Gt;dependency! M % k ` f n ( f>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>0 H C @ S
<groupId>O t 3 | T + N |org.junit.vintage<9 Y M : + H N;/groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusiong w h F O s B M ls&@ - & * : i C f ~ 8
</plugin>
</ P W ~ a rplugins>
</build>
</project>application.properties
spring.application.name=springboot2demo
#L # s R ( 打开所有J h & Actuator 服务
management.endpoints.5 w Jweb.exposure.include=*
# 将应用名称添加到计量器的 tag 中去
# 以便 Prome[ G ltheus 根据应用名区分不同服务
ma1 l ` h F 0ample.springboot2demo;
importO A D 1 io.micrometer.core.instrument3 y 0 b {.MeterRegist0 L # V S M = Y Nry;
import org.springframework.beans.factory.annotatio^ @ Cn.Value;
i{ t Jmport org.springframework.boot.SpringApplication;
import org.spri{ 3 I i c * :ngframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import2 C H org.springframework.boot.autoconfigure.SpringBootAQ ` I j 4 Epplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplicatih 3 6onpublic class Springboot2demoApplicatiok t ] xn {
public static void main(String args) {
SpringApplication.run(SpriO t ,ngboot2demoApplicatid K r Q $ B Aon.class, args);
}
@Bean
MeterRegir | V R stryCustomizer<MeterRegistry> configurer(
@D 2 t E 7 W UValue(\"${spring.application.nad P A R J p ame}\") String applicationName) {
return (registry) -> registry.config().commonTags(\"application\", applicationName);2 L k x K X
}
}启动服务。
查看监控端点信息:
2y | h `. 部署 Prometheus
官网:
https://prometheus.io/
可以下载安装包来C Z P (安装,但下载速度极其慢,几乎下载不了。
可以使用 docker 部署,因为国内有docker镜像,所以速度很快。
docker 方式启动:
$ docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus执行完成后就OK了,可以看一下 Prometheus 的界面。
ht2 M / l Htp://localhost:9090/P C 7 ~ H } Ftargets 是监控目标列表页:
http://localhost:9090/graph 是查询控制台,也有简单的图表展示:
现在还没对接应用,后面对接之后可以看到详细的内容。
3. Prometheus + SprY S Q M B : g Z 7ingboot应用
监控应用,需要在 Promet7 P ] F F g d Qheus 配置文件中添加应用的相关信息。
配5 1 [ , I Y置文件在容器中的路径:/etc/promy j Q % q * _ :etheus。
查看一下配置文件的默认内容:
$ docker exec -it cat /etc/prometheus/prometheus.yml红框内是我们要关注的部分,按照这个形式添加我们的应用即可。
需要添加的内容为:
- job_name: \'springboot_app\'
scrape_interval: 5s
metrics_path: \'/actuator/prometheus\'
static_configs:
- targets:
\"lab% z ? ~ Z . # c 6els\": {
\"instat w U Nnce\": \"springboot2-AI $ k 1 H u\"G * | ! z 6,
\"service\": \"springboot2-A-service\"
}metrics_path 指定监控端点的路径。
targets 指定应用的IP端口,这里使用了IP,没有使用loc9 I Y ualhost,因为 Promethe& s 9 2 o b & b Xus 是容器运行的,如果使用 lo( Z F R R 7 & ^c^ } A | L 2alhost 就会访问容器内部。
配置不是直接在容器内部修改,可以把容器内部的配置文件拷贝出来一份,修改后,重启启动容器,挂载本地修改过的配置文件。
拷贝容器中的配置文件:
$ docker cp :/etc/prometheus/prometheus.yml .修. j D e % v w改配置文件,添加配置,最终的内容:
# my global configg
lobal: scrape_interval: 15s
# Set the scrape interval= H : S b n / o 3 to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s
# Evaluate rules every 15 se; J i W & iconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Aler: I 5 n 2 Ptma~ = v s # + , . Inager configurationalerting:y y $ r w
alertmanagers: - static_configs: - tO m 2 g 9argets:
# - alertmaG r e V Bnager:9093
# Load rules oncH 2 1 h % {e and periodically evaluate them accordic b N a Mng tC R d U J lo the global \'evaluatiT $ W ! } [ A lon_interval\'.rulm z J q U . - je_files:
# - \"first_rules.yml\"
# -! k c I 8 % _ \"second_ruleh a w !s.yml\"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it\'s Prometheus itself.scrape_configs:
# The job name is added as) 0 } q S a label `job=<job_name>` to any timeseries scraped from thi~ , N e v X k D ,s config. - jobY i H N ( V i p_name: e b B d u / i\'prometheus\'
# metrics_path dee + % Vfaults to \'/metrics\'
# scheme defaults to \'http\'.
static_configs: - targets:
- job_name:N 1 ? g 3 s h - \'0 ? N ! C V o k 6springboot_app\'
scrape_interval: 5s
metrics_path: \'/acc l G 3 I atuator/prometheus\'
statiu ; F W )c_configs:
- targets:
\"labels\": {
\"instance\": \"springG N ; Z , n X L 4boot ] i # E j d ;2-A\",
\"service\": \"springboot2-A-? 4 S o - 3 tservice\"
}3 P / i t停掉之前的容器,重新启动:
$ dockA K J q F 0 X 3 rer run --name prometheus -d \\
-p 9090:9090 \\
-v /prometheus.yml:/etc/prometheus/prometheus.yml \\
prom/prometheus访问监控列表页 htv { L | 2 k G 9tp://localhost:9090/targets 就可以看到我们的应用了:
点( 6 ^ * t K v击端点链接,可以看到监控数据,例如:
进入查询控制台页面 http://loca/ * . 3 0 ]lhost:9090/graph,可以查询一个指标,例如 http_server_requests_seconds_sum,效果:
4. 部署 Grafana
docker方式运行:
$ docke@ f & C @ w 7 jr run -d \\
-p 3000:3000 \\
--name=grafana \\
grafaO , P c 2 _ Ina/grafana启动后,访问:http://localhost:3000,默认用户名密码 admin/admin。
5. 添加 PrometheusL s t S 1 ! 数据源
6. 展示应用的 JVM 信息
Grafana 中已经有现P S ? m k k h W u成的 JVM 仪表盘,我们直接导入使用即可。
这个仪表盘的编号为 4701。
至此,Prometheus + Grafana + Springboot 的整体流程已经跑通了。
但是,这些指标都是底层通用指标,在业务层面一定会有个性需求,下面我们自己定义一些监控指标。
7. 自定义监控指标
需求:监控所有接口的请求次数。
应用中添加依赖:
&R 5 ; Z = = ) 4 7lt;de2 i u \");
}
@Before(\"pointCuu U $ + n V Kt()\"u L D H 1 B)
public void doBefore(] . . y ^ m oJoinPoint jo4 J [ 9 * $inPoint) throws Throwable {
System.out.println(\"do before\");
counter.increment();
//请求计数
}
@AfterReturning(returning = \"returnVal\", poin? e .tcut = \"pointCut()\")
public void do( _ ? 0 h t kAfterReturning(Object returnVal) {
System.out.printH Z Y p ! ^ ; ? @ln(\"do after\");
}
}创建一个测试接口:
package comK % ( k { Y r.e& L 3 K g b Jxample.springboot2demo;
i# ( m g K import org.springframework.web.bind.annotation.RequestMappingi 5 p [;
import org.springframework.web.bind.annotation.{ w @ K "/hello\")
public String hello() {
return \"hello\";
}
}重启5 u m m y ~ O应用,多访问几次测试接口,然后查看 Prometheus 中的应用监控端点页面,就可以看到监控结果:
然后,我们把这个指标在 Grafana 中显示出来。
8. 动态变更监控目标
上面 Prometheu7 ~ D K 6 _ 7s 配置文件中定义的监控目标使用的是静态方式,改配置文件后需要重O d - N Z x w h ~启。
如果服务变更了,或者增加服务了,经常重启 Prometheus 肯定不合适。
Prometheus 提供了动态加载的方式,把服务信息放到一个单独的文件中,Prometheus 配置中指定这个外部文件,内容变化后,Prometheus 就会自动重新加载。
服务信息配置文件例如:
[
{
\"targets\": ,
\"labels0 | Z X +\": {
\"instance\": \"springboot2-A\",
\"service\": \"sprinL 7 Z a { gboot2-A-service\"
}
}
]Prometheu5 2 U E 8 ~ a ; =s 配置文件 # R p z中的写法:
...
- job_name: \'springboot_app\'
scrape_interval: 5s
metrics_path: \'/actuator/prometheus\'
file_sd_configs:
- files:
- /home/*.json
refresh_interval: 1m启动 Prometheus 容器时要挂载这个服务信息配置文件的目录:
$ docker run --name prometheus -d -p 9090:9090 l Q g - J 0\
-v /a o / e q 8 ,prometheus.yq _ & [ ) +ml:/etc/prometheus/p@ h M 6 * Erometheus.yml \\
-v :/home \\ prom/prometheus