spring-boot 1.4.x遇到的cpu高的问题
如果你的spring-boot应用里tomcat线程耗cpu较高,并主要耗在做读取jar的操作上(堆栈类似下面),可能跟我们遇到同样的问题。
CRC32.update(byte[], int, int) line: 76
JarInputStream(ZipInputStream).read(byte[], int, int) line: 200
JarInputStream.read(byte[], int, int) line: 207
JarInputStream(ZipInputStream).closeEntry() line: 140
JarInputStream(ZipInputStream).getNextEntry() line: 118
JarInputStream.getNextEntry() line: 142
JarInputStream.getNextJarEntry() line: 179
JarWarResourceSet.getArchiveEntries(boolean) line: 112
JarWarResourceSet(AbstractArchiveResourceSet).getResource(String) line: 256
StandardRoot.getResourceInternal(String, boolean) line: 280
CachedResource.validateResource(boolean) line: 95
Cache.getResource(String, boolean) line: 69
StandardRoot.getResource(String, boolean, boolean) line: 215
StandardRoot.getResource(String) line: 205
Mapper.internalMapWrapper(Mapper$ContextVersion, CharChunk, MappingData) line: 1027
Mapper.internalMap(CharChunk, CharChunk, String, MappingData) line: 842
Mapper.map(MessageBytes, MessageBytes, String, MappingData) line: 698
CoyoteAdapter.postParseRequest(Request, Request, Response, Response) line: 672
CoyoteAdapter.service(Request, Response) line: 344
Http11Processor.service(SocketWrapperBase<?>) line: 784
Http11Processor(AbstractProcessorLight).process(SocketWrapperBase<?>, SocketEvent) line: 66
AbstractProtocol$ConnectionHandler<S>.process(SocketWrapperBase<S>, SocketEvent) line: 802
NioEndpoint$SocketProcessor.doRun() line: 1410
NioEndpoint$SocketProcessor(SocketProcessorBase<S>).run() line: 49
ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1142
ThreadPoolExecutor$Worker.run() line: 617
TaskThread$WrappingRunnable.run() line: 61
TaskThread(Thread).run() line: 745
这种情况只发生在 spring-boot 1.4.x版本(及1.3.x版本,更早的没有确认),1.5.x已经没有这个问题。
主要的改变在org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory的内部类StoreMergedWebXmlListener的onStart方法:
// TomcatEmbeddedContext 启动时触发了该监听器
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
}
// 注意最后这句,1.5.3版本已经去掉了这句,它导致变慢
TomcatResources.get(context).addClasspathResources();
}
在addClasspathResources方法里对于jar资源的处理,不同的tomcat版本方式有所不同,spring-boot 中如果使用嵌入式的 tomcat8 的话这些jar资源会记录到StandardRoot里的jarResources集合里,它们会被定时清理。
tomcat容器的后台线程(ContainerBackgroundProcessor)会触发StandardRoot里的清理逻辑
public void backgroundProcess() {
cache.backgroundProcess();
gc();
}
public void gc() {
for (List<WebResourceSet> list : allResources) {
for (WebResourceSet webResourceSet : list) {
webResourceSet.gc();
}
}
}
// JarWarResourceSet里的gc方法
public void gc() {
synchronized (archiveLock) {
if (archive != null && archiveUseCount == 0) {
try {
archive.close();
} catch (IOException e) {
// Log at least WARN
}
archive = null;
archiveEntries = null;
}
}
}
请求过来时,Mapper阶段会根据请求路径去找映射的资源,Cache不管命中还是未命中,都会对资源进行validate,在validateResource时要去遍历WebResourceRoot里所有的资源(包括所有的jar资源),若应用依赖的jar比较多时,会导致cpu较高。
spring-boot 1.5 版本里不会再将 BOOT-INF/lib 下的所有jar添加到tomcat的WebResourceRoot里,升级到1.5.3后这个情况没有再发生。
http://hongjiang.info/spring-boot-1-4-bug/
spring-boot 1.4.x遇到的cpu高的问题的更多相关文章
- Spring boot 1.3.5 RELEASE 官方文档中文翻译--Part2:新手入门
Part II. 新手入门 如果你刚刚开始学习Spring boot或"普通"的Spring,这部分非常适合你!在这里,我们回答了最基础的"什么是?".&quo ...
- spring boot 1.x完整学习指南(含各种常见问题servlet、web.xml、maven打包,spring mvc差别及解决方法)
spring boot 入门 关于版本的选择,spring boot 2.0开始依赖于 Spring Framework 5.1.0,而spring 5.x和之前的版本差距比较大,而且应该来说还没有广 ...
- 【转】Spring Boot干货系列:(一)优雅的入门篇
转自Spring Boot干货系列:(一)优雅的入门篇 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社区中热度一直很高,所以决定花时间来了解和学习,为自己做 ...
- Spring Boot干货系列:(一)优雅的入门篇
Spring Boot干货系列:(一)优雅的入门篇 2017-02-26 嘟嘟MD 嘟爷java超神学堂 前言 Spring一直是很火的一个开源框架,在过去的一段时间里,Spring Boot在社 ...
- 《Spring Boot官方指南》(二)入门
如果您刚开始接触Spring Boot,或者简称’Spring’, 这个部分对您来说非常有用.这个部分提供了“是什么?”,“怎么做?”和 “为什么?”的解释.您除了会阅读一份附带Spring Boot ...
- Spring boot参考指南
介绍 转载自:https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/details 带目录浏览地址:http://ww ...
- 【spring boot】SpringBoot初学(1) - Hello World
前言 此文只是记录自己简单学习spring boot的笔记.所以,文章很多只是初步理解,可能存在严重错误. 一.Spring boot的初步理解 1.spring boot的目标 (摘自:spring ...
- Spring Boot从入门到精通(八)日志管理实现和配置信息分析
Spring Boot对日志的处理,与平时我们处理日志的方式完全一致,它为Java Util Logging.Log4J2和Logback提供了默认配置.对于每种日志都预先配置使用控制台输出和可选的文 ...
- spring boot springMVC扩展配置 。WebMvcConfigurer ,WebMvcConfigurerAdapter
摘要: 在spring boot中 MVC这部分也有默认自动配置,也就是说我们不用做任何配置,那么也是OK的,这个配置类就是 WebMvcAutoConfiguration,但是也时候我们想设置自己的 ...
- 是时候为Spring Boot 3.0做准备了
2018年2月28日Spring Boot进入2.0时代,距今已经超过4年了. 2022 年 11 月 Spring Boot 3.0 将正式发布,它将基于 Spring Framework 6.0, ...
随机推荐
- 转载:解决CentOS7虚拟机无法上网并设置CentOS7虚拟机使用静态IP上网
最近在VMware虚拟机里玩Centos,装好后发现上不了网.经过一番艰辛的折腾,终于找到出解决问题的方法了.最终的效果是无论是ping内网IP还是ping外网ip,都能正常ping通.方法四步走: ...
- vs2015+opencv3.3.1 +Eigen 3.3.4 c++实现 薄膜插值 泊松图像编辑(v=0||Δf=0)
#include "core/core.hpp" #include "highgui/highgui.hpp" #include "imgproc/i ...
- 洛谷P4012 深海机器人问题(费用流)
传送门 图给的好坑……还得倒过来…… 用大佬的图做个示范 我们考虑左图吧 把每一个点向下连边,容量$1$,费用为给出的价值(表示一个机器人可以过去取得标本) 再连一条边,容量$inf$,费用$0$(表 ...
- 扩展jQuery---选中指定索引的文本
<script type="text/javascript"> //1.扩展jQuery $.fn.selectRange = function (start, end ...
- XAF实现交叉分析
如何实现如图的交叉分析? In this lesson, you will learn how to add the Analysis functionality to your applicatio ...
- feign调用过程注意事项
Feign是Netflix开发的声明式.模板化的HTTP客户端, Feign可以帮助我们更快捷.优雅地调用HTTP API. 在Spring Cloud中,使用Feign非常简单——创建一个接口,并在 ...
- MVC4设置伪静态---路由伪静态
有些客户要求设置静态的,为了完成需求,而且更简单的做法就是设置伪静态,例如:http://localhost:80/Home/Index.html ,也可以访问http://localhost:80/ ...
- linux 配置环境变量
配置全局 环境变量 查看环境变量 #这个变量赋值操作,只是临时生效,需要写入到文件,永久生效 echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/u ...
- BZOJ - 3757 树上莫队解决离线路径问题 & 学习心得
题意:给你一棵树,求u,v最短路径的XXX(本题是统计权值种类) 今天课上摸鱼学了一种有意思的处理路径方式(其实是链式块状树翻车了看别的),据说实际运行跑的比XX记者还快 大概就是像序列莫队那样 首先 ...
- SPOJ - DQUERY 莫队
题意:给定\(a[1...n]\),\(Q\)次询问,每次统计\([L,R]\)范围内有多少个不同的数字 xjb乱写就A了,莫队真好玩 #include<iostream> #includ ...