Spring Boot有多快,如何做性能优化

Spring Engineering团队的首要任务之一就是spring的性能,Spring Boot2.1之后能在10MB的堆中运行简单的Netty应用。

Spring Boot性能优化遵循一个简单的原则,使用最新的正式发布版本。

启动时间优化

Packaging:带有自己main方法的应用程序总是会更快,这也是Spring Boot自行构建打包插件的一个原因。

服务器:Tomcat、Jetty、Undertow之间没有明显的差异。

Netty在启动时速度会稍快一些,但在大型应用这一点很难注意到。

使用的功能越多,加载的类就越多。

根据应用的需要移除不必要的spring功能:如:Hibernate Validator,Jackson,如果需要JSON渲染使用Gson,Logback中改用slf4j-jdk14。

使用spring-context-indexer依赖,在编译时创建候选对象的静态列表提高大型应用的启动性能。

Spring Boot2.2之前,actuators对性能影响较大,如果负担不起可选择关闭。

Spring Boot2.2 之前,如果不使用JMX,通过参数JMXspring.jmx.enabled=false关闭

使用延迟加载:

spring.main.lazy-initialization=true
spring.data.jpa.repositories.bootstrap-mode=lazy

使用显式类路径运行。

禁用字节码验证:

-noverify -XX:-UseSplitVerifier

禁用jdk解释器多层编译模式:

禁用C1只用C2:

-noverify -XX:-TieredCompilation

禁用C2只用C1:

-noverify -XX:TieredStopAtLevel=1

说明:C1、C2对应多层编译模式,禁用后会限制JVM在运行时优化自身的能力。

关于多层编译可以参考豆瓣中的一篇文章和oracle的演示稿

https://book.douban.com/annotation/31392220/
http://cr.openjdk.java.net/~iveresov/tiered/Tiered.pdf

一个更极端的选择是使用功能Bean(functional bean)重新定义所有应用程序配置。包括正在使用的所有Spring Boot自动配置,其中大部分都可以重复使用。如果尝试这种方法,启动时间可能会缩短2倍,看看BuncApplication在微应用程序,看看如何不启动春季启动@Configuration级处理器。

排除netty-transport-native-epollc也会使应用提高约 30 毫秒(仅Linux)。

如有这方面的需求可参考spring官方给出的建议:

https://github.com/dsyer/spring-boot-allocations
https://github.com/dsyer/spring-boot-micro-apps

说明:这将减慢JIT以后以牺牲节省的启动时间

启动命令行中使用参数(spring.config.location)指定配置文件,覆盖Spring Boot默认配置。

spring.config.location=file:./src/main/resources/application.properties

堆内存优化

关于内存优化很多工作需要做,优化方案只是一部分,前期有针对性的调查才是关键,此处就不再举例了,免得挂一漏万,具体思路参考spring官方的早期文章:

https://spring.io/blog/2015/12/10/spring-boot-memory-performance