Birt Performance问题与解决
今天同事有个Birt的Performance问题需要解决,这个问题是在Birt里嵌入一段我们自己写的代码来调用一些已有的类去取得配置在文件中的数据库信息,这里因为数据库的用户名和密码是加密的,所以不能直接写在rptdesign文件中,而只能通过调用原来已有的类来取得数据库信息。而每次在调用这个类之后,都会导致Birt产生报表特别慢,并且CPU居高不下,而如果不调用这些类,同样的查询条件,同样的数据,同样的数据库都会很快的返回,用时相差25-30倍。
对于这个问题,首先想到的是由于birt是嵌入的JavaScript语句在rptdesign文件中,是不是Birt会重复加载我们使用的那些类?于是我们在那些类中加了一个静态域,并且加了一些log在静态域和构造函数中。但是结果是,静态域只被执行了一次,那就是没有重复加载那些类。这个想法不对。
然后想到由于每次都会特别消耗CPU,所以就用了JDK6自带的jvisualvm来profile,于是将环境转换到JDK6上,开始profile CPU信息,结果发现CPU耗时多的地方并不是birt和我们自己的类,而都是一些系统类,仅仅从这些信息看不出有什么特别,因此这个想法也被排除了。
最后,想到了是不是可以dump thread信息在CPU特别忙的时候,于是,我们dump了很多组数据,开始分析thread信息。这是我们发现在CPU特别忙的时候总是有一个线程(就是Tomcat中Birt产生报表的线程)很特别,这里特别是因为只有它有特别长的堆栈信息,一眼就可以看出,并且是和birt已经mozilla的javascript库相关。而且,这些组数据中,虽然最上边的堆栈并不是停留在同一个位置,但是在堆栈中部却都有一个mozilla的javascript的importPackage方法信息。于是找来rptdesign文件,发现在代码中果然有importPackage(Packages.x.y.z);看到这里就想是不是这里的importPackage有问题,于是就把这一句给删除了,然后在底下调用的时候全部使用类的全路径,一试,果然问题没有了。
但是原因却没有搞明白,等以后再慢慢找吧。
总结:感谢老天,我运气太好了,不小心搞定了。