酒水在什么网站做推广好,谷歌浏览器引擎入口,新乡网站建设那家好,哪个网站做签约插画师好引言
现状和背景
Spring框架是广泛使用的Java开发框架之一#xff0c;它提供了强大的功能和灵活性#xff0c;但在大型应用中#xff0c;由于Spring框架的复杂性和依赖关系#xff0c;应用的启动时间和性能可能会受到影响。这可能导致开发过程中的迟缓和开发效率低下。优…引言
现状和背景
Spring框架是广泛使用的Java开发框架之一它提供了强大的功能和灵活性但在大型应用中由于Spring框架的复杂性和依赖关系应用的启动时间和性能可能会受到影响。这可能导致开发过程中的迟缓和开发效率低下。优化Spring应用程序的启动速度和性能是一个重要的任务通过分析和优化应用的初始化过程、减少不必要的依赖和组件加载、并利用异步初始化、懒加载等技术可以显著改善应用的启动性能。这将帮助开发者提高开发效率、减少调试时间并提供更好的用户体验。
线上的业务 jar 包基本上普遍比较庞大动不动一个 jar 包几百 M启动时间在10分钟级拖慢了我们在故障时快速扩容的响应、以及本地开发调试效率。于是做了一些分析看看 Spring 程序启动慢到底慢在哪里如何去优化目前的效果是大部分大型应用启动时间可以缩短 70%~80%。
主要有下面这些内容
SpringBean 加载耗时 timeline 可视化分析✅SpringBean 的可视化依赖分析✅应用未加载的jar包(Jar瘦身)✅应用启动过程线程wall clock火焰图✅
重要性和影响
◦ 开发效率提高较快的应用启动速度可以显著减少开发和调试的时间。开发人员能够更快地启动应用程序进行功能测试和调试从而提高开发效率和迭代速度。
◦ 部署和扩展效率提升优化启动速度可以减少部署和扩展应用程序的时间和成本。快速启动的应用程序可以更快地响应负载变化提高系统的可伸缩性和弹性。
◦ 资源利用率优化通过减少初始化时间和优化资源加载可以降低应用程序的内存和CPU占用率。这有助于提高服务器的利用率并降低运行应用程序的成本。
分析工具
ArthasArthas是一个开源的Java诊断工具可以实时监控和诊断Java应用程序。它提供了丰富的命令和功能用于分析应用程序的性能问题包括启动过程中的资源消耗和加载时间。JVM SandboxJVM Sandbox是一种基于Java安全管理器的技术用于隔离和限制Java应用程序的访问权限。它可以帮助减少启动时的资源消耗和加载时间提高应用程序的启动速度。Async ProfilerAsync Profiler是一个低开销的异步Java性能分析工具用于收集和分析应用程序的性能数据。它可以帮助你找出启动过程中的性能瓶颈以及其他影响启动速度的问题。启动加速-异步初始化方法异步初始化方法是一种启动加速的技术通过将一些初始化任务异步执行可以减少启动时间并提高应用程序的响应性。这可以通过使用线程池、异步框架或异步注解等方式来实现。Spring Boot Startup ReportSpring Boot Startup Report是一个用于生成Spring Boot应用程序启动报告的工具。它可以提供详细的启动过程信息包括每个bean的加载时间、自动配置的耗时等帮助你分析和优化启动过程。Jaeger UI Jaeger UI是一个用于可视化和分析分布式追踪数据的工具。通过使用Jaeger UI你可以监控和分析应用程序的启动过程识别潜在的性能问题和瓶颈。Spring Startup AnalyzerSpring Startup Analyzer是一个用于采集Spring应用程序启动过程数据并生成交互式分析报告的工具。它的目标是帮助分析Spring应用程序的启动卡点并支持Spring Bean的异步初始化以减少优化Spring应用程序的启动时间。该工具支持在Linux、Mac和Windows操作系统上运行并参考了spring-boot-startup-report实现其用户界面。使用Spring Startup Analyzer可以收集应用程序的启动过程数据并生成可视化的HTML报告。这个报告可以帮助你分析Spring应用程序的启动性能并找出潜在的优化机会。
Spring Startup Analyzer优化方案
借助Spring startup analyzer的能力我们以业务线的ARK项目为例深入研究如何优化提效Spring项目的启动过程。下面我们先观察下ARK的基本启动情况
启动概览
Startup Time(s)启动时长Num of Bean初始化的Bean数量Used/Total Jars使用Jar数量/总量Unused/Total Jars未使用Jar数量/总量ClassLoader Count类加载器数量 Spring Bean初始化详情
Name一级name对应着Bean的名称Duration with children (ms) Bean的引用加载时长Duration (ms) Bean本身的加载时长Detail包含类加载器、加载该Bean的线程信息异步加载的话会有多个不同的 SpringBean 加载耗时 timeline 可视化分析
这个观察项可以一直下探直到Bean引用的最末级可以看出每一级的加载时长 应用启动过程线程wall clock火焰图
如何看懂火焰图
y 轴表示调用栈每一层都是一个函数。调用栈越深火焰就越高顶部就是正在执行的函数下方都是它的父函数。
x 轴表示抽样数如果一个函数在 x 轴占据的宽度越宽就表示它被抽到的次数多即执行的时间长。注意x 轴不代表时间而是所有的调用栈合并后按字母顺序排列的。
火焰图就是看顶层的哪个函数占据的宽度最大。只要有平顶plateaus就表示该函数可能存在性能问题。
颜色没有特殊含义因为火焰图表示的是 CPU 的繁忙程度所以一般选择暖色调
火焰图总览
从总览图中可以看出有三个入口函数占用百分比较大下面分别看一下 火焰局部图1
这部分火焰图可以看出springfox在启动过程做了很多初始化占了大量时间对于不需要该功能的项目可以直接下掉 火焰局部图2
了解下spring bean 的初始化过程 从这个图中可以看出bean的创建过程也占了很多时间 火焰局部图3
从这个图中可以看出注册BeanPostProcessor也耗费了大量时间 应用未加载的jar包(Jar瘦身)
这一个观察项可以搜集到项目启动完之后没有用到的Jar包 实施与优化效果
操作步骤和配置项
安装Spring Startup Analyzer
手动安装 点击realease下载最新版tar.gz包 新建文件夹并解压
linux/mac系统可以考虑使用以下命令
mkdir -p ${HOME}/spring-startup-analyzercd 下载路径
tar -zxvf spring-startup-analyzer.tar.gz -C 安装路径/spring-startup-analyzer
脚本安装(linux/mac)
curl -sS https://raw.githubusercontent.com/linyimin0812/spring-startup-analyzer/main/bin/install.sh | sh
脚本默认安装路径$HOME/spring-startup-analyzer
应用启动
spring-startup-analyzer是以agent的方式启动的所以在启动命令中添加参数-javaagent:安装路径/spring-startup-analyzer/lib/spring-profiler-agent.jar即可。
以java命令行的方式启动应用则在命令行中添加参数例如
java -javaagent:/Users/runner/spring-startup-analyzer/lib/spring-profiler-agent.jar \-Dproject.namemac-demo \-Dspring-startup-analyzer.admin.http.server.port8066 \-jar /Users/runner/spring-startup-analyzer/ARK.jar
IDEA中启动则需要在VM options选项中添加 日志文件路径安装路径/spring-startup-analyzer/logs
startup.log: 启动过程中的日志transform.log: 被re-transform的类/方法信息
应用启动完成后会在console和startup.log文件中输出 spring-startup-analyzer finished, click http://localhost:xxxx to visit details. 可以通过此输出来判断采集是否完成。
启动时间和性能改善情况
优化之前
预发平均启动10分钟本地无法启动每次需求需要提交到预发环境验证开发和发版周期比较长且预发环境连接的生产库不能随便造数。项目引用585个jar其中有337个jar没用到。 慢bean分析
分析可以看到耗时排名前面的接口都是jsf相关的加载还有一个es相关的bean。
功能路径Details of Method Invoke -- AbstractAutowireCapableBeanFactory.createBean jsf启动优化
注index“注册中心地址”中的“注册中心地址“做了匿名在具体场景查看自己代码中的配置
jsf的生产者的注册中心在启动的时候会拉取一批ip不断尝试注册jsf在办公环境这些ip无法访问导致启动过程一直重试 !-- 预发、生产的注册中心 --jsf:registry idjsfRegistry protocoljsfRegistry index注册中心地址/
在本机host里面增加jsf发布地址的host配置,下面*...* 在使用的时候替换成自己的可以 ping test.注册中心地址 获取。“注册中心地址” 替换成上面index后面的地址
*.*.*.* 注册中心地址
再次启动项目时长来到185s 开启Bean懒加载
将ES的Bean初始化进行懒加载以及开启全局懒加载时长来到131s
全局懒加载
1、根据spring版本的不同开启全局懒加载的方式可能会不相同
2、不建议生产环境开启全局懒加载因为基本上我们的服务都是部署在k8s上的有可能服务在伸缩的时候在访问量大的时候由于懒加载的配置服务快速启动成功了会返回给docker容器服务已经准备就绪状态导致k8s把流量分给该服务导致预想不到的问题。 Jar瘦身
对于应用未使用的jar包可以谨慎剔除在剔除的时候一个一个下每下一个都要重复编译和启动验证是否会对项目造成影响这是一个持续和长期的过程Jar瘦身不仅对启动时长有收益而且对编译提效很明显减少了大量的Jar复制过程 最终效果
做完上述优化之后
本地能够启动和debug项目这对开发人员来说有极大的提效。预发使用该方案进行优化之后能够缩短项目编译以及发布的时间对于快速验证和迭代需求有极大提效。整体启动效率提升70%~80%。在intel芯片电脑启动速度在2min11s。在m1芯片的电脑速度会更快大概启动时间在90s左右。使用该思路可以优化大部分spring以及spring boot项目建议定期做一轮这种排查和优化。
优化关键点和方法
去除未使用的jar包定位未使用的jar包。通过分析和整理项目依赖可以将这些未使用的jar包从应用中移除减少编译、启动时间和资源消耗。优化慢速的Bean初始化找到启动耗时较长的Bean。可以考虑对这些接口和Bean进行优化例如使用延迟加载或异步加载的方式以减少启动时的耗时。取消不需要的发布对于本地开发环境而言如果不需要发布jsf接口可以在本地取消这部分的发布以节省启动时间。开启全局懒加载通过开启全局懒加载可以延迟加载一些不必要的组件和资源从而减少启动时间。确保在需要使用时才进行加载。拆分大型组件定位加载时间较长的组件可以考虑将其拆分成多个组件并在启动时只加载需要的部分。这样可以减少启动时的加载时间和资源消耗。使用性能分析工具结合之前提到的性能分析工具如Spring Startup Analyzer、Java Profiler、VisualVM等对应用进行性能分析。通过监测和分析应用的性能数据可以找到性能瓶颈并针对性地进行优化。定期进行代码优化和重构定期审查和优化代码识别和消除潜在的性能问题。使用优化的算法和数据结构减少不必要的计算和循环优化数据库查询等以提高应用的性能。使用缓存机制合理地使用缓存来减少对数据库或其他资源的频繁访问。通过缓存常用数据或计算结果可以显著提升应用的响应速度和性能。并行化处理如果有一些独立的任务可以并行处理可以考虑使用多线程或异步机制来提高处理速度和效率。
信息补充
oracle jdk8下载地址
https://www.oracle.com/java/technologies/downloads/#java8-mac
oracle登录账号
请联系作者提供免费账号
本地redis安装
https://redis.io/docs/install/install-redis/install-redis-on-windows/
spring-startup-analyzer启动分析工具
https://github.com/linyimin0812/spring-startup-analyzer/blob/main/README_ZH.md 作者京东健康 梁灿 来源京东云开发者社区 转载请注明来源