项目上线后,除了能保障正常运行以外,也需要服务运行的各个指标进行监控,例如 服务器CPU、内存使用占比,Full GC 执行时间等,针对一些指标出现异常,可以加入一些报警机制能及时反馈给开发运维。这样,对于一些突发异常,能提前预知、并及时修复,避免服务宕机造成的损失。
针对 SpringBoot 项目,Spring 团队提供了对应 stater , spring-boot-actuator
模块通过 HTTP endpoints 来获取 SpringBoot 项目中的审计、健康状况以及一些配置项、容器注册 bean 以及heapdump
等信息,
actuator 通过开放 http 接口方式来表示各个指标详情,但这种方式并不直观,并且针对一些指标阈值并没有提供一些报警规则,因此需要引入另外一个服务Prometheus
,专用于事件监视以及报警的开源工具。
Prometheus 指标是基于事件戳方式进行记录的,通过 key、value 方式存储,记录指标在时间维度方面颗粒度更小;除了Prometheus
外,针对指标可视化还需要一个工具Grafana
,专用于数据查询、以及指标可视化
SpringBoot
创建一个 SpringBoot 项目,加入 spring-boot-starter-actuator
以及 micrometer-registry-prometheus
依赖,对外暴露 /actuator/permetheus
端口服务,让Prometheus
用于数据抓取;
项目 pom 依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.8.RELEASE</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
服务 yml 配置项,除了将 actuator 的 metrics、health 等接口暴露给 prometheus 服务外,服务还加入了 druid
数据连接池,监控 MYSQL数据库的运行,密码是经过 Druid 加密后处理的。
server:
port: 8082
spring:
application:
name: metricsLocalApp
redis:
host: localhost
port: 6379
password: 123456
datasource:
url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: YjHh36LKJ62yxE9RhYVQLDDWK2QseZ/S7OgtBC7sv1Yzi6YLUOZMN8BcFrAbzLJmjXtmXW2f9nISSReTob+qZQ==
driver-class-name: com.mysql.cj.jdbc.Driver
# 开启druid驱动
type: com.alibaba.druid.pool.DruidDataSource
druid:
filter:
config:
enabled: true
# 初始化建立物理连接个数
initial-size: 3
# 最凶奥连接池
min-idle: 3
# 连接池最大连接数
max-active: 20
# 获取连接时最大等待时间,单位毫秒
max-wait: 60000
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
test-while-idle: true
# 既作为检测的间隔时间又作为testWhileIdel执行的依据
time-between-connect-error-millis: 60000
# 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接
min-evictable-idle-time-millis: 30000
# 用来检测连接是否有效的sql 必须是一个查询语句
# mysql中为 select 'x'
# oracle中为 select 1 from dual
validation-query: select 'x'
# 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-borrow: false
# 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-return: false
# 是否缓存preparedStatement,mysql5.5+建议开启
pool-prepared-statements: true
# 当值大于0时poolPreparedStatements会自动修改为true
max-pool-prepared-statement-per-connection-size: 20
# 合并多个DruidDataSource的监控数据
use-global-data-source-stat: false
# 配置扩展插件
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=2000
# 定时输出统计信息到日志中,并每次输出日志会导致清零(reset)连接池相关的计数器。
time-between-log-stats-millis: 300000
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: '/*'
exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
# 配置DruidStatViewServlet
stat-view-servlet:
# 是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
url-pattern: '/druid/*'
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# # druid登录名
login-username: admin
# 登录密码
login-password: admin
enabled: true
connection-properties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOuIUu/iVnxlfq9EYCmu9CVVEYrjwMjI8/DZ7zMwVnLov9cNxRnK3TV94SDL6p5C0EjFx1NKW5ntJwVoe8jZxV8CAwEAAQ==
management:
server:
port: 9001
# 开启 actator 服务
endpoints:
web:
exposure:
include: '*'
# 暴露 metrics 端口
endpoint:
metrics:
enabled: true
# 配置 prometheus 服务
prometheus:
enabled: true
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}
此外,SpringBoot启动入口,将服务名注册到 micrometer
中的 application
,用于prometheus
数据抓取
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
MeterRegistryCustomizer<MeterRegistry> configurer(
@Value("${spring.application.name}") String applicationName){
return (registry) -> registry.config().commonTags("application",applicationName);
}
}
项目启动,浏览器输入 http://localhost:9001/actuator/prometheus
,就可以看到如下基本指标,包含jvm、tomcat 以及 系统cpu、线程及内存信息
Prometheus 配置
以下操作,都以假设你的电脑已经安装好 Docker 工具为前提;
本机环境 OS
:Windows10
- 1,从dockerhub 拉取 prometheus 镜像
docker pull prom/prometheus:v2.37.5
- 2,在合适文件中创建
prometheus.yml
配置文件
global:
# 数据抓取频率
scrape_interval: 60s
# 数据评估频率
evaluation_interval: 60s
# 抓取配置项
scrape_configs:
# 指定 springboot name标签
- job_name: "metricsLocalApp"
# 设定metrics 的路径
metrics_path: "/actuator/prometheus"
static_configs:
# 配置目标关联 host,如果是本机的话,建议用 内网ip,而不用 localhost;
- targets: ['192.168.0.108:9001']
3,打开 terminal,启动刚刚拉取的 permetheus
镜像;注意 D:/programCoding/Docker/permetheus/config/prometheus.yml
为我的电脑中 permetheus 的安装路径,这里目的是要挂载到镜像中的配置文件夹中;
docker run -d -p 9090:9090 -v D:/programCoding/Docker/permetheus/config/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:v2.37.5
镜像启动成功后,浏览器输入http://localhost:9090
,点击上方菜单栏中的 status 下选框,点击 Targets,就能看到类似于下面的页面效果;第一个对应上文中的 SpringBoot 项目;
Grafana 安装
prometheus
配置完成之后,下面需要配置 Grafana
,这里也是借助 Docker 镜像;
- docker 拉取 grafana 镜像
docker pull grafana/grafana:9.2.13
- 运行镜像
docker run -d -p 3000:3000 --name=grafana -v D:/programCoding/Docker/grafana/storage:/var/lib/grafana grafana/grafana:9.2.13
启动成功后,浏览器输入http://localhost:3000
;Grafana 初始账号和密码都为 admin
首先,创建数据源
然后,创建dashboard
选取数据源,指定metrics 指标
然后 Grafana 就能根据你的设置,生成N个可视化面板。