启用S​​pring Boot ApplicationStartup度量标准以诊断启动缓慢


概述

在应用程序启动过程中,Spring Boot在后台执行大量工作。这项工作涉及创建Spring Application Context,创建各种bean,自动装配和各种组件的自动配置,最后启动应用程序。当Spring Boot应用程序的启动速度很慢时,它可能是一个或多个bean和相关的依赖项,需要花费更长的时间来初始化和减慢整个过程。

对Spring Boot应用程序进行性能分析通常无法帮助诊断启动问题。这是因为初始化了许多Bean,而实际上很难弄清是哪些导致了延迟。在这种情况下,Spring Boot应用程序启动指标非常有用。

在本教程中,我们将在Spring Boot应用程序中启用ApplicationStartup指标。我们还将启用S​​pring Boot Actuator启动端点来监视启动指标。最后,我们将使用Java Flight Recorder记录应用程序启动指标。

ApplicationStartup和StartupStep

在Spring Boot 2.4发布之前, 确实很难确定启动缓慢的根本原因。但是,在Spring Boot 2.4.0中,我们有机会生成ApplicationStartup指标,该指标可用于准确确定哪个部分花费的时间更长。

尽管该ApplicationStartup接口及其概念是Spring Boot的新功能,但它们自5.3版本以来就是Spring Framework的一部分。启动度量标准提供了组件初始化,bean实例及其依赖关系链接的详细日志和逐步减少的日志。而且,这些度量提供每个粒度步骤的开始和结束时间,这对于确定最慢的位非常有帮助。

在应用程序启动指标期间,捕获整个启动过程的过程分为多个步骤,这些步骤由StartupStep接口表示。每个步骤都有一个唯一的ID,即步骤名称,父ID。同样,这些实现记录步骤的开始和结束时间。使用它们,我们可以发现哪一步比预期的慢。

启用ApplicationStartup指标 为了启用ApplicationStartup指标,我们需要确保使用的是Spring Boot 2.4.0或更高版本。

pom.xml:

<parent>        
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.2</version>
    <relativePath/>
</parent>

或build.gradle:

plugins {    
    id 'org.springframework.boot' version '2.4.2'    
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'    
    id 'java' 
}

现在,SpringApplication该类将启动任何Spring Boot应用程序,该类将获取setStartup方法,该方法采用ApplicationStartup接口的实现。

package com.amitph.spring.tutorials.students;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        application.setApplicationStartup(new BufferingApplicationStartup(10000));
        application.run(args);
    }
}

在上面的示例中,我们创建的实例SpringApplication,并在调用在应用程序上run设置的方法applicationStartup并传递的实例之前BufferingApplicationStartup。另外,我们可以FlightRecorderApplicationStartup通过JFR来监视启动指标。接下来,我们将了解有关这两种启动实现的更多信息。

具有/ startup执行器端点的ApplicationStartup指标 该应用程序启动的指标可以从监控/startup终端在 春季启动器。为此,我们需要插入缓冲应用程序启动并启用/startup端点。

第一步是插件BufferingApplicationStartup

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(Application.class);
    application.setApplicationStartup(
      new BufferingApplicationStartup(10000));
    application.run(args);
}

我们将缓冲区容量指定为10000。将应用程序启动指标捕获到/startup执行器端点中可用的缓冲区中。

接下来,我们将/startup在执行器属性中启用端点。

在 application.yml 文件中:

management:
  endpoints:
    web:
      exposure:
        include: 'startup'

或者,在application.properties文件中:

management.endpoints.web.exposure.include=startup

启用后,我们需要启动执行器并在/actuator/startup端点上执行POST请求。

我们可以http://host:port/actuator/startup从Web浏览器执行,或curl如下所示使用。

curl --location --request POST'http:// localhost:8080 / actuator / startup'

接下来,是显示StudentRepository,StudentControllerBean及其创建开始和结束时间的输出片段。

{
                "startupStep": {
                    "name": "spring.beans.instantiate",
                    "id": 123,
                    "parentId": 122,
                    "tags": [
                        {
                            "key": "beanName",
                            "value": "studentRepository"
                        }
                    ]
                },
                "startTime": "2021-01-26T06:38:09.234585991Z",
                "endTime": "2021-01-26T06:38:09.380445297Z",
                "duration": "PT0.145859306S"
            },
            {
                "startupStep": {
                    "name": "spring.beans.instantiate",
                    "id": 122,
                    "parentId": 5,
                    "tags": [
                        {
                            "key": "beanName",
                            "value": "studentsController"
                        }
                    ]
                },
                "startTime": "2021-01-26T06:38:09.231829732Z",
                "endTime": "2021-01-26T06:38:09.382129262Z",
                "duration": "PT0.15029953S"
            },

这是需要注意的重要,虽然/启动端点返回一个JSON的端点遵循 了 HTTP POST方法。此外,指标存储在缓冲区中,因此端点将仅返回一次。

Java Flight RecorderApplicationStartup指标

在Java的飞行记录器(JFR)是一个监测工具,是JVM的一部分。它可以从Java应用程序收集各种指标和诊断数据,并提供分析它们的工具。

为了使用Java Flight Recorder查看ApplicationStartup指标,我们需要使用FlightRecordingApplicationStartup

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(Application.class);
    application.setApplicationStartup(new FlightRecorderApplicationStartup());
    application.run(args);
}

完成后,我们需要将应用程序打包到JAR中。

为了使用Java Flight Recorder捕获指标,我们需要在运行应用程序时传递一些参数:

java -XX:+FlightRecorder \        
        -XX:StartFlightRecording=duration=5s,filename=myrecording.jfr \        
        -jar target/spring-boot-crud-jpa.jar

在这里,我们使用-XX:+FlightRecorder参数启用飞行记录器。接下来,我们指示通过传递XX:StartFlightRecording带有持续时间和文件名等选项的参数来开始度量记录。生成应用程序后,Java Flight Recorder指标将被记录到myrecording.jfr文件中。

我们可以使用JDK Mission Control之类的工具来打开和分析.jfr文件中的指标。

概括

在本教程中,我们学习了如何启用S​​pring Boot ApplicationStartup指标,这些指标可用于分析启动例程并诊断Spring Boot Applications的启动缓慢。我们还了解到,使用BufferingApplicationStartup可以启用的Spring Boot Actuator端点/startup,该端点提供了有用的指标。或者,我们可以使用Java Flight RecorderFlightRecodingApplicationStartup`来记录启动指标。


原文链接:http://codingdict.com