欢迎来到“管理角”这个版,新一期de月刊专栏专注于 WebLogic 服务器de管理、配置、处理和开发方面.
开辟这个专栏de目de是为了向大家介绍在使用WebLogic Sever时,能普遍用到de非J2EE开发方面de问题.开发者和管理者同样会发现这个专栏非常有价值,因为这些文章既适用于开发又适用于最终产品de应用.此外,它很大程度上利用了来自于该领域和工程实验室de经验,它提供了对实际问题de详细解答.
JSP预编译de必要性
本月de文章着眼于移除潜在de系统性能瓶颈,它通过解决一个最普通de问题――在服务器运行时间中deJSP (JavaServer Page)编译de系统开销问题,这个问题困扰着几乎所有deJ2EE发展计划.虽然JSP是在J2EE应用范围内呈现动态HTML视图de理想选择,但在某种程度上它们会影响性能,这比错误de更令人讨厌,给人de第一感觉是该程序很慢.
根据J2EE规范,JSP主要是HTML文件,在它里面包含着Java相关代码用来和其他de系统组件进行交互以及动态de显示信息.规范规定所有deJ2EE编译应用服务器应当支持JSP,客户请求一个特定deJSP,将:
● 转换JSP从HTML格式成为servlet类型deJava类(Java源格式),用简写deJSP符号代替完全符合规定deJava语法
● 将新产生deJava源文件编译成.class字节码形式
● 在新编译de类上执行适当de接口方法并且对客户端请求返回响应.
虽然从发展de观点来看对于在表示层内管理动态HTMLde产生这是最好de途径,但它影响到服务器de运行时间环境,要求JSP被解析、转变成Java相关代码,并且在它去处理一个特定de客户端请求之前被编译.对最终用户明显de影响是,一个响应将会被延迟知道给定deJSP文件被编译通过.考虑到一个特定de用户请求可能用到两个或多个JSP文件,因此编译状态必需de时间增加了很多倍.
对第一个请求一个特定deJSP页面并且迫使被请求de文件进行初始编译de终端用户,会感觉应用程序很慢并且没有响应. 虽然这样de感觉可能存在,但是对于特定deJSP文件de编译过程通常在给定de应用服务器虚拟机实例de生命周期中完成一次. 因此,它对性能总体上de影响被考虑成一种障碍,而不是对应用程序总响应时间de一个严重de障碍.然而,在生产环境中为了传送基于JSPdeJ2EE应用程序de生产系统,必须克服JSPde缺陷并且对最终用户进行透明de编译.
这样,生产环境如何能受益于JSP文件,还要避免运行时编译de性能打击?答案是简单de:执行一个一般作为JSP预编译de过程. 借用JSP预编译,已经被预编译de在脱机环境中deJSP文件和他们de编译结果被部署在生产环境中.如果结果类文件de预编译和部署正确de完成,应用程序服务器将会为JSP文件运行先前de编译类,并且在运行中将不强制对特定de请求进行再编译. 这样产生了一种情况,应用程序de操作避免了多余de编译开销,允许系统管理员移除对系统总性能会造成影响de一个已知de瓶颈.
不同de方法论和途径
没有人怀疑JSP预编译de承诺听起来令人兴奋. 然而,为了要实现这样de承诺,您必须首先了解能够执行这个技术de不同途径,以及它们各自优点和缺点.
运行应用程序进行强制预编译
用于实现JSP预编译最显而易见de方法是在产品发布前,通过请求在应用程序中de所有可能deJSP页面,因此编译在终端用户访问站点前完成.它既可以通过第一次人工浏览整个站点时完成也可以通过从测试系列应用程序或其他脚本语言de客户端(例如LoadRunner 或 SilkPerformer)发动自动请求来实现. 当使用这种方法(可能是所有deJSP预编译方法中de最简单de而又较下策de一个方法)时,他de缺点很快就显现出来了.也许最大de缺点是很难实现跨集群环境,在集群环境中,用该方法对于单一节点de实例发送de请求依集群中de节点数量成倍de增加.而且,当这个集群是由一个或更多deWeb服务器或硬件负载权衡者来代理时,更难保证在一个集群de环境中每个服务器实例都进行JSP预编译,因为一般没有方法来搞清代理最初把请求转到哪个应用服务器.此外,在应用服务器每次重启时,这个方法必须执行,当站点很小时,不能一次实现所有de编译就会很痛苦.因此,我不推荐这种JSP预编译de方法.
使用编译工具来实现预编译
因为人工执行一个站点应用程序来强制JSP预编译在真实de产品环境中是一个较大de缺点,在预编译运行期间选择编译JSP,使其变成为servlets变得更令人心动.幸运地,WLS提供了二个方法.第一种方法在服务器启动部署一个特定deWeb应用程序de时候执行预编译(declarative预编译),第二种方法是命令行Java工具(weblogic.jspc)允许过程在完全脱机de情况下处理(程序方式de预编译).两种方法都有它们de优点,程序方式de预编译在两者中有更灵活de选项,并且提供更让人无法抗拒de理由来使用它.
DECLARATIVE预编译
对于在WLS下公布de预编译,一个特定deWeb应用程序(独立de或者作为EARde一部分)能够被配置,因此所有deJSP在应用程序部署(服务器启动时)和重新部署(运行时)期间里被预编译.对WEB-INF/ weblogic.xml部署描述符要做必要de配置变化,使用预编译<jsp-param/>指令,如下:
<weblogic-web-app>
…
<jsp-descriptor>
<jsp-param>
<param-name>precompile</param-name>
<param-value>true</param-value>
</jsp-param>
</jsp-descriptor>
…
</weblogic-web-app>
在一个特定deWeb应用程序上进行部署(或重新部署),如果上述de参数被设定成真, WLS 将会在WAR内尝试预编译所有deJSP文件,在程序中从 Web 应用程序de根目录下循环de运行它de方法( 略过Web-INF) .以. jsp 或 .JSP为扩展名de文件都变成了编译de对象. 被编译后de文件被以适当de包目录结构形式被放置在Web 应用程序de临时工作目录下面(默认在Web-INF子目录中,除非在 weblogic.xml 里有特别说明).
这个方法是到目前为止进行JSP预编译最方便de途径(“flick-a-switch” 途径),他有许多指出来毫无意义de缺点.如果一个错误在JSPde编译期间或在部署(或重新部署) de时候发生,Web 应用程序de预编译将会在例外处暂停.另外,如果在一个特定deWeb应用程序里面有许多JSP文件de情况,declarative预编译显著de影响着部署时间,阻断部署直到所有de文件都被编译.对于大型de应用程序,当出现数以百计deJSP 文件以declarative预编译被执行de时候,这种部署时间趋向以分钟来计算 (在某些情况10到15分钟,其他情况可能更长时间).设想开始一个服务器实例,在一个特定deWeb应用程序周期内进入部署状态用declarative 预编译激活.如果在应用内有很多deJSP文件以及部署,接近完成时就已经花费了大量de时间,在编译期间由于抛出一个例外而突然失败,当然会引起挫折感.虽然起先看起来比较方便,但declarative 编译对生产系统管理造成重大de风险,因此应该在经过慎重de考虑后再使用它.
程序方式de预编译
在WLS下最可靠de预编译JSPde方法是使用Java命令行,weblogic.jspc,它位于WLS安装delib目录之下deweblogic.jar文件中.这个工具允许开发者在发展阶段和在部署前解决编译时间问题de时候编译需要deJSP文件.它也为生产系统提供一个有能力实现JSP预编译de管理员.这种用法de主要好处是:
● 文件可以被预编译一次然后可以被多次部署.(这不被服务器实例de重复利用所影响)
● 编译时de例外可以被预先解决而不影响部署.
● 类可以通过集群部署.
使用weblogic.jspcde缺点是需要人工干涉,并且它在开发时并当在JSP文件变得过时de时候必须被重新运行.然而,考虑到前面de两个方法de讨论,我几乎不能将这种不方便当成该方法de一个缺点,因此推荐它作为最可靠和最灵活de机制来实现JSP预编译.
执行weblogic.jspc
为了更有效de使用weblogic.jspc,您必须首先了解它de用法和语法.这篇文章我将利用WLS6.1 SP2de工具de功能.注意:下面给出de语法和最好de惯例应该应用于WLS 6.1de所有版本以及新deWLS 7.0.
为了调用命令行JSP编译器(weblogic.jspc),您必须确定下面de内容:
● PATH环境变量必须包含您机器上安装deJ2SE1.3包de二进制目录(例如,/opt/j2se/1.3.1/sdk/bin 或者c:\sunsoft\j2se\1.3.1\sdk\bin),以获得JVM运行时de支持.如果您打算使用javac作为您deJSP编译deJava编译器,要确定PATH包含全部Java 1.3 de软件开发工具包(SDK)de二进制目录,并且不仅仅是JRE(Java Runtime Engine,Java运行时间引擎),因为没有编译器和JRE关联. 如果您打算使用一个编译器而不是javac(例如 Jikes),也要为那个编译器确定在PATH中包含正确de目录.
● 设置Java系统类路径用来包含来自WLS 6.1 SP2 安装目录deweblogic.jar文件,通过在产品库目录下默认建立(例如,/opt/bea/wlserver6.1/lib/weblogic.jar或者c:\bea\wlserv -er6.1\lib\weblogic.jar).此外,请确定在JSP编译阶段中您可能需要de参考类(JAR或类文件)也在您de类路径中.
在第一次执行weblogic.jspc之前,您需要测试您de命令行配置是否是按上述配置.它可以通过简单运行一个WLS版本检查来完成,使用命令“java weblogic.version”,这个命令应该返回下面de内容:
which should return the following:
WebLogic Server 6.1 SP2 12/18/2001 11:13:46
#154529
WebLogic XML Module 6.1 SP2 12/18/2001
11:28:02 #154529
如果您de输出和上面de不相似(和您运行de版本相对应),在进行JSP预编译前,要重新访问PATH和类路径变量将其设置成您de当前命令行环境.
一般deweblogic.jspcde语法如下面给出de:
java weblogic.jspc [options] <jsp files>…
在一个编译器de单一调用中默认情况下JSP编译器可以编译一个JSP文件或一组JSP文件,并且可以通过设置命令行选项,编译器可以以不同de方法工作.下面给出一个例子:
java
weblogic.jspc
-webapp mywebapp
-compiler javac
-compileFlags “-g”
-classpath /u/apps/dist/src/lib.jar
-d .
-package com.slackwerks.mywebapp.jsp
-commentary
-keepgenerated
-k
mywebapp\index.jsp
这篇文章只列举了一个例子,如果您要想更加了解weblogic.jspc如何能在您de环境中使用和管理de话,请参阅www.slackwerks.com/wldj,我提供了对整套de工作选项,使用de含义以及相关联问题de讨论.
结论
虽然关于JSP预编译de问题较多,但许多de途径可以解决.然而,考虑到上文所说de那些优点和缺点,应该较容易de看出经由weblogic.jspc预编译de程序方式是为克服JSP固有de缺点de一个灵活de选项.在开发阶段de早期,熟悉该工具将改善生产期间应用程序de管理和性能状况.