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

http://blog.csdn.net/github_32521685/article/details/50463895

Spring Boot 性能优化的更多相关文章

  1. 170322、Spring Boot 性能优化之将Servlet容器变成Undertow

    需求缘起:在研究Spring Boot加速启动的时候,发现我们在实际中,可能比较注重我们服务器的内存的情况,那么我们会想如果在启动的时候,所占用的内存越低是越好,基于这个想法,我们看看Spring B ...

  2. Spring boot 内存优化

    转自:https://dzone.com/articles/spring-boot-memory-performance It has sometimes been suggested that Sp ...

  3. 使用Spring Boot DevTools优化你的开发体验

    场景再现 某日少年收到前端同学发来的消息说联调的接口响应异常

  4. Spring Boot Logback应用日志

    e Spring Boot Logback应用日志 2015-09-08 19:57 7673人阅读 评论(0) 收藏 举报 . 分类: Spring Boot(51) . 目录(?)[+] 日志对于 ...

  5. 【SpringBoot】SpringBoot性能优化

    Spring 框架给企业软件开发者提供了常见问题的通用解决方案,包括那些在未来开发中没有意识到的问题.但是,它构建的 J2EE 项目变得越来越臃肿,逐渐被 Spring Boot 所替代.Spring ...

  6. 这样优化Spring Boot,启动速度快到飞起!

    微服务用到一时爽,没用好就呵呵啦,特别是对于服务拆分没有把控好业务边界.拆分粒度过大等问题,某些 Spring Boot 启动速度太慢了,可能你也会有这种体验,这里将探索一下关于 Spring Boo ...

  7. 15套java架构师、集群、高可用、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...

  8. Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战

    视频课程内容包含: 高级 Java 架构师包含:Spring boot.Spring cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.Zer ...

  9. java架构师负载均衡、高并发、nginx优化、tomcat集群、异步性能优化、Dubbo分布式、Redis持久化、ActiveMQ中间件、Netty互联网、spring大型分布式项目实战视频教程百度网盘

    15套Java架构师详情 * { font-family: "Microsoft YaHei" !important } h1 { background-color: #006; ...

随机推荐

  1. mac xcworkspace xcodebuild

    xcodebuild 在介绍xcodebuild之前,需要先弄清楚一些在XCode环境下的一些概念[4]: Workspace:简单来说,Workspace就是一个容器,在该容器中可以存放多个你创建的 ...

  2. iOS开发Swift篇—(四)运算符

    iOS开发Swift篇—(四)运算符 一.运算符 1.Swift所支持的部分运算符有以下一些 赋值运算符:= 复合赋值运算符:+=.-= 算术运算符:+.-.*./ 求余运算符:% 自增.自减运算符: ...

  3. 制造业如何基于BPM做供应链管理?

    公司介绍深圳市吉祥腾达科技有限公司是中国网络产业的开航者,是中国无线网络领域的首批开拓者之一.历经10年的开拓创新,已经形成了拥有自主研发的全面产品线. 为了使公司物流.资金流和信息流实现优化整合,腾 ...

  4. linux命令每日一练习-mkdir,rm

    mkdir 创建一个文件夹 mkdir -p tian/hong 递归创建文件目录 mkdir tian hong 创建多个文件 mkdir -v tian 创建文件的时候显示信息 mkdir -m ...

  5. iOS 图片填充 UIImageView (contentMode)

    掐指算下来做iOS开发也是有两年多的时间了,然后今天一个超级常用的控件让我颜面大跌,于是我准备把自己的丢人行径公之于众.如果您看到我这篇文章时和我一样,也是刚刚知道这项功能,那么您就当收获了一个... ...

  6. python3 使用pyperclip读写剪贴板(windows)

    2016年5月14日 03:41:38 codegay 使用pyperclip库读写剪贴板非常简单~, 1.使用命令安装: pip install pyperclip 2.然后...就可以了: 以下是 ...

  7. jQueryMobile控件之展开与合并

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. C语言获得数组长度的函数

    <转自百度知道> 1.c语言中,定义数组后可以用sizeof命令获得数组的长度(可容纳元素个数). 例如: int data[4]; int length; length=sizeof(d ...

  9. 2016 - 1- 24 大文件下载 关于NSOutStream 的使用补充

    // // ViewController.m // 大文件下载 // // Created by Mac on 16/1/24. // Copyright © 2016年 Mac. All right ...

  10. windows核心编程---第三章 内核对象及句柄本质

      本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...