【Java实战㊳】Spring Boot实战:从打包到监控的全链路攻略
目录
- 一、Spring Boot 项目打包
- 1.1 Jar 包打包(Maven/Gradle 打包配置、依赖打包方式)
- 1.2 War 包打包(修改打包类型、配置 SpringBootServletInitializer)
- 1.3 打包常见问题(依赖冲突、资源文件路径问题)
- 二、项目部署方式
- 2.1 本地部署(Jar 包命令启动、War 包部署到 Tomcat)
- 2.2 Linux 服务器部署(远程上传、后台启动、日志查看)
- 2.3 Docker 容器部署(编写 Dockerfile、构建镜像、启动容器)
- 2.4 部署自动化(Jenkins 集成 Git、自动构建与部署)
- 三、Spring Boot 监控(Actuator 与 Prometheus)
- 3.1 Spring Boot Actuator 整合(依赖导入、端点暴露配置)
- 3.2 核心端点使用(/health 健康检查、/info 项目信息、/metrics 指标)
- 3.3 Prometheus+Grafana 整合(监控指标采集、可视化面板配置)
- 3.4 告警配置(基于 Grafana 设置异常指标告警)
一、Spring Boot 项目打包
1.1 Jar 包打包(Maven/Gradle 打包配置、依赖打包方式)
在 Spring Boot 项目中,Jar 包是一种常用的打包方式,它可以将项目的所有依赖、类文件、资源文件等打包成一个可执行的文件,方便部署和运行。下面分别介绍 Maven 和 Gradle 的打包配置以及依赖打包方式。
Maven 打包配置
在 Maven 项目中,打包配置主要在pom.xml文件中进行。首先,确保项目的pom.xml文件中包含 Spring Boot Maven 插件,该插件提供了对 Spring Boot 项目的打包支持。示例配置如下:
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.1</version><configuration><!-- 设置main类,可省略,Spring Boot会自动检测 --><mainClass>com.example.demo.DemoApplication</mainClass><!-- 是否跳过测试,true表示跳过 --><skipTests>true</skipTests></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins>
</build>
在上述配置中,spring-boot-maven-plugin插件的repackage目标会将项目打包成一个可执行的 Jar 包。configuration标签内可以设置一些打包相关的属性,如mainClass指定项目的主类,skipTests表示是否跳过测试。
Gradle 打包配置
对于 Gradle 项目,打包配置在build.gradle文件中。同样需要应用 Spring Boot Gradle 插件,并进行相关配置。示例如下:
plugins {id 'org.springframework.boot' version '2.7.1'id 'io.spring.dependency-management' version '1.0.11.RELEASE'id 'java'
}springBoot {mainClassName = 'com.example.demo.DemoApplication'// 是否跳过测试,true表示跳过skipTests = true
}repositories {mavenCentral()
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-web'// 其他依赖
}
在这个build.gradle文件中,通过plugins块应用了 Spring Boot 插件和其他相关插件。springBoot块中设置了主类和跳过测试的属性。
依赖打包方式
在打包 Jar 包时,有多种依赖打包方式可供选择:
- 打包所有依赖(默认方式):Spring Boot Maven 和 Gradle 插件默认会将项目的所有依赖打包进 Jar 包中。这种方式的优点是部署时只需要一个 Jar 包,无需额外处理依赖;缺点是 Jar 包体积较大。例如,在 Maven 中,使用spring-boot-maven-plugin的默认配置即可实现所有依赖打包。
- 仅打包必要依赖:有时候,我们可能希望只打包项目运行所必需的依赖,而将一些公共依赖(如数据库驱动等)在运行环境中单独提供。可以通过配置 Maven 或 Gradle 来排除不需要打包的依赖。例如,在 Maven 的pom.xml文件中,可以在依赖项中使用exclusions标签排除特定依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><exclusions><exclusion><groupId>com.h2database</groupId><artifactId>h2</artifactId></exclusion></exclusions>
</dependency>
在 Gradle 中,可以使用exclude指令排除依赖:
implementation('org.springframework.boot:spring-boot-starter-jdbc') {exclude group: 'com.h2database', module: 'h2'
}
- 依赖分离打包:还可以将依赖和项目代码分开打包,例如将依赖打包到一个单独的目录中,项目 Jar 包只包含代码。这种方式可以减小项目 Jar 包的体积,并且便于依赖的管理和升级。在 Maven 中,可以使用maven-dependency-plugin插件将依赖复制到指定目录,然后在运行时通过classpath指定依赖路径;在 Gradle 中,可以通过配置configurations和copy任务来实现依赖分离打包。
1.2 War 包打包(修改打包类型、配置 SpringBootServletInitializer)
有时候,我们需要将 Spring Boot 项目打包成 War 包,以便部署到外部的 Servlet 容器(如 Tomcat)中。下面介绍如何将项目打包类型改为 war,并配置SpringBootServletInitializer。
修改打包类型
首先,在项目的pom.xml(Maven 项目)或build.gradle(Gradle 项目)文件中修改打包类型为war。
- Maven 项目:在pom.xml文件中,将packaging标签的值改为war,示例如下:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><!-- 修改打包类型为war --><packaging>war</packaging> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.1</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><!-- 项目依赖 --></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.1</version></plugin></plugins></build>
</project>
- Gradle 项目:在build.gradle文件中,添加war插件并配置相关属性,示例如下:
plugins {id 'org.springframework.boot' version '2.7.1'id 'io.spring.dependency-management' version '1.0.11.RELEASE'id 'war' // 添加war插件id 'java'
}group = 'com.example'
version = '0.0.1-SNAPSHOT'sourceCompatibility = '11'repositories {mavenCentral()
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-web'// 其他依赖
}war {// 配置war包名称,可省略,默认使用项目artifactId和versionarchiveFileName.set('demo.war')
}
配置 SpringBootServletInitializer
为了使 Spring Boot 项目能够在外部 Servlet 容器中正确运行,需要配置SpringBootServletInitializer。SpringBootServletInitializer是 Spring Boot 提供的一个用于将 Spring Boot 应用配置为 Servlet 3.0 + 初始化的类。
- Maven 项目:在项目的主类中,继承SpringBootServletInitializer并重写configure方法。示例如下:
package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(DemoApplication.class);}public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
- Gradle 项目:同样在主类中继承SpringBootServletInitializer并重写configure方法,配置与 Maven 项目类似。
完成上述配置后,使用 Maven 的mvn clean package命令或 Gradle 的gradle build命令即可将项目打包成 War 包。生成的 War 包可以部署到外部 Servlet 容器中,如将 War 包放置到 Tomcat 的webapps目录下,启动 Tomcat 即可运行项目。
1.3 打包常见问题(依赖冲突、资源文件路径问题)
在打包 Spring Boot 项目时,可能会遇到一些常见问题,下面主要分析依赖冲突和资源文件路径问题及解决方法。
依赖冲突
依赖冲突是指项目中引入的多个依赖库依赖于同一个库的不同版本,导致在编译或运行时出现问题。例如,项目中同时引入了库 A 和库 B,库 A 依赖于commons-io的 1.0 版本,库 B 依赖于commons-io的 2.0 版本,这就会产生依赖冲突。
- 原因分析:依赖冲突通常是由于传递性依赖导致的。在 Maven 或 Gradle 项目中,一个依赖可能会引入其他依赖,这些被引入的依赖又可能引入更多依赖,形成复杂的依赖树。如果不同的依赖路径引入了同一个库的不同版本,就会出现依赖冲突。此外,手动指定依赖版本时,如果与传递性依赖的版本不一致,也可能引发冲突。
- 解决方法:
- 使用mvn dependency:tree或gradle dependencies排查冲突:在 Maven 项目中,可以使用mvn dependency:tree命令查看项目的依赖树,该命令会显示所有依赖及其版本信息,通过分析依赖树可以找出冲突的依赖。例如,执行mvn dependency:tree后,输出结果中如果某个依赖出现了多个版本,就可能存在冲突。在 Gradle 项目中,可以使用gradle dependencies命令获取类似的依赖信息。
- 通过exclusions标签排除冲突依赖:在pom.xml(Maven)或build.gradle(Gradle)文件中,可以使用exclusions标签(Maven)或exclude指令(Gradle)排除冲突的依赖。例如,在 Maven 中,如果发现commons-io存在版本冲突,并且希望排除某个版本,可以在相关依赖中添加如下配置:
<dependency><groupId>org.example</groupId><artifactId>example-library</artifactId><version>1.0.0</version><exclusions><exclusion><groupId>commons-io</groupId><artifactId>commons-io</artifactId></exclusion></exclusions>
</dependency>
在 Gradle 中,对应的配置为:
implementation('org.example:example-library:1.0.0') {exclude group: 'commons-io', module: 'commons-io'
}
- 强制指定依赖版本:可以在dependencyManagement(Maven)或resolutionStrategy(Gradle)中强制指定某个依赖的版本,确保所有依赖都使用指定版本。例如,在 Maven 的pom.xml文件中:
<dependencyManagement><dependencies><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.0</version></dependency></dependencies>
</dependencyManagement>
在 Gradle 的build.gradle文件中:
configurations.all {resolutionStrategy {force 'commons-io:commons-io:2.0'}
}
资源文件路径问题
在打包过程中,资源文件(如配置文件、静态资源等)的路径也可能出现问题,导致项目在运行时无法正确加载资源。
- 原因分析:常见的原因包括资源文件放置位置不正确、打包插件对资源文件的处理方式不当等。例如,在 Spring Boot 项目中,配置文件通常放置在src/main/resources目录下,如果手动修改了配置文件的位置,可能会导致加载失败。另外,某些打包插件可能会改变资源文件在打包后的路径结构,也会引发问题。
- 解决方法:
- 遵循 Spring Boot 资源文件约定:Spring Boot 对资源文件的加载有一定的约定,尽量遵循这些约定可以避免很多路径问题。例如,将配置文件命名为application.properties或application.yml,并放置在src/main/resources目录下,Spring Boot 会自动加载这些文件。对于静态资源,如 HTML、CSS、JavaScript 文件,可以放置在src/main/resources/static目录下,Spring Boot 会将其映射到/static路径下供前端访问。
- 配置资源文件路径:如果由于特殊原因需要修改资源文件的位置,可以在application.properties或application.yml文件中配置资源文件路径。例如,在application.properties中配置自定义配置文件路径:
spring.config.location=classpath:/config/,file:/data/config/
上述配置表示 Spring Boot 会从classpath:/config/和file:/data/config/这两个路径下加载配置文件。
- 检查打包插件配置:确保打包插件(如 Spring Boot Maven 插件或 Gradle 插件)的配置正确,不会错误地处理资源文件。例如,在 Maven 的spring-boot-maven-plugin插件中,可以通过resources标签配置资源文件的包含和排除规则:
<build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.yml</include></includes><excludes><exclude>**/*.txt</exclude></excludes></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.1</version></plugin></plugins>
</build>
在 Gradle 中,可以通过sourceSets配置资源文件路径:
sourceSets {main {resources {srcDirs 'src/main/resources', 'src/main/config'}}
}
二、项目部署方式
2.1 本地部署(Jar 包命令启动、War 包部署到 Tomcat)
在开发和测试阶段,本地部署是一种常见的方式,方便快速验证项目的功能。下面分别介绍如何通过命令启动 Jar 包以及将 War 包部署到 Tomcat 服务器上。
Jar 包命令启动
在本地,我们可以使用java -jar命令来启动 Spring Boot 项目打包生成的 Jar 包。假设项目打包后生成的 Jar 包名为demo.jar,在命令行中进入到 Jar 包所在目录,执行以下命令:
java -jar demo.jar
这样,Spring Boot 项目就会以默认配置启动,应用程序会监听默认端口(通常是8080)。如果需要指定启动参数,比如设置 Java 虚拟机的初始堆大小和最大堆大小,可以使用如下命令:
java -Xms512m -Xmx1024m -jar demo.jar
上述命令中,-Xms512m表示初始堆大小为512MB,-Xmx1024m表示最大堆大小为1024MB。另外,如果项目需要指定不同的配置文件,也可以通过命令行参数来实现。例如,假设项目有一个application-prod.properties的生产环境配置文件,我们可以使用如下命令启动:
java -jar -Dspring.config.name=application-prod -Dspring.config.location=classpath:/config/ demo.jar
其中,-Dspring.config.name指定配置文件的名称,-Dspring.config.location指定配置文件的路径。
War 包部署到 Tomcat
当项目打包成 War 包后,我们可以将其部署到 Tomcat 服务器上。首先,确保已经安装并启动了 Tomcat 服务器。然后,将生成的 War 包放置到 Tomcat 的webapps目录下。例如,如果 Tomcat 安装在/usr/local/tomcat目录,将demo.war包复制到/usr/local/tomcat/webapps目录下:
cp demo.war /usr/local/tomcat/webapps
Tomcat 在启动时会自动解压 War 包,并将应用部署到服务器中。部署完成后,可以通过访问http://localhost:8080/demo(假设 Tomcat 默认端口为8080,demo为 War 包的名称,也是应用的上下文路径)来访问项目。如果需要修改应用的上下文路径,可以通过修改 Tomcat 的配置文件server.xml来实现。在server.xml文件中,找到Host标签,添加或修改Context标签,例如:
<Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><Context path="/myapp" docBase="demo" reloadable="true" crossContext="true"/>
</Host>
上述配置中,path属性指定了应用的上下文路径为/myapp,docBase属性指定了 War 包的名称(不包含.war后缀)。修改完配置文件后,重启 Tomcat 服务器,应用就可以通过http://localhost:8080/myapp来访问了。
2.2 Linux 服务器部署(远程上传、后台启动、日志查看)
将 Spring Boot 项目部署到 Linux 服务器上是生产环境中常见的做法,下面详细介绍相关步骤。
远程上传
首先,需要将打包好的 Jar 包或 War 包上传到 Linux 服务器。常用的上传方式有以下几种:
- 使用scp命令:scp(Secure Copy)是一个基于 SSH 协议的安全文件传输命令。假设本地 Jar 包路径为/Users/user/demo.jar,服务器 IP 为192.168.1.100,用户名是root,服务器上的目标路径为/root/app,则可以使用以下命令上传:
scp /Users/user/demo.jar root@192.168.1.100:/root/app
执行该命令后,系统会提示输入服务器的密码,输入正确密码后即可开始上传。
使用ftp或sftp工具:可以使用图形化的ftp或sftp工具,如 FileZilla 等。打开工具后,输入服务器的 IP 地址、用户名和密码,连接到服务器。然后在本地找到 Jar 包或 War 包,将其拖放到服务器的目标目录中。
- 使用git拉取:如果项目代码托管在git仓库中,可以在服务器上通过git clone命令拉取代码,然后在服务器上进行打包操作。例如:
git clone https://github.com/yourusername/yourproject.git
cd yourproject
mvn clean package
后台启动
在 Linux 服务器上,为了避免终端关闭后应用程序也随之关闭,我们通常使用nohup命令将应用程序放到后台运行。假设上传到服务器的 Jar 包名为demo.jar,可以使用以下命令启动:
nohup java -jar demo.jar &
nohup命令会忽略所有挂断(SIGHUP)信号,使应用程序在后台持续运行。&符号表示将命令放到后台执行。启动后,应用程序的输出日志会默认输出到当前目录下的nohup.out文件中。如果希望将日志输出到指定文件,比如/var/log/demo.log,可以使用如下命令:
nohup java -jar demo.jar > /var/log/demo.log 2>&1 &
上述命令中,>表示将标准输出重定向到/var/log/demo.log文件,2>&1表示将标准错误输出也重定向到标准输出,即也输出到/var/log/demo.log文件中。
日志查看
在项目运行过程中,查看日志是了解应用程序运行状态和排查问题的重要手段。在 Linux 服务器上,可以使用以下命令查看日志:
- 使用tail命令实时查看日志:tail命令用于查看文件的末尾内容,-f参数可以实现实时跟踪文件的变化。例如,查看/var/log/demo.log文件的实时日志:
tail -f /var/log/demo.log
使用该命令后,终端会实时显示/var/log/demo.log文件的新增内容,方便及时了解应用程序的运行情况。
- 使用less命令查看日志:less命令可以用于查看文件内容,并且支持分页查看、搜索等功能。例如,查看/var/log/demo.log文件:
less /var/log/demo.log
在less命令界面中,可以使用上下箭头键滚动查看日志内容,输入/keyword可以搜索指定关键词,按q键退出查看。
2.3 Docker 容器部署(编写 Dockerfile、构建镜像、启动容器)
Docker 是一种容器化技术,它可以将应用程序及其依赖打包成一个独立的容器,实现快速部署和迁移。下面介绍如何使用 Docker 部署 Spring Boot 项目。
编写 Dockerfile
Dockerfile是一个文本文件,用于定义如何构建 Docker 镜像。在 Spring Boot 项目的根目录下创建一个Dockerfile文件,内容如下:
# 使用官方的OpenJDK 11基础镜像
FROM openjdk:11-jre-slim# 将项目的Jar包复制到容器内
COPY target/demo.jar app.jar# 声明容器运行时监听的端口,这里假设Spring Boot项目默认端口为8080
EXPOSE 8080# 定义容器启动时执行的命令,运行Jar包
CMD ["java", "-jar", "app.jar"]
上述Dockerfile中,首先指定了基础镜像为openjdk:11-jre-slim,这是一个精简的 OpenJDK 11 运行时环境镜像。然后使用COPY指令将项目打包生成的demo.jar(假设打包后的 Jar 包名为demo.jar,位于target目录下)复制到容器内并命名为app.jar。接着使用EXPOSE指令声明容器运行时监听的端口为8080。最后,通过CMD指令定义容器启动时执行的命令,即运行app.jar。
构建镜像
编写好Dockerfile后,就可以使用docker build命令来构建 Docker 镜像。在项目根目录下,打开命令行,执行以下命令:
docker build -t demo:v1.0.0.
其中,-t参数用于指定镜像的标签(tag),格式为仓库名:标签,这里demo为仓库名,v1.0.0为标签,表示版本号。最后的.表示当前目录,即Dockerfile所在的目录。执行该命令后,Docker 会根据Dockerfile的定义逐步构建镜像,构建过程中会显示详细的日志信息。如果构建成功,会生成一个名为demo:v1.0.0的镜像。
启动容器
镜像构建完成后,就可以使用docker run命令启动容器。执行以下命令:
docker run -d -p 8080:8080 demo:v1.0.0
-d参数表示将容器在后台运行,-p参数用于端口映射,将主机的8080端口映射到容器的8080端口,这样就可以通过访问主机的8080端口来访问容器内运行的 Spring Boot 应用程序。demo:v1.0.0为要启动的镜像名称和标签。启动容器后,可以使用docker ps命令查看正在运行的容器列表,确认容器是否成功启动。如果需要停止容器,可以使用docker stop命令,后跟容器的 ID 或名称。
2.4 部署自动化(Jenkins 集成 Git、自动构建与部署)
使用 Jenkins 集成 Git 仓库可以实现代码的自动拉取、构建和部署,大大提高开发和部署效率,实现持续集成和持续交付(CI/CD)。下面介绍具体的配置步骤。
安装 Jenkins 与相关插件
首先,需要在服务器上安装 Jenkins。可以根据服务器的操作系统,参考 Jenkins 官方文档进行安装。安装完成后,在浏览器中访问 Jenkins 的 Web 界面(通常为http://服务器IP:8080/jenkins,8080 为 Jenkins 默认端口,可根据实际情况修改),进行初始化设置。
安装完成后,需要安装相关插件。在 Jenkins 的管理页面中,选择 “管理 Jenkins” -> “管理插件”,在 “Available” 选项卡中搜索并安装以下插件:
- Git 插件:用于与 Git 仓库进行交互,实现代码拉取。
- Maven 插件:用于构建 Java 项目,执行 Maven 命令。
- Publish Over SSH 插件:用于将构建生成的文件通过 SSH 上传到远程服务器,实现部署。
配置 Jenkins 与 Git 的集成
安装好插件后,进行以下配置:
- 配置 Git:进入 Jenkins 的 “系统管理” -> “系统设置”,在 “Git” 部分,配置 Git 的路径。如果服务器上已经安装了 Git 并且在系统路径中,可以直接留空让 Jenkins 自动检测;否则,需要手动指定 Git 的安装路径。
- 配置 GitHub 凭证:如果 Git 仓库是私有的,需要配置凭证以便 Jenkins 能够访问该仓库。在 “系统管理” -> “凭证” 中,添加 GitHub 的凭证。选择 “Kind” 类型,如 “Username with password”(使用用户名和密码)或 “SSH Username with private key”(使用 SSH 密钥),输入相应的凭据信息并保存。
配置 Jenkins 项目使用 Git
在 Jenkins 中创建一个新的自由风格项目或选择一个现有的项目,在项目配置页面中进行以下设置:
- 源代码管理:选择 “Git”,输入 Git 仓库的 URL,如https://github.com/yourusername/yourproject.git 或 git@github.com:yourusername/yourproject.git。选择之前配置好的凭据(如果仓库是私有的),并配置要构建的分支,如*/main 或 */master。
- 构建触发器:可以配置自动触发构建任务的方式,如勾选 “GitHub hook trigger for GITScm polling”,当 GitHub 仓库有代码变更时自动触发构建;或者勾选 “Poll SCM”,并配置轮询频率,如H/5 * * * *表示每 5 分钟检查一次仓库是否有变更。
- 构建步骤:点击 “Add build step”,选择 “Invoke top-level Maven targets”(如果项目使用 Maven 构建),在 “Goals” 文本框中输入 Maven 命令,如clean install,用于清理项目、编译代码、运行测试并生成可部署的 Jar 包。
配置构建后操作
在项目配置页面的 “Post-build Actions” 部分,添加构建后操作:
- 上传文件到远程服务器(以 Publish Over SSH 插件为例):如果选择使用Publish Over SSH插件进行部署,首先在 “系统管理” -> “系统设置” 中配置 SSH 服务器信息,包括服务器 IP、用户名、密码或 SSH 密钥等。然后在项目配置的 “Post-build Actions” 中,选择 “Send files or execute commands over SSH”,配置要上传的文件路径(如target/demo.jar)和远程服务器的目标路径,以及上传完成后在远程服务器上执行的命令(如启动 Jar 包的命令)。
- 其他操作:还可以根据需要添加其他构建后操作,如发送邮件通知构建结果、归档构建产物等。
通过以上配置,当 Git 仓库有代码提交时,Jenkins 会自动拉取最新代码,执行构建和部署操作,实现项目的自动化部署。
三、Spring Boot 监控(Actuator 与 Prometheus)
3.1 Spring Boot Actuator 整合(依赖导入、端点暴露配置)
Spring Boot Actuator 是 Spring Boot 提供的一个强大功能模块,它可以帮助我们监控和管理 Spring Boot 应用程序。通过 Actuator,我们能够轻松获取应用程序的健康状况、性能指标、环境信息等,这些功能在开发、测试以及生产环境中都非常实用。
依赖导入
首先,我们需要在项目中引入 Spring Boot Actuator 依赖。如果使用 Maven 构建项目,在pom.xml文件中添加以下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
如果使用 Gradle,在build.gradle文件中添加:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
添加依赖后,Maven 或 Gradle 会自动下载并将 Actuator 相关的库添加到项目中。
端点暴露配置
在 Spring Boot 2.x 版本中,Actuator 的端点默认只暴露了/health和/info。如果我们想要暴露更多的端点,需要在配置文件(application.properties或application.yml)中进行配置。
使用application.properties配置时:
# 暴露所有端点
management.endpoints.web.exposure.include=*
# 或者指定暴露某些端点,如health、info、metrics
# management.endpoints.web.exposure.include=health,info,metrics
使用application.yml配置时:
management:endpoints:web:exposure:include: '*' # 或者指定暴露某些端点# include: health,info,metrics
上述配置中,management.endpoints.web.exposure.include属性用于指定要暴露的端点。*表示暴露所有端点;如果只想暴露特定端点,如health、info、metrics,则将其以逗号分隔列出即可。另外,还可以通过management.endpoints.web.exposure.exclude属性来排除某些端点,例如:
management.endpoints.web.exposure.exclude=env
这表示不暴露/env端点,其他端点按照include的配置进行暴露。
3.2 核心端点使用(/health 健康检查、/info 项目信息、/metrics 指标)
Spring Boot Actuator 提供了多个核心端点,每个端点都有其特定的功能,下面详细介绍/health、/info和/metrics这三个常用端点的使用方法。
/health 健康检查
/health端点用于检查应用程序的健康状况。它会返回一个 JSON 格式的响应,告知应用程序是否正常运行,以及各个组件(如数据库连接、磁盘空间等)的健康状态。例如,当我们访问http://localhost:8080/actuator/health(假设应用程序运行在本地 8080 端口)时,可能得到如下响应:
{"status": "UP","components": {"diskSpace": {"status": "UP","details": {"total": 499763210752,"free": 304417739264,"threshold": 10485760}},"ping": {"status": "UP"}}
}
在这个响应中,status字段表示应用程序的整体健康状态,UP表示正常,DOWN表示异常。components字段包含了各个组件的健康信息,例如diskSpace表示磁盘空间检查结果,ping是一个简单的心跳检查。如果应用程序依赖数据库,还会包含数据库连接的健康信息。我们可以通过实现HealthIndicator接口来自定义健康检查逻辑。例如,创建一个自定义的健康检查类:
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;@Component
public class CustomHealthIndicator implements HealthIndicator {@Overridepublic Health health() {// 自定义健康检查逻辑,例如检查某个服务是否可用boolean isServiceAvailable = checkServiceAvailability(); if (isServiceAvailable) {return Health.up().withDetail("Service Status", "Available").build();} else {return Health.down().withDetail("Service Status", "Unavailable").build();}}private boolean checkServiceAvailability() {// 实际的服务可用性检查逻辑// 这里可以是调用远程服务的接口,检查响应等return true; }
}
上述代码中,CustomHealthIndicator类实现了HealthIndicator接口,并重写了health方法。在health方法中,通过调用checkServiceAvailability方法来检查服务的可用性,并根据结果返回不同的健康状态和详细信息。
/info 项目信息
/info端点用于返回应用程序的自定义信息,例如应用的版本号、描述、构建时间等。默认情况下,/info端点返回一个空的 JSON 对象。我们可以通过在配置文件中添加自定义信息来丰富其返回内容。在application.properties文件中添加:
info.app.name=My Spring Boot Application
info.app.version=1.0.0
info.app.description=This is a sample Spring Boot application with Actuator.
在application.yml文件中添加:
info:app:name: My Spring Boot Applicationversion: 1.0.0description: This is a sample Spring Boot application with Actuator.
配置完成后,访问http://localhost:8080/actuator/info,将得到如下响应:
{"app": {"name": "My Spring Boot Application","version": "1.0.0","description": "This is a sample Spring Boot application with Actuator."}
}
此外,我们还可以通过实现InfoContributor接口来自定义/info端点返回的信息。例如:
import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;
import java.util.Collections;@Component
public class CustomInfoContributor implements InfoContributor {@Overridepublic void contribute(Info.Builder builder) {builder.withDetail("customInfo", Collections.singletonMap("key", "value"));}
}
上述代码中,CustomInfoContributor类实现了InfoContributor接口,在contribute方法中,使用Info.Builder添加了自定义信息customInfo,其值为一个包含key和value的 Map。此时访问/info端点,返回的 JSON 数据中会包含这个自定义信息。
/metrics 指标
/metrics端点提供了应用程序的各种度量指标,如内存使用情况、CPU 使用率、HTTP 请求统计等。访问http://localhost:8080/actuator/metrics,会得到一个包含所有可用指标的列表,每个指标都有其对应的描述和值。例如,获取 JVM 内存使用情况的指标:
{"name": "jvm.memory.used","description": "The amount of used memory","baseUnit": "bytes","measurements": [{"statistic": "VALUE","value": 1.23456789E8}],"availableTags": [{"tag": "area","values": ["heap", "nonheap"]},{"tag": "id","values": ["PS Eden Space", "PS Survivor Space", "PS Old Gen", "Metaspace", "Compressed Class Space"]}]
}
在这个响应中,name字段表示指标名称,description是指标描述,baseUnit是指标的基本单位,measurements包含了指标的具体测量值,availableTags则列出了可以用于细分指标的标签。如果我们只想获取某个特定指标的数据,可以在/metrics后面加上指标名称,例如http://localhost:8080/actuator/metrics/jvm.memory.used。我们还可以使用 Micrometer 提供的 API 来创建自定义指标。例如,在 Spring Boot 应用中,使用MeterRegistry来记录一个自定义的计数器指标:
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Counter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MetricController {private final Counter requestCounter;public MetricController(MeterRegistry meterRegistry) {this.requestCounter = meterRegistry.counter("requests_count");}@GetMapping("/metric")public String metric() {requestCounter.increment(); return "Metric updated!";}
}
上述代码中,MetricController类通过构造函数注入了MeterRegistry,并使用它创建了一个名为requests_count的计数器requestCounter。在metric方法中,每次请求都会使计数器增加 1。此时访问/actuator/metrics/requests_count,就可以获取到这个自定义指标的统计数据。
3.3 Prometheus+Grafana 整合(监控指标采集、可视化面板配置)
Prometheus 是一个开源的系统监控和警报工具包,而 Grafana 是一个开源的多平台可视化工具,它们结合使用可以实现对 Spring Boot 应用的全面监控和可视化展示。下面介绍如何将 Prometheus 与 Spring Boot 集成进行监控指标采集,以及如何使用 Grafana 配置可视化面板。
监控指标采集
- 添加依赖:在 Spring Boot 项目中,为了让 Prometheus 能够采集到应用的指标数据,需要添加 Spring Boot Actuator 和 Micrometer Prometheus Registry 的依赖。如果使用 Maven,在pom.xml文件中添加:
<dependencies><!-- Spring Boot Actuator --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- Micrometer Prometheus Registry --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId></dependency>
</dependencies>
如果使用 Gradle,在build.gradle文件中添加:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'
- 配置 Actuator:在配置文件(application.properties或application.yml)中配置 Actuator,以暴露 Prometheus 端点。使用application.properties配置:
management.endpoints.web.exposure.include=prometheus
management.metrics.export.prometheus.enabled=true
使用application.yml配置:
management:endpoints:web:exposure:include: prometheusmetrics:export:prometheus:enabled: true
上述配置中,management.endpoints.web.exposure.include指定暴露prometheus端点,management.metrics.export.prometheus.enabled启用 Prometheus 的指标导出功能。
- 启动 Prometheus:可以从 Prometheus 官网下载适用于本地操作系统的二进制文件,解压后,通过命令行启动。例如,在解压后的目录中执行:
./prometheus --config.file=prometheus.yml
其中,prometheus.yml是 Prometheus 的配置文件。也可以使用 Docker 来启动 Prometheus,执行以下命令:
docker pull prom/prometheus
docker run --name prometheus -d -p 9090:9090 prom/prometheus
这将拉取 Prometheus 镜像并在本地启动一个容器,映射容器的 9090 端口到主机的 9090 端口,通过访问http://localhost:9090可以打开 Prometheus 的 Web 界面。
- 配置 Prometheus:在prometheus.yml配置文件中,添加 Spring Boot 应用作为监控目标。例如:
scrape_configs:- job_name:'spring-boot-application'metrics_path: '/actuator/prometheus'scrape_interval: 15sstatic_configs:- targets: ['localhost:8080']
上述配置中,job_name是抓取任务的名称,可自定义;metrics_path指定 Spring Boot 应用中 Prometheus 端点的路径,默认是/actuator/prometheus;scrape_interval定义了 Prometheus 抓取指标数据的频率,这里设置为每 15 秒抓取一次;static_configs中的targets指定了 Spring Boot 应用的地址和端口,这里假设应用运行在本地 8080 端口。配置完成后,Prometheus 会按照设定的频率从 Spring Boot 应用的/actuator/prometheus端点抓取指标数据。
可视化面板配置
- 安装 Grafana:可以从 Grafana 官网下载安装包进行安装,也可以使用 Docker 安装。使用 Docker 安装的命令如下:
docker pull grafana/grafana
docker run -d --name=grafana -p 3000:3000 grafana/grafana
这将拉取 Grafana 镜像并启动一个容器,映射容器的 3000 端口到主机的 3000 端口,通过访问http://localhost:3000可以打开 Grafana 的登录界面,默认用户名和密码是admin/admin。
-
配置数据源:登录 Grafana 后,点击左侧菜单栏的 “Configuration” -> “Data Sources”,然后点击 “Add data source”,选择 “Prometheus”。在配置页面中,填写 Prometheus 的 URL,例如http://localhost:9090,保存并测试数据源,确保连接正常。
-
创建可视化面板:点击左侧菜单栏的 “+” 号,选择 “Dashboard”,然后点击 “Add query”。在查询编辑器中,选择之前配置的 Prometheus 数据源,并使用 Prometheus 查询语言(PromQL)编写查询语句来获取要展示的指标数据。例如,要展示 HTTP 请求的总数,可以使用查询语句http_server_requests_total。选择合适的可视化类型,如柱状图、折线图、仪表盘等,调整面板的样式和参数,最后保存面板。还可以通过导入 Grafana 官方或社区提供的模板来快速创建可视化面板。在 Dashboard 页面,点击 “Import”,输入模板 ID 或上传模板文件,选择数据源后即可导入模板并查看可视化效果。
3.4 告警配置(基于 Grafana 设置异常指标告警)
在 Grafana 中设置告警规则可以帮助我们及时发现应用程序中的异常情况,当监控指标出现异常时及时发出警报。下面介绍如何在 Grafana 中进行告警配置。
- 设置告警通知渠道:在 Grafana 中,首先需要配置告警通知渠道,以便在告警触发时能够将通知发送出去。常见的通知渠道有邮件、钉钉机器人、Webhook 等。以配置邮件通知为例,点击左侧菜单栏的 “Configuration” -> “Notification channels”,然后点击 “Add channel”,选择 “Email”。在配置页面中,填写邮件服务器的相关信息,如 SMTP 服务器地址、端口、用户名、密码等,以及接收告警通知的邮件地址,保存配置。如果要配置钉钉机器人通知,同样在 “Add channel” 中选择 “Webhook”,在 Webhook URL 中填写钉钉机器人的 Webhook 地址,并根据钉钉机器人的要求设置请求头和请求体等参数。
- 创建告警规则:点击要设置告警规则的面板,然后点击面板右上角的 “Edit” 按钮进入编辑模式。在编辑模式下,找到 “Alert” 选项卡,点击 “Create alert rule”。在告警规则设置页面,首先设置告警规则的名称,例如 “High CPU Usage Alert”。然后选择数据源,这里选择之前配置的 Prometheus 数据源。接着编写告警触发条件,使用 PromQL 语句来定义。例如,要设置当 CPU 使用率超过 80% 时触发告警,可以使用以下 PromQL 语句:
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
上述语句中,node_cpu_seconds_total{mode=“idle”}表示获取 CPU 空闲时间指标,irate函数用于计算每秒的变化率,avg by (instance)表示按实例进行平均,最后计算出 CPU 使用率,并判断是否大于 80%。设置告警的触发条件后,还可以设置告警的评估周期(For),例如设置为 “5m”,表示当 CPU 使用率连续 5 分钟超过 80% 时才触发告警,这样可以避免短暂的波动导致误告警。在 “Notifications” 选项中,选择之前配置好的通知渠道,如邮件或钉钉机器人。还可以添加一些注解(Annotations),用于在告警通知中显示更多的信息,例如告警的原因、解决方法等。
- 测试和启用告警规则:完成告警规则设置后,点击 “Test rule” 按钮可以手动测试告警规则是否正常工作。Grafana 会模拟触发告警条件,检查是否能够正确发送通知。如果测试通过,点击 “Enable alert rule” 按钮启用告警规则。此后,当监控指标满足告警触发条件时,Grafana 会按照配置的通知渠道发送告警通知,帮助我们及时发现和处理。