高并发环境下,如何解决xml解析过慢的问题?

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

环境:
软件 版本
JDK 1,8
centos 7


一、环境准备
博主这里是使用阿里巴巴开源的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。我这里大概总结一下这个方法的步骤:

查找环境变量中是否配置了javax.xml.parsers.SAXParserFactory,如果有配置,则取配置值并返回;


尝试从 $java.home/lib/jaxp.properties 查找配置,如果可以找到,则取配置中的javax.xml.parsers.SAXParserFactory并返回;


尝试通过读取jar包来获取服务。


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


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

-Djavax.xml.parsers.SAXParserFactory="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
1
五、结果
添加参数之后,重新启动,速度果然有了比较大的提升。未添加参数之后,清洗效率为:

添加参数之后,清洗效率为:

耗时为原本耗时的十分之一!!!

posted @ 2021-07-06 14:10  _猿人崛起  阅读(478)  评论(0)    收藏  举报