读书人

Resin3 JSP预编译兑现

发布时间: 2012-11-13 10:00:50 作者: rapoo

Resin3 JSP预编译实现

?

Resin3?JSP预编译实现

?

?

一、预编译需求

通过预先编译JSP,而不是在线上编译,节省了线上编译时间,降低系统上线初期超高的CPU使用率,以及用户请求等待事件

默认方式,Resin3提供了俩种预编译(http://www.caucho.com/resin-3.0/jsp/compile.xtp),但在实际使用的时候,无论哪种方法,都只能编译部分JSP,导致优化很不明显,据运维的说,还发生了log4j日志无法输出的情况(这个我也很莫名其妙,至今不知道原因)

二、预编译改善原理

幸好Resin是公开源码的,通过分析预编译代码,其默认编译方式是每64个jsp文件为一组,好处是这样编译速度快,但如果其中有一个jsp没有编译通过,则这64个文件都奖编译失败。在我们系统中,有很多子jsp,如果一些JSP不幸与这些子JSP分在一组,则编译不通过。

?

目前解决办法是每组JSP只包含一个jJSP文件。这样就能保证全部编译,但缺点是需要较长编译时间,在测试系统上大概需要1分钟才能编译好200多个JSP文件

?

代码如下:

package?com.javamonkey.common.util;

?

import?java.lang.reflect.Method;

?

import?com.caucho.java.JavacConfig;

?

public?class?ResinJSPCompileTask?{

?

/**

?*?@param?args

?*/

public?static?void?main(String[]?args)?throws?Exception?{

JavacConfig?config?=?JavacConfig.getLocalConfig();

if?(config?==?null)?{

config?=?new?JavacConfig();

}

config.setMaxBatch(1);

config.setArgs("-nowarn");

config.init();

//String?appDir?=?"D:\\workspace\\20111221_data\\resin\\webRoot";

//String?classDir?=?"D:\\workspace\\20111221_data\\resin\\webRoot\\WEB-INF\\work\\";

?

?String?appDir?=?args[0];

?String?classDir?=?args[1];

String?clsName?=?"com.caucho.jsp.JspCompiler";

Class?jsp?=?Class.forName(clsName);

Method?main?=?jsp.getMethod("main",?new?String[0].getClass());

main.invoke(null,?new?Object[]?{?new?String[]?{?"-app-dir",?appDir,

"-class-dir",?classDir?}?});

?

}

}

?

?

?

?

?

核心代码就是config.setMaxBatch(1);

另外?appDir?是web根目录,classDir?是jsp编译后的保存的目录,其实就是${appDir}/WEB-INF/work.

?

针对编译速度慢的情况,可以做如下调整

1?换到线上机器进行预编译,速度能提高

2?setMatBatch(2),能节约一半时间。但会有少数JSP(<?子JSP个数)无法预编译。

?

?

?

读书人网 >JavaScript

热点推荐