调优系列:高并发环境下,解决xml解析过慢的方法

场景

多线程环境下,启动了线程池,包含30个线程进行数据清洗。其中涉及xml文件的解析。即使机器配置十分不错,但是启动多个线程进行清洗,速度依旧跟不上。本篇博客主要是讲述该情况的原因及解决方法。

环境

软件版本
JDK1,8
centos7

正文

一、环境准备

博主这里是使用阿里巴巴开源的arthas工具进行问题的跟踪。如果有兴趣了解的小伙伴请自行百度搜索。

二、启动项目和arthas工具

启动项目,等开始运行之后,使用命令ps -ef|grep clean获取进程编号,然后使用arthas工具绑定对应的进程号。具体操作可以点击 https://arthas.aliyun.com/doc/quick-start.html 进行查看。

三、查看进程情况

一般像这种启动了多个线程,但是速度跟不上的情况,很大程度是因为锁的问题。我们这里使用arthas提供的thread命令,查看进程情况。结果如下:
在这里插入图片描述
从上图可以了解到,有30个线程的情况下,有21个线程被阻塞等待其他操作的完成。我们可以看到里面是关于dom4j的操作导致阻塞的。这个时候,就得去研究一下源码,看看是什么原因导致线程阻塞的。

四、源码剖析

给大家截图一下,我们这里使用的业务代码,如下:
在这里插入图片描述
我们这里主要使用了DocumentHelper.parseText进行文本解析。单步进去查看源码,我们可以根据第三步的截图来锁定具体的位置,如下图:
在这里插入图片描述
这个时候,要进去查看一下,如下图:
在这里插入图片描述
这里要记录一下,这里主要是为了搜索SAXParserFactory的实现类,其中第二个参数为搜索不到之后的默认参数。这里先mark一下,是后面的重点。下图是该方法的注释:
在这里插入图片描述
我们再进去find方法,这里就是主要的问题难点了。有兴趣的同学可以自己查看源码,源码路径为:javax.xml.parsers.FactoryFinder#find。我这里大概总结一下这个方法的步骤:

  1. 查找环境变量中是否配置了javax.xml.parsers.SAXParserFactory,如果有配置,则取配置值并返回;
    在这里插入图片描述

  2. 尝试从 $java.home/lib/jaxp.properties 查找配置,如果可以找到,则取配置中的javax.xml.parsers.SAXParserFactory并返回;
    在这里插入图片描述

  3. 尝试通过读取jar包来获取服务。
    在这里插入图片描述

我们从第三步的截图可以了解到,这里是走入第三种情况,所以去搜索jar包里面是否存在对应的服务。是不是有一种恍然大悟的感觉?!!
在这里插入图片描述

博主在本地单步调试过,最后是jar包搜索不到,直接返回默认值了。所以,这个时候,我们可以直接在启动脚本设置环境变量javax.xml.parsers.SAXParserFactory,减少反复搜索的时间消耗。设置如下:

-Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"

五、结果

添加参数之后,重新启动,速度果然有了比较大的提升。未添加参数之后,清洗效率为:
在这里插入图片描述
添加参数之后,清洗效率为:
在这里插入图片描述
耗时为原本耗时的十分之一!!!

在这里插入图片描述

总结

工作中会遇到很多问题,多总结,多思考,多输出,日积月累,总会变成一个大神!!!

随缘求赞

如果我的文章对大家产生了帮忙,可以在文章底部点个赞或者收藏;
如果有好的讨论,可以留言;
如果想继续查看我以后的文章,可以点击关注
可以扫描以下二维码,关注我的公众号:枫夜之求索阁,查看我最新的分享!
在这里插入图片描述
拜拜

posted on 2022-11-29 18:39  枫夜求索阁  阅读(269)  评论(0)    收藏  举报

导航