Spring应用启动分析优化

news2024/12/27 9:31:58

最近在搞应用的启动优化,参考一些可以显著提高 Java 启动速度方法和spring-boot-startup-report实现了此项目,Spring Startup Ananlyzer 采集Spring应用启动过程数据,生成交互式分析报告(HTML),用于分析Spring应用启动卡点,优化Spring应用启动速度,并实现了一个Bean初始化方法异步化执行工具,实现了应用启动时长降低50%-60%。

🤩核心能力

📈Spring应用启动数据采集报告

Spring Bean初始化详情信息,支持初始化耗时/beanName搜索、Spring Bean初始化时序图方法调用次数及耗时统计(支持自定义方法)、应用未加载的jar包(帮助fatjar瘦身)及应用启动过程线程wall clock火焰图,帮助开发者快速分析定位应用启动卡点。

  1. Spring Bean初始化详情
    spring-bean-initialization
  2. Spring Bean初始化时序图
    spring-bean-timeline
  3. 方法调用次数、耗时统计(支持自定义方法)
    details-of-method-invoke
  4. 应用未加载的jar包(帮助fatjar瘦身)
    unused-jars
  5. 应用启动过程线程wall clock火焰图(支持指定线程名称,不指定则采集全部线程)
    flame-graph

🚀应用启动时长优化

提供一个Spring Bean异步初始化jar包,针对初始化耗时比较长的bean,异步执行init和@PostConstruct方法提高应用启动速度。

📈Spring应用启动数据采集报告

安装jar包

提供了手动安装一键脚本安装两种安装方式

  1. 手动安装
  • 点击realease下载最新版tar.gz包

  • 新建文件夹,并解压


mkdir -p ${HOME}/spring-startup-analyzer

cd 下载路径

tar -zxvf spring-startup-analyzer.tar.gz ${HOME}/spring-startup-analyzer

  1. 脚本安装

curl -sS https://raw.githubusercontent.com/linyimin0812/spring-startup-analyzer/main/bin/install.sh | sh

配置项

在启动参数中进行配置,如配置超时时间为30分钟:-Dspring-startup-analyzer.app.health.check.timeout=30

请务必配置spring-startup-analyzer.app.health.check.endpoints选项,不然会一直采集直到应用启动检查超时时间(默认20分钟)才会停止,每隔1秒请求一次endpoint,请求响应头状态码为200则认为应用启动完成。默认健康检查URL:http://127.0.0.1:7002/actuator/health

配置项说明默认值
spring-startup-analyzer.app.health.check.timeout应用启动健康检查超时时间,单位为分钟20
spring-startup-analyzer.app.health.check.endpoints应用启动成功检查url,可配置多个,以","分隔http://127.0.0.1:7002/actuator/health
spring-startup-analyzer.admin.http.server.port管理端口8065
spring-startup-analyzer.async.profiler.sample.thread.namesasync profiler采集的线程名称,支持配置多个,以","进行分隔main
spring-startup-analyzer.async.profiler.interval.millisasync profiler采集间隔时间(ms)5

应用启动

此项目是以agent的方式启动的,所以在启动命令中添加参数-javaagent:$HOME/spring-startup-analyzer/lib/spring-profiler-agent.jar即可。如果是以java命令行的方式启动应用,则在命令行中添加,如果是在IDEA中启动,则需要在VM options选项中添加。

日志文件路径:$HOME/spring-startup-analyzer/logs

  • startup.log: 启动过程中的日志

  • transform.log: 被re-transform的类/方法信息

应用启动完成后会在console和startup.log文件中输出======= spring-startup-analyzer finished, click http://localhost:8065 to visit details. ======,可以通过此输出来判断采集是否完成。

自定义扩展

如果需要自定义观测能力,需要引入spring-profiler-starter的pom作为扩展项目的父pom,然后就可以使用项目对外暴露的接口进行扩展。更多的细节可以参考spring-profiler-extension的实现


<parent>

    <groupId>io.github.linyimin0812</groupId>

    <artifactId>spring-profiler-starter</artifactId>

    <version>2.0.0</version>

</parent>

扩展接口

public interface EventListener extends Startable {

    /**
     * 应用启动时调用
     */
    void start();

    /**
     * 应用启动完成后调用
     */
    void stop();
    
    /**
     * 需要增强的类
     * @param className 类全限定名, 如果为空, 默认返回为true

     * @return true: 进行增强, false: 不进行增强
     */
    boolean filter(String className);

    /**
     * 需要增强的方法(此方法会依赖filter(className), 只有filter(className)返回true时,才会执行到此方法)
     * @param methodName 方法名
     * @param methodTypes 方法参数列表
     * @return true: 进行增强, false: 不进行增强
     */
    default boolean filter(String methodName, String[] methodTypes) {
        return true;
    }

    /**
     * 事件响应处理逻辑
     * @param event 触发的事件
     */
    void onEvent(Event event);

    /**
     * 监听的事件
     * @return 需要监听的事件列表
     */
    List<Event.Type> listen();

}

其中start()和stop()方法代表系统的生命周期,分别在应用开始启动和应用启动完成时调用。filter()方法指定需要增强的类/方法。listen()方法指定监听的事件,包括进入方法和方法返回两种事件。onEvent()方法在监听的事件发生时会被调用

例如下面是一个统计应用启动过程中java.net.URLClassLoader.findResource(String)方法调用次数的扩展

打包运行

spring-profiler-starter的pom中已经定义了打包plugin,默认会将生成的jar包拷贝到$HOME/spring-startup-analyzer/extension文件下。


mvn clean package

只要按照步骤安装jar包安装好此项目,再执行上述的打包命令,打包好后再启动应用即可加载扩展jar包。

🚀应用启动时长优化

从应用启动数据采集中,可以获取初始化耗时长的Bean,因为Spring启动过程是单线程完成的,为了优化应用的启动时长,可以考虑将这些耗时长的Bean的初始化方法异步化,查看实现原理。

需要注意:

  • 应该优先从代码层面优化初始化时间长的Bean,从根本上解决Bean初始化耗时长问题

  • 对于二方包/三方包中初始化耗时长的Bean(无法进行代码优化)再考虑Bean的异步化

  • 对于不被依赖的Bean可以放心进行异步化,可以通过各个Bean加载耗时中的Root Bean判断Bean是否被其他Bean依赖

  • 对于被依赖的Bean需要小心分析,在应用启动过程中不能其他Bean被调用,否则可能会存在问题

支持异步化的Bean类型

支持@Bean, @PostConstruct@ImportResource 方式初始化bean,使用demo: spring-boot-async-bean-demo

1. @Bean(initMethod = “init”)标识的Bean


@Bean(initMethod = "init")

public TestBean testBean() {

    return new TestBean();

}

2. @PostConstruct标识的Bean


@Component

public class TestComponent {

    @PostConstruct

    public void init() throws InterruptedException {

        Thread.sleep(20 * 1000);

    }

}

接入异步Bean优化

1. 添加pom依赖


<dependency>   

  <groupId>io.github.linyimin0812</groupId>   

  <artifactId>spring-async-bean-starter</artifactId>   

  <version>2.0.0</version>

</dependency>

2. 配置一步加载信息


# 异步化的Bean可能在Spring Bean初始化顺序的末尾,导致异步优化效果不佳,打开配置优先加载异步化的

Beanspring-startup-analyzer.boost.spring.async.bean-priority-load-enable=true

# 指定异步的Bean名称

spring-startup-analyzer.boost.spring.async.bean-names=testBean,testComponent

# 执行异步化Bean初始化方法线程池的核心线程数

spring-startup-analyzer.boost.spring.async.init-bean-thread-pool-core-size=8

# 执行异步化Bean初始化方法线程池的最大线程数

spring-startup-analyzer.boost.spring.async.init-bean-thread-pool-max-size=8

3. 检查Bean是否异步初始化

查看日志$HOME/spring-startup-analyzer/logs/startup.log文件,对于异步执行初始化的方法,会按照以下格式写一条日志:

async-init-bean, beanName: ${beanName}, async init method: ${initMethodName}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/661011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让数据不再裸奔:学习使用AES加解密算法

目录 1. application.yml文件配置 2. AES加解密工具类 3. AES消息秘钥、AES秘钥初始向量、转字节数组工具类 4. AES加解密测试 我们为什么要用AES算法来进行加解密&#xff1f; AES&#xff08;Advanced Encryption Standard&#xff09;&#xff0c;又称高级加密标准&am…

C语言之生成随机数方法(C代码实现猜数字游戏)

C语言之生成随机数方法&#xff08;C代码实现猜数字游戏&#xff09; 首先先把猜数字游戏的代码给大家暂时出来&#xff0c;然后我们在根据代码的步骤一步一步的推导 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <tim…

【ChatGPT】一个凭借两百多年历史的公式崛起的巨星

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后端的开发语言A…

一分钟学一个 Linux 命令 - ps

前言 大家好&#xff0c;我是 god23bin。欢迎来到《一分钟学一个 Linux 命令》系列&#xff0c;每天只需一分钟&#xff0c;记住一个 Linux 命令不成问题。今天要说的是 ps 命令。 什么是 ps 命令&#xff1f; ps 的英文全称是 process status&#xff0c;意思是进程状态。 …

Servlet执行原理和API详解---【创建Servlet项目】

目录 一、Servlet 是什么&#xff1f; 主要工作&#xff1a; 第一个Servlet项目&#xff1a; 编写代码 打包程序 一、Servlet 是什么&#xff1f; Servlet 是一款基于HTTP协议&#xff0c;用来开发Java Web&#xff0c;运行在Tomcat里面的里的框架技术。 一种实现动态页面…

chatgpt赋能python:Python创建文件

Python创建文件 Python是一种高级编程语言&#xff0c;广泛应用于各种领域&#xff0c;尤其在数据分析、机器学习和人工智能方面被广泛使用。在Python中&#xff0c;创建文件是一项基本任务&#xff0c;本文将介绍如何使用Python创建文件。 创建一个空文件 在Python中&#…

3.CSS 的背景

通过CSS背景属性&#xff0c;可以给页面元素添加背景样式。 背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。 3.1背景颜色 background-color属性定义了元素的背景颜色 background-color:颜色值;一般情况下元素背景颜色默认值是transparent(透…

【实战】 React 与 Hook 应用:实现项目列表 —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表1.新建文件2.状态提升3.新建utils4.Custom Hook 学习内容来源&#xff1a;React React Hook TS 最佳实践-慕课网 相对原教程&#xff0c;我在学习开始时&#xff08;2023.0…

记录好项目D8

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是超市管理系统 技术栈&#xff1a;springbootjavamysqlthyemleafshiro …

数据安全--24--数据安全管理之API管理

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/131274853 一、API管理概述 API是指应用程序编程接口&#xff0c;它的存在主要是为了提高系统各组成单元的内聚性&#xff0c;降低组成单元之间的耦合程度&#xff08;相互依赖程度&#xff09;&#…

[元带你学: eMMC协议详解 18] eMMC的后台操作(Background Operations)

依JEDEC eMMC 5.1及经验辛苦整理&#xff0c;付费内容&#xff0c;禁止转载。 所在专栏 《元带你学: eMMC协议详解》 内容摘要 全文 1800 字&#xff0c; 主要内容 1、后台操作/前台操作区别&#xff1f; 2、如何进行手动后台操作&#xff1f; 3、自动后台启动和停止方法&a…

【Redis基础】

Redis基础 Redis基础Note Redis基础1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启1.3.7.wi…

web安全自学笔记

Web 安全方面的基本知识是有很必要的&#xff0c;未必就要深入理解。本文主要介绍常见的网络攻击类型&#xff0c;不作深入探讨。 正文 网络攻击的形式种类繁多&#xff0c;从简单的网站敏感文件扫描、弱口令暴力破解&#xff0c;到 SQL 注入&#xff0c;再到复杂的网络劫持等…

基于Web的影院信息管理系统设计与实现(论文+源码)_kaic

摘要 随着文化产业的发展&#xff0c;电影行业迎来了发展的黄金期&#xff0c;而且人民生活水平的 不断提高&#xff0c;观众对影院的服务要求也越来越高。传统的服务模式&#xff0c;已经不能满足 观众的需求&#xff0c;随着信息技术的发展&#xff0c;越来越多的影院将信息技…

Qt 中动态加载窗口

在编程中&#xff0c;我经常会遇见要根据用户触发按钮&#xff0c;动态生成窗口的情况。在此有两种方法可以动态生成窗口&#xff1a;一&#xff1a;直接在槽函数中调用窗口类。二&#xff1a;将 **.ui 添加到资源文件&#xff0c;通过 QUiLoader 加载。 现将两种方法介绍如下…

LAMPDISCUZ论坛

目录 1.1 LAMP 1.2 LAMP架构搭建 2. 关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下 APache的源码编译安装涉及到的软件包&#xff1a; 2.2 安装环境依赖包 2.3 配置软件模块 2.4 添加httpd系统服务 2.5 修改httpd 服务配置文件 3.编译安装mysqld 服务 3.1 …

1. CSS的三大特性

CSS有三个非常重要的三个特性&#xff1a;层叠性、继承性、优先级 1.1层叠性 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖(层叠)另一个冲突的样式。层叠性主要解决样式冲突 的问题 层叠性原则: ●样式冲突,遵循的原则是就近原则,哪个样式离结构近,就执行哪个…

记一次Windows 下Microsoft Store应用权限问题

关键字&#xff1a;windows、 microsoft store 画图 mspaint 终端 terminal Windows11 锁屏界面黑屏 起因 情不知所起&#xff0c;额走错片场了。。。 具体原因无法确定&#xff0c;猜测是由于之前磁盘故障后进行修复导致的权限丢失异常 表象 几乎是所有的Microsoft store的…

Java-反射机制(超详解)

Java反射机制概述 前言一、Java反射机制概述1. Java Reflection2. 动态语言 vs 静态语言二、 Class类的理解1. 类的加载过程1.1 初步了解1.2 类的加载过程图解1.3 了解&#xff1a;什么时候会发生类初始化&#xff1f;1.4 类加载器的作用1.5 JVM中不同类型的类的加载器1.6 代码…

SpringMVC系列-1 使用方式和启动流程

背景 SpringMVC作为SSM组件之一&#xff0c;Java开发有必要了解SpringMVC是如何被集成到Spring框架以及整个项目的启动流程。本文以Tomcat作为Servlet容器进行介绍&#xff0c;默认认为读者使用过Tomcat且对Tomcat内部组件有足够的理解。 1.启动流程 当Tomcat被部署到服务器…