Spring Boot 性能优化

Spring 框架给企业软件开发者提供了常见问题的通用解决方案,包括那些在未来开发中没有意识到的问题。但是,它构建的 J2EE 项目变得越来越臃肿,逐渐被 Spring Boot 所替代。Spring Boot 让我们创建和运行项目变得更为迅速,现在已经有越来越多的人使用它。我们已经在几个项目中使用了 Spring Boot ,今天我们就来一起讨论一下如何改进 Spring Boot 应用的性能。

首先,从之前我在开发中遇到的一个问题说起。在一次查看项目运行日志的时候,我偶然发现了一个问题,日志里显示这个项目总是加载 Velocity 模板引擎,但实际上这个项目是一个没有 web 页面的 REST Service 项目。于是我花了一点时间去寻找产生这个问题的原因,以及如何改进 Spring Boot 应用的性能。在查找了相关的资料后,我得出的结论如下:

组件自动扫描带来的问题

默认情况下,我们会使用 @SpringBootApplication 注解来自动获取的应用的配置信息,但这样也会给应用带来一些副作用。使用这个注解后,会触发自动配置( auto-configuration )和 组件扫描 ( component scanning ),这跟使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解的作用是一样的。这样做给开发带来方便的同时,也会有两方面的影响:

1、会导致项目启动时间变长。当启动一个大的应用程序,或将做大量的集成测试启动应用程序时,影响会特别明显。

2、会加载一些不需要的多余的实例(beans)。

3、会增加 CPU 消耗。

针对以上两个情况,我们可以移除 @SpringBootApplication 和 @ComponentScan 两个注解来禁用组件自动扫描,然后在我们需要的 bean 上进行显式配置:

// 移除 @SpringBootApplication and @ComponentScan, 用 @EnableAutoConfiguration 来替代
@Configuration
@EnableAutoConfiguration
public class SampleWebUiApplication {
    // ...
    // 用 @Bean 注解明确显式配置,以便被 Spring 扫描到
    @Bean
    public MessageController messageController(MessageRepository messageRepository) {
        return new MessageController(messageRepository);
    }

如何避免组件自动扫描带来的问题

我们在上面提到,@SpringBootApplication 注解的作用跟 @EnableAutoConfiguration 注解的作用是相当的,那就意味着它也能带来上述的三个问题。要避免这些问题,我们就要知道我们需要的组件列表是哪些,可以用 -Ddebug 的方式来帮助我们明确地定位:

mvn spring-boot:run -Ddebug
…
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
   DispatcherServletAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - found web application StandardServletEnvironment (OnWebApplicationCondition)
...

接着拷贝 Positive matches 中列出的信息:

DispatcherServletAutoConfiguration
EmbeddedServletContainerAutoConfiguration
ErrorMvcAutoConfiguration
HttpEncodingAutoConfiguration
HttpMessageConvertersAutoConfiguration
JacksonAutoConfiguration
JmxAutoConfiguration
MultipartAutoConfiguration
ServerPropertiesAutoConfiguration
PropertyPlaceholderAutoConfiguration
ThymeleafAutoConfiguration
WebMvcAutoConfiguration
WebSocketAutoConfiguration

然后来更新项目配置,显式地引入这些组件,引入之后,再运行一下应用确保没有错误发生:

@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        JmxAutoConfiguration.class,
        MultipartAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        ThymeleafAutoConfiguration.class,
        WebMvcAutoConfiguration.class,
        WebSocketAutoConfiguration.class,
})
public class SampleWebUiApplication {

在上面的代码中,我们可以删掉我们不需要的组件信息,来提高应用的性能,比如在我的项目中,不需要 JMX 和 WebSocket 功能,我就删掉了它们。删掉之后,再次运行项目,确保一切正常。

将Servlet容器变成Undertow

默认情况下,Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器。我们可以启动项目,然后用 VisualVM 或者 JConsole 来查看应用所占的内存情况:

以上是我使用 Spring Boot 的默认方式启动应用后,用 VisualVM 监控到的内存的占用情况:堆内存占用 110M,16 个线程被开启。

可以将 Web 服务器切换到 Undertow 来提高应用性能。Undertow 是一个采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。Undertow 是红帽公司的开源产品,是 Wildfly 默认的 Web 服务器。首先,从依赖信息里移除 Tomcat 配置:

<exclusions>
        <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
</exclusions>

然后添加 Undertow:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

启动项目后,用 VisualVM 监控到的信息显示:堆内存占用 90M,13个线程被开启。

总结

这些都是我们在项目开发中使用到的一些优化 Spring 
Boot 应用的小技巧,对于大的应用性能的提高还是很明显的。大家可以尝试一下,然后告诉我们你的测试结果。

最后,附上代码,大家可以去这里下载:spring-boot-performance

文中大部分内容参考英国一个架构师的博客 和 DZone 近期发布的文章,在此感谢两位大牛。参考文章及链接:

(1)Spring Boot 性能优化:Spring Boot Performance

(2)Spring Boot 内存优化:Spring Boot Memory Performance

(3)https://www.techempower.com/benchmarks/

(4)Spring 应用程序优化:Optimizing Spring Framework for App Engine Applications

OneAPM 为您提供端到端的 Java 应用性能解决方案,我们支持所有常见的 Java 框架及应用服务器,助您快速发现系统瓶颈,定位异常根本原因。分钟级部署,即刻体验,Java 监控从来没有如此简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客

本文转自 OneAPM 官方博客

时间: 2024-10-28 12:38:10

Spring Boot 性能优化的相关文章

Spring Boot 整合 Redis 实现缓存操作

一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解 运行环境: Mac OS 10.12.x JDK 8 + Redis 3.2.8 Spring Boot 1.5.1.RELEASE 一.缓存的应用场景 什么是缓存? 在互联网场景下,尤其2C端大流量场景下,需要将一些经常展现和不会频繁变更的数据,存放在存取速率更快的地方.缓存就是一个存储器,在技术选型中,常用 Re

Hibernate程序性能优化的考虑要点

程序|性能|优化 本文依照HIBERNATE帮助文档,一些网络书籍及项目经验整理而成,只提供要点和思路,具体做法可以留言探讨,或是找一些更详细更有针对性的资料. 初用HIBERNATE的人也许都遇到过性能问题,实现同一功能,用HIBERNATE与用JDBC性能相差十几倍很正常,如果不及早调整,很可能影响整个项目的进度. 大体上,对于HIBERNATE性能调优的主要考虑点如下: Ø 数据库设计调整 Ø HQL优化 Ø API的正确使用(如根据不同的业务类型选用不同的集合及查询API) Ø 主配置参

使用Spring Boot构建RESTful Web服务以访问存储于Aerospike集群

Spring Boot是对Spring快速入门的强大工具.Spring Boot能够帮助你很容易地构建基于Spring的应 用. Aerospike是分布式和可复制的内存数据库,不管使用DRAM还是原生的flash/SSD,Aerospike都进行 了优化. Aerospike具有高可靠性并且遵循ACID.开发人员能够在不停止数据库服务的情况下,很快地将 数据库集群从两个节点扩展到二十个节点. 你所要构建的是什么 本文将会引领你使用Spring Boot创建一个简单的RESTful Web服务.

深入实践Spring Boot导读

Preface?前 言 Spring Boot作为Java编程语言的一个全新开发框架,在国内外才刚刚兴起,还未得到普及使用.相比于以往的一些开发框架,Spring Boot不但使用更加简单,而且功能更加丰富,性能更加稳定而健壮.使用Spring Boot开发框架,不仅能提高开发速度,增强生产效率,从某种意义上,可以说是解放了程序员的劳动,而且一种新技术的使用,更能增强系统的稳定性和扩展系统的性能指标.本书就是本着提高开发效率,增强系统性能,促进新技术的普及使用这一目的而写的. Spring Bo

Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询

摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+,ElasticSearch 2.3.2 本文提纲 一.ES 的使用场景 二.运行 springboot-elasticsearch 工程 三.springboot-elasticsearch 工程代码详解 一.ES 的使用场景 简

《深入实践Spring Boot》一第一部分 Part 1基础应用开发

第一部分 Part 1 基础应用开发 第1章 Spring Boot入门 第2章 在Spring Boot中使用数据库 第3章 Spring Boot界面设计 第4章 提高数据库访问性能 第5章 Spring Boot安全设计 这一部分从搭建开发环境,简单入门,到使用数据库.界面设计.安全管理等一系列内容,介绍了使用Spring Boot框架进行基础应用开发的方法. 第1章介绍了开发环境的搭建和开发工具的选择和安装,并以一个非常简单的实例,演示了如何使用Spring Boot框架创建工程和发布应

利用 Spring Boot 在 Docker 中运行 Hadoop

本文讲的是利用 Spring Boot 在 Docker 中运行 Hadoop,[编者的话]Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.本文介绍了如何利用Spring Boot在Docker中运行Hadoop任务. 简介 越来越多的应用都开始使用Hadoop框架.而开发者在使用过程中也遇到一些挑战,比如使用诸如Docker之类的容器开发和部署相关的技术栈开发的应用.我们将会在下面的例子中介绍如何克服这些挑战. 由于 S

深入学习微框架:Spring Boot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以 及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. 多年以来,Spring IO平台饱受非议的一点就是大量的XML配置以及复杂的依赖管理.在去年的SpringOne 2GX会议上,Pivotal的CTO Adrian Co

一篇文章学会spring boot(包括jms和hessian的集成)

之前在学习spring cloud微服务的时候,由于spring cloud的基础是spring boot,因此曾简单地了解过spring boot,但也只是简单的了解过而已. 而现在,需要把struts2项目改为spring boot,一开始时以为是整个项目重构,不仅限于struts2部分,因此就相对更系统.更细致的学了一下spring boot. 整个过程由易到难,大概分成了这么些模块: 一.创建简单的spring boot web项目 很多时候学一个新的东西,都需要从最简单的地方开始,然后