JSF访问速度问题原因跟踪分析过程
1、 现象
在项目中发现某一页面功能,每天到下午的时候,处理速度会慢很多,简单的无任何业务逻辑的处理操作需要4s左右,重启weblogic的appserver之后会恢复到1s以内。其他功能现象不明显。
2、 环境
a) 运行环境
Linux+Weblogic10+Oracle;Primefaces3+JSF2.1.11+Spring+Hibernate;
b) 页面编码状况
i. 大量ui:include,p:dialog组件。整个页面在JSF restore的时候需要解释的组件约1000个。
ii. 与其他功能模块的AM也有关联调用,整个结构很复杂
3、 分析过程
a) 耗时分析
通过PhaseListener对各个JSF各个生命周期的时间监控,发现主要的时间增长在Restore View和Render阶段
b) 可能原因排查
i. 页面结构复杂,可能存在不合理的写法和引用
通过清理页面,清除了一些没有用到的dialog,减少了页面的组件数,性能有一定改善,但是还是出现越来越慢的情况,说明此原因不是问题的根本原因,通过这一步之后,基本上判断出现此问题是在系统底层
ii. 内存泄露排查
1. 从变慢的现象来看,判断可能是系统在运行过程中在全局的上下文中积累了越来越多的数据,导致越来越慢
2. 引入了Jprofiler和Jmeter进行进行分析测试,发现ApplyToken持续增长,并且session过期后不会回收。跟踪发现是项目中javax.faces.FACELETS_REFRESH_PERIOD参数未设置,将此参数设置为-1后,ApplyToken未再增长,性能有一定提升,但是还会增长。
3. 其他主要用到的class在测试中正常。只有string和char有增长,因为这是最基础的对象,通过观察内存的方法,无法再继续。
iii. 具体facelets组件的处理时间分析
1. 前面2个方法结束之后,分析原因可能是某个facelet的handler的处理问题
2. 源代码分析,通过跟踪源代码,很难看出问题出现在什么地方
3. 将jsf的源代码导入到工程中,在几个主要handler加了时间统计,统计出来的结果是:NamespaceHandler、ComponentHandler、CompositeFaceletHandler、HtmlComponentHandler等主要Handler的时间都有增长。
4. 通过查看这些Handler的源代码,发现都是嵌套调用,所以这个时间统计无法计算出具体是哪一个或者那些Handler出现的问题。
iv. 控件排除
1. 前面几种方法的思路是想通过工具分析定位到问题点,从实施情况来看,无法定位到具体组件或者程序。只能一个一个控件来进行压力测试排除
2. 控件排除,通过编写最简单的页面,每个页面上放100个一样的控件。通过压力测试来测试是否出现越来越慢的问题。
3. 通过一段时间的测试,发现H和P的简单控件都没问题,include也没有问题,出现问题的是composite写的自定义控件。终于有了明确的问题点了。还是最土的办法最后让我们看到希望了。
v. 自定义控件的分析
1. 跟踪CompositeComponentTagHandler的源代码未发现问题
2. 还是使用删减法来测试,最后发现是控件中composite:attribute的default值引起的。去掉default值的定义后,响应速度不再随访问次数增加而增加。
3. 原因分析:查看了源代码,未发现具体原因。后续待查。
4、 最终解决方法
将所有自定义控件的xhtml文件里面的default定义都去掉,改用el表达式的empty来控制。
5、 总结
此问题前后调试2个星期,从方法论的角度来说,中间走了一些弯路,应该从一开始就建立简单测试页面进行测试,不要纠结在复杂的业务功能界面,深陷其中。
本文详述了一个JSF项目中页面响应速度在下午显著变慢的问题,经过逐层排查,从页面结构、内存泄露、Facelets组件处理时间、控件测试到自定义控件的深入分析,最终发现是composite组件中`composite:attribute`的default值导致内存占用增加,通过移除default并改用EL表达式解决。总结中提醒在遇到此类问题时应尽早建立简单测试页面进行测试,避免陷入复杂业务的迷雾。
1499

被折叠的 条评论
为什么被折叠?



