Spring Boot 性能优化

 

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 三个注解的作用是一样的。这样做给开发带来方便的同时,也会有三方面的影响:

  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);
    }
  • 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工程师 责编/仲浩)

文章标签: JavaSpring

相关热词: spring与 spring和 spring的和 spring的 spring常用

上一篇君子豹变,Think in Cloud 2015看互联网趋势与万众创新

 

下一篇Apache Zeppelin与Apache Kylin结合运用实践

区块链以太坊DApp开发为什么人才稀少?薪资到底有多高?

区块链开发平均薪资是多少?快速学习区块链开发,掌握以太坊开发和智能合约应用。

SpringBoot--简单处理高并发demo

L1522985454

 877

目录结构:(只跟book相关的)model:package com.cxb.model;import javax.persistence.Column;import javax.persistence...

springboot手写JDBC面对2000并发量毫无压力

u011550710

 5907

声明:本博客所有文章都是原创,不会有任何抄袭现象。请转载的朋友,标注出处,谢谢。 最近比较流行springboot微服务,那么持久层到底怎么样才算好?面对高并发的压力,如何抵制?本文将以JDBC来...

指定springboot的jar运行内存 - CSDN博客

6-4

一般情况下,我们运行一个springboot的jar包,是这样运行的:java -jar xxx.jar如果想指定运行的内存,可以这样:java -Xms10m -Xmx200m -jar xxx.jar这个参数是...

Spring cloud开发内存占用过高解决方法 - CSDN博客

7-20

写这篇博客的目的可能反思多一些,前些日子一直想做docker内存的优化,没有做成,...本文主要是解决springboot  maven打包jar太大。springBoot的web应用一般都添加了...

 

SpringBoot优化内嵌的Tomcat

mn960mn

 2.1万

SpringBoot测试版本 org.springframework.boot spring-boot-starter-parent 1.3.3.RELEASE ...

Spring boot内存压榨 - CSDN博客

7-30

项目中需要一个Java HTTP服务器作为代理,这个服务只是偶尔执行几个命令,并没有什么负载(这个很关键)。基于Java语言、web服务器和开发效率上的考虑,我们选择了Spring...

springboot如何进行优化 - CSDN博客

7-25

这一部分分为三个部分,启动部分的优化,Tomcat参数设置和内存调优启动部分的优化这一小节来自 Spring Boot 性能优化  http://www.cnblogs.com/chen110xi/p/...

Spring Boot 性能优化之将Servlet容器变成Undertow

belalds

 78

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

Spring boot内存压榨

wy674396380

 837

     项目中需要一个Java HTTP服务器作为代理,这个服务只是偶尔执行几个命令,并没有什么负载(这个很关键)。基于Java语言、web服务器和开发效率上的考虑,我们选择了Spring boot...

springboot集成内存cache - CSDN博客

7-22

写这篇博客的目的可能反思多一些,前些日子一直想做docker内存的优化,没有做成,...指定springboot的jar运行内存 qq_37372909 04-27 1225 一般情况下,我们运行一...

SpringBoot打包jar包并后台运行 - CSDN博客

7-1

文章标签: springboo jar 部署linux 个人分类: IDE Spring Boot 想...直接前台执行:java -jar ./owl.jar 如果 Maven 运行过程出现内存溢出,则可.....

springboot在运行过程中莫名killed问题的解决

qq_32532853

 604

我们之前开发的系统是第一次基于springboot开发的,在测试阶段一直被一个问题困扰,就是程序莫名其妙就killed,没有打印什么堆栈内存不够的信息,用jamp -heap 命令也没有查找到内存有泄...

 

解决SpringBoot jar包太大的问题 - CSDN博客

5-23

本文主要是解决springboot maven打包jar太大。springBoot的web应用一般都添加了spring-boot-maven-plugin插件Maven xml代码 org.springframework.boot spring-boot-maven...

Spring Boot 性能优化 - CSDN博客

3-9

Spring Boot 性能优化 标签: spring boot打成jar包性能优 2017年10月27日 ...以上是我使用 Spring Boot 的默认方式启动应用后,用 VisualVM 监控到的内存的...

Spring boot 性能优化

qq_25353539

 2347

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

请注意 SpringBoot 2.0 新坑 我刚刚从坑里爬出来

xzyxcy

 8160

以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持。 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被...

Spring boot 项目内存管理 - CSDN博客

6-14

Spring Boot 性能优化 Spring 框架给企业软件开发者提供了常见问题的通用解决方案...指定springboot的jar运行内存 一般情况下,我们运行一个springboot的jar包,是这样...

Spring Boot 性能优化(1) - CSDN博客

7-3

java -jar shouse-0.0.1-SNAPSHOT.jar --debug … === AUTO-CONFIGURATION...Tomcat参数设置和内存调优启动部分的优化这一小节来自 Spring Boot 性能优化  ...

Spring Boot 2.0 的配置详解(图文教程)

GitChat

 6119

...

Spring cloud开发内存占用过高解决方法

wanhuiguizong

 4220

问题:在开发spring cloud过程中一个很严重的资源问题就是内存占用过高,而实际上本机开发测试并没有很大的请求量,所以这是对电脑资源的一种严重的浪费,甚至导致IDE卡死、崩溃。一个完整包含eur...

Java 开发基于Zookeeper,Spring,vue.js的高并发多用户模块化微信商城系统(四) Java微框架Spring Boot的应用

yanglinjingshu

 3606

一、简介从最初学习Java这门语言开始,就已经开始接触Spring。在过去的一段时间里,Spring Boot在社区中热度一直很高。Spring Boot不是一门新技术,从本质上来说,Spring B...

Spring 包扫描

github_39525088

 140

这是入口 public class BeanScannerConfigurer implements BeanFactoryPostProcessor, ApplicationListener ...

SpringMVC及Spring扫描包隔离及配置优化

anshengsuiyeu

 37

其实Spring和SpringMVC是有父子容器关系的,而且正是因为这个才会出现包扫描的问题,在此来分析和理解Spring和SpringMVC的父子容器关系并且给出Spring和SpringMVC配置...

 

springboot之几种同步,线程安全处理的方法

east123321

 5304

在一些公共资源的处理上,经常会出现对公共资源的争夺使用权限的问题,以及对数据库处理时,容易出现线程安全的问题,比如对数据操作时的一致性,可见性等等。 这时候,为了避免这样的问题,一般的处理方式是当某...

Spring Boot + Redis + MQ实现高并发点赞功能:项目实战

huangwenyi1010

 4750

开心一笑 【最后一次警告看我CSDN博客的人,你们都他妈给老子小心点,首先我不管你是什么身份,什么背景,混的有多牛逼,是不是老板,是不是社会人,这些我都不知道,我也都不在意,你们给我记住,都给我认真...

springMVC一个Controller处理所有用户请求的并发问题

u010523770

 2.5万

springMVC一个Controller处理所有用户请求的并发问题 有状态和无状态的对象基本概念:  有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非...

SpringBoot 并发编程学习历程(绝对的干货)

qq_41701956

 1327

如果一个项目总用单线程来跑,难免会遇到一些性能问题,所以再开发中,我们应该尽量适量的使用多线程(在保证线程安全的情况下)。本教程大概目录:模拟单线程情节用Callable实现 并发编程用Defered...

Spring-Boot中如何使用多线程处理任务

u010454030

 2.2万

看到这个标题,相信不少人会感到疑惑,回忆你们自己的场景会发现,在Spring的项目中很少有使用多线程处理任务的,没错,大多数时候我们都是使用Spring MVC开发的web项目,默认的Controll...

 

Springboot+rabbitmq如何实现高并发的rpc调用

CSDNOFZHC

 1966

        一.背景        公司项目的收单前置服务A与收单服务B之间是通过rabbitmq来通信的,而且A服务在给B服务发送信息后,必须收到返回结果(同步通知),于是使用了此方法:rabb...

Spring Boot同步架构与Vert.x异步架构高并发性能对比

u013615903

 3404

得益于Spring Boot的便捷性,使用JAVA语言开发REST服务变成了一件非常简单的工作,但于此同时我们也不得不面对一个问题,目前Spring MVC+Spring Boot+JPA或者Myba...

java大数据 高并发 系统框架 springmvc mybatis Bootstrap html5

jingdianss

 4561

获取【下载地址】     【免费支持更新】 A 代码生成器(开发利器);       增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本...

10-SpringBoot——Spring 高级话题-多线程

DERRANTCM

 8138

Spring 通过任务执行器( TaskExecutor )来实现多线程和并发编程。使用ThreadPoolTask-Executor 可实现一个基于线程泊的TaskExecutor。而实际开发中任务...

Spring 并发访问的线程安全性问题

hejingyuan6

 2.8万

首先对于Spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一...

 

springboot如何进行优化

maoyeqiu

 2870

这一部分分为三个部分,启动部分的优化,Tomcat参数设置和内存调优 启动部分的优化 这一小节来自 Spring Boot 性能优化  http://www.cnblogs.com/chen110...

Spring boot 项目内存管理

kenight

 1019

内存相关的运行参数 值为最低配置的参考 -Xms16m \ -Xmx48m \ -XX:MaxMetaspaceSize=64m \ -XX:CompressedClassSpaceSize=8m...

SpringBoot 定时任务踩坑记录

weixin_40582024

 438

springboot已经支持了定时任务Schedule模块,一般情况已经完全能够满足我们的实际需求。今天就记录一下我使用 schedule 时候踩的坑吧。 想要使用定时,我们首先要开启支持,其实...

maven聚合项目搭建,简单的SpringBoot集成

SongSir001

 417

1、new Maven project ,第一行 create a .... 打钩2、项目结构如下图,可以删除src,只保留pom3、右键该项目,new   project  选择maven mode...

IDEA创建基于springboot的多个module聚合项目,并生成war包

zhang_ming_xuan

 7748

背景:最近公司在做一个基于springboot的景区管理系统,项目前期将所有的功能都做到了一个项目里,现在客户需要把前台售票和后台管理分别部署到两个域名下,本人负责拆分项目,决定使用idea创建两个p...

 

Springboot+Maven多模块开发 (一)初始化工程(新建第一个web工程)

buyi_

 3万

Springboot+maven多模块开发笔记

小程序用SpringBoot搭建聚合工程

github_38313789

 43

先建 parent  pom工程 然后建 common  模块             pojo  模块  依赖 common             mapper 模块  依赖 pojo  ...

个人资料

仲浩

关注

原创

126

粉丝

220

喜欢

1

评论

2

等级:

 

访问:

 

2万+

积分:

 

239

排名:

 

36万+

 

最新文章

归档

展开

热门文章

最新评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值