https://blog.csdn.net/zhong930/article/details/80121467
Spring 框架给企业软件开发者提供了常见问题的通用解决方案,包括那些在未来开发中没有意识到的问题。但是,它构建的 J2EE 项目变得越来越臃肿,逐渐被 Spring Boot 所替代。Spring Boot 让我们创建和运行项目变得更为迅速,现在已经有越来越多的人使用它。我们已经在几个项目中使用了 Spring Boot ,今天我们就来一起讨论一下如何改进 Spring Boot 应用的性能。
首先,从之前我在开发中遇到的一个问题说起。在一次查看项目运行日志的时候,我偶然发现了一个问题,日志里显示这个项目总是加载 Velocity 模板引擎,但实际上这个项目是一个没有 web 页面的 REST Service 项目。于是我花了一点时间去寻找产生这个问题的原因,以及如何改进 Spring Boot 应用的性能。在查找了相关的资料后,我得出的结论如下:
组件自动扫描带来的问题
默认情况下,我们会使用 @SpringBootApplication 注解来自动获取应用的配置信息,但这样也会给应用带来一些副作用。使用这个注解后,会触发自动配置( auto-configuration )和 组件扫描 ( component scanning ),这跟使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解的作用是一样的。这样做给开发带来方便的同时,也会有三方面的影响:
-
会导致项目启动时间变长。当启动一个大的应用程序,或将做大量的集成测试启动应用程序时,影响会特别明显。
-
会加载一些不需要的多余的实例(beans)。
-
会增加 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
如何避免组件自动扫描带来的问题
我们在上面提到,@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)
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
接着拷贝 Positive matches
中列出的信息:
DispatcherServletAutoConfiguration
EmbeddedServletContainerAutoConfiguration
ErrorMvcAutoConfiguration
HttpEncodingAutoConfiguration
HttpMessageConvertersAutoConfiguration
JacksonAutoConfiguration
JmxAutoConfiguration
MultipartAutoConfiguration
ServerPropertiesAutoConfiguration
PropertyPlaceholderAutoConfiguration
ThymeleafAutoConfiguration
WebMvcAutoConfiguration
WebSocketAutoConfiguration
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
然后来更新项目配置,显式地引入这些组件,引入之后,再运行一下应用确保没有错误发生:
@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 {
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
在上面的代码中,我们可以删掉我们不需要的组件信息,来提高应用的性能,比如在我的项目中,不需要 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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
然后添加 Undertow:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
启动项目后,用 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工程师 责编/仲浩)
相关热词: spring与 spring和 spring的和 spring的 spring常用
上一篇君子豹变,Think in Cloud 2015看互联网趋势与万众创新
下一篇Apache Zeppelin与Apache Kylin结合运用实践
区块链以太坊DApp开发为什么人才稀少?薪资到底有多高?
区块链开发平均薪资是多少?快速学习区块链开发,掌握以太坊开发和智能合约应用。
877
5907
6-4
Spring cloud开发内存占用过高解决方法 - CSDN博客
7-20
写这篇博客的目的可能反思多一些,前些日子一直想做docker内存的优化,没有做成,...本文主要是解决springboot maven打包jar太大。springBoot的web应用一般都添加了...
2.1万
SpringBoot测试版本 org.springframework.boot spring-boot-starter-parent 1.3.3.RELEASE ...
7-30
项目中需要一个Java HTTP服务器作为代理,这个服务只是偶尔执行几个命令,并没有什么负载(这个很关键)。基于Java语言、web服务器和开发效率上的考虑,我们选择了Spring...
7-25
Spring Boot 性能优化之将Servlet容器变成Undertow
78
837
项目中需要一个Java HTTP服务器作为代理,这个服务只是偶尔执行几个命令,并没有什么负载(这个很关键)。基于Java语言、web服务器和开发效率上的考虑,我们选择了Spring boot...
7-22
SpringBoot打包jar包并后台运行 - CSDN博客
7-1
604
解决SpringBoot jar包太大的问题 - CSDN博客
5-23
3-9
2347
请注意 SpringBoot 2.0 新坑 我刚刚从坑里爬出来
8160
以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持。 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被...
6-14
7-3
6119
4220
Java 开发基于Zookeeper,Spring,vue.js的高并发多用户模块化微信商城系统(四) Java微框架Spring Boot的应用
3606
140
这是入口 public class BeanScannerConfigurer implements BeanFactoryPostProcessor, ApplicationListener ...
37
5304
Spring Boot + Redis + MQ实现高并发点赞功能:项目实战
4750
springMVC一个Controller处理所有用户请求的并发问题
2.5万
springMVC一个Controller处理所有用户请求的并发问题 有状态和无状态的对象基本概念: 有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非...
1327
2.2万
Springboot+rabbitmq如何实现高并发的rpc调用
1966
一.背景 公司项目的收单前置服务A与收单服务B之间是通过rabbitmq来通信的,而且A服务在给B服务发送信息后,必须收到返回结果(同步通知),于是使用了此方法:rabb...
Spring Boot同步架构与Vert.x异步架构高并发性能对比
3404
java大数据 高并发 系统框架 springmvc mybatis Bootstrap html5
4561
获取【下载地址】 【免费支持更新】 A 代码生成器(开发利器); 增删改查的处理类,service层,mybatis的xml,SQL( mysql 和oracle)脚本...
10-SpringBoot——Spring 高级话题-多线程
8138
2.8万
2870
这一部分分为三个部分,启动部分的优化,Tomcat参数设置和内存调优 启动部分的优化 这一小节来自 Spring Boot 性能优化 http://www.cnblogs.com/chen110...
1019
438
springboot已经支持了定时任务Schedule模块,一般情况已经完全能够满足我们的实际需求。今天就记录一下我使用 schedule 时候踩的坑吧。 想要使用定时,我们首先要开启支持,其实...
417
1、new Maven project ,第一行 create a .... 打钩2、项目结构如下图,可以删除src,只保留pom3、右键该项目,new project 选择maven mode...
IDEA创建基于springboot的多个module聚合项目,并生成war包
7748
Springboot+Maven多模块开发 (一)初始化工程(新建第一个web工程)
3万
43
先建 parent pom工程 然后建 common 模块 pojo 模块 依赖 common mapper 模块 依赖 pojo ...
个人资料
粉丝
220
喜欢
1
评论
2
等级:
访问:
2万+
积分:
239
排名:
36万+
最新文章
- 史上最奇葩的5个编程语言,其指令更算计了奶牛、空格等
- Apache Spark作为编译器:深入介绍新的Tungsten执行引擎
- Spark多数据源计算实践及其在GrowingIO的实践
- 中国Spark技术峰会(下):七剑带你玩转Spark 2.0
- 中国Spark技术峰会(下):七剑带你玩转Spark 2.0
归档
- 2016年6月1篇
- 2016年5月17篇
- 2016年4月6篇
- 2016年3月22篇
- 2016年2月21篇
- 2016年1月39篇
- 2015年12月12篇
- 2015年5月2篇
- 2013年10月4篇
- 2013年8月1篇
- 2013年4月1篇
展开
热门文章
- 谷歌的新Stackdriver服务可以跨云管理应用
阅读量:3988
- 时序列数据库武斗大会之TSDB名录 Part 2
阅读量:3705
- Apple的部分业务将从AWS转移到Google云服务
阅读量:3678
- 深度学习和自然语言处理中的attention和memory机制
阅读量:2607
- 应用Docker+Jupyter快速搭建数据科研环境
阅读量:1030
最新评论
- 如何使用 Java8 实现观察者模...
qq_32204717:老板,你写的什么哦 ,能运行吗 public class Zoo { private L...
- 云计算是最终的计算架构?
u012025054:你好,希望可以邀请你加入 NetSuite产品群,779253701谢谢。