java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Boot从打包到监控

Spring Boot从打包到监控的全链路实战指南

作者:奔跑吧邓邓子

本文系统讲解了SpringBoot项目的打包方式(Jar/War)、部署方法(本地/服务器/Docker)及全链路监控方案,涵盖Actuator健康检查、Prometheus指标采集与Grafana可视化监控,并介绍了如何通过Jenkins实现自动化部署,感兴趣的朋友跟随小编一起看看吧

全链路监控是什么?

概念解释

全链路监控,简单来说就是追踪一个请求从进入系统到返回结果的整个过程,记录下每个环节的调用关系、耗时等信息。

就像你点了份外卖,从商家接单、厨师做菜、骑手取餐到最终送达,全程都有记录和追踪。

为什么需要方法级的全链路监控?

定位性能瓶颈:哪个方法耗时最长,一目了然
异常追踪:出了问题,直接定位到具体方法
服务依赖分析:清晰了解系统内部调用关系
告别无效加日志:不用再到处打印日志来排查问题

一、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 包时,有多种依赖打包方式可供选择:

<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'
}

1.2 War 包打包(修改打包类型、配置 SpringBootServletInitializer)

有时候,我们需要将 Spring Boot 项目打包成 War 包,以便部署到外部的 Servlet 容器(如 Tomcat)中。下面介绍如何将项目打包类型改为 war,并配置SpringBootServletInitializer。

修改打包类型

首先,在项目的pom.xml(Maven 项目)或build.gradle(Gradle 项目)文件中修改打包类型为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>
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和version
    archiveFileName.set('demo.war') 
}

配置 SpringBootServletInitializer

为了使 Spring Boot 项目能够在外部 Servlet 容器中正确运行,需要配置SpringBootServletInitializer。SpringBootServletInitializer是 Spring Boot 提供的一个用于将 Spring Boot 应用配置为 Servlet 3.0 + 初始化的类。

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 {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(DemoApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

完成上述配置后,使用 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 版本,这就会产生依赖冲突。

<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>
    <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.config.location=classpath:/config/,file:/data/config/

上述配置表示 Spring Boot 会从classpath:/config/和file:/data/config/这两个路径下加载配置文件。

<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 /Users/user/demo.jar root@192.168.1.100:/root/app

执行该命令后,系统会提示输入服务器的密码,输入正确密码后即可开始上传。
使用ftp或sftp工具:可以使用图形化的ftp或sftp工具,如 FileZilla 等。打开工具后,输入服务器的 IP 地址、用户名和密码,连接到服务器。然后在本地找到 Jar 包或 War 包,将其拖放到服务器的目标目录中。

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 -f /var/log/demo.log

使用该命令后,终端会实时显示/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” 选项卡中搜索并安装以下插件:

配置 Jenkins 与 Git 的集成

安装好插件后,进行以下配置:

配置 Jenkins 项目使用 Git

在 Jenkins 中创建一个新的自由风格项目或选择一个现有的项目,在项目配置页面中进行以下设置:

配置构建后操作

在项目配置页面的 “Post-build Actions” 部分,添加构建后操作:

通过以上配置,当 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 {
    @Override
    public 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 Application
    version: 1.0.0
    description: 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 {
    @Override
    public 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 配置可视化面板。

监控指标采集

  1. 添加依赖:在 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'
  1. 配置 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: prometheus
  metrics:
    export:
      prometheus:
        enabled: true

上述配置中,management.endpoints.web.exposure.include指定暴露prometheus端点,management.metrics.export.prometheus.enabled启用 Prometheus 的指标导出功能。

  1. 启动 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 界面。

  1. 配置 Prometheus:在prometheus.yml配置文件中,添加 Spring Boot 应用作为监控目标。例如:
scrape_configs:
  - job_name:'spring-boot-application'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    static_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端点抓取指标数据。

可视化面板配置

  1. 安装 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。

3.4 告警配置(基于 Grafana 设置异常指标告警)

在 Grafana 中设置告警规则可以帮助我们及时发现应用程序中的异常情况,当监控指标出现异常时及时发出警报。下面介绍如何在 Grafana 中进行告警配置。

  1. 设置告警通知渠道:在 Grafana 中,首先需要配置告警通知渠道,以便在告警触发时能够将通知发送出去。常见的通知渠道有邮件、钉钉机器人、Webhook 等。以配置邮件通知为例,点击左侧菜单栏的 “Configuration” -> “Notification channels”,然后点击 “Add channel”,选择 “Email”。在配置页面中,填写邮件服务器的相关信息,如 SMTP 服务器地址、端口、用户名、密码等,以及接收告警通知的邮件地址,保存配置。如果要配置钉钉机器人通知,同样在 “Add channel” 中选择 “Webhook”,在 Webhook URL 中填写钉钉机器人的 Webhook 地址,并根据钉钉机器人的要求设置请求头和请求体等参数。
  2. 创建告警规则:点击要设置告警规则的面板,然后点击面板右上角的 “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),用于在告警通知中显示更多的信息,例如告警的原因、解决方法等。

  1. 测试和启用告警规则:完成告警规则设置后,点击 “Test rule” 按钮可以手动测试告警规则是否正常工作。Grafana 会模拟触发告警条件,检查是否能够正确发送通知。如果测试通过,点击 “Enable alert rule” 按钮启用告警规则。此后,当监控指标满足告警触发条件时,Grafana 会按照配置的通知渠道发送告警通知,帮助我们及时发现和处理。

到此这篇关于Spring Boot从打包到监控的全链路攻略的文章就介绍到这了,更多相关Spring Boot从打包到监控内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文