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, ...
随机推荐
- Day 3 Python 基础数据类型二
1. INT 型 #1. 数字int #bit_length() 当十进制用二进制表示时,最少使用的位数. v =11 data = v.bit_length() print(data) 2. 布尔值 ...
- lfs原理
- day7学python 初识简单模板
初识简单模板 模块与包 1.模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现功能),本质是.py结尾的文件 但导入的模块名,无.py 2.包:从逻辑上组织模块,本质就是目录(含有_i ...
- php代码审计1(php.ini配置)
1.php.ini基本配置-语法 大小写敏感directive = value(指令=值)foo=bar 不等于 FOO=bar 运算符| & - ! 空值的表达方法foo = ;fo ...
- 洛谷P2566 [SCOI2009]围豆豆(状压dp+计算几何)
题面 传送门 题解 首先要解决一个问题,就是怎么判断一个点是否在多边形内部 从这个点向某一个方向做一条射线,如果这条射线和多边形的交点为奇数说明在多边形内,否则在多边形外 然而有一些特殊情况,比方说一 ...
- Python3之shutil模块
一. 简介 shutil 是高级的文件,文件夹,压缩包处理模块. 二. 使用 shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中 import ...
- [APIO2009]抢掠计划 tarjan缩点+spfa BZOJ1179
题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri 的酒吧也都设 ...
- [HEOI2012]采花 树状数组 BZOJ 2743
题目描述 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于 ...
- 【转】intellij idea使用指南—— 导入Eclipse的Web项目
通常一个团队中可能有人用eclipse,有人用intelliJ,那么经常会出现需要导入别人用eclipse建好的web项目.而IntelliJ提供了多种项目类型的导入方式,其中就有eclipse. 在 ...
- matlab中的linkage和cluster函数
Linkage: Agglomerative hierarchical cluster tree(凝聚成层次聚类树) 语法: 解释: Z=linkage(x),返回Z,是一个X矩阵中行的分层聚类树(用 ...