zoukankan      html  css  js  c++  java
  • 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的内部类StoreMergedWebXmlListeneronStart方法:

    // 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/

  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/softidea/p/9724645.html
Copyright © 2011-2022 走看看