1.1. BES中jsp請求主要執行流程
主要流程圖如下:
流程說明:
1.客戶端發送jsp請求;
2.服務端接受並解析jsp請求;
3.服務端檢查jsp是否已經訪問過;
4.服務端檢查是否需要編譯;若需要編譯,則編譯器將jsp編譯成servlet的java源碼並編譯成class;
5.服務端檢查是否需要加載jsp編譯的servlet;若需要加載,則新建JasperLoader,加載並初始化servlet。
6.服務端調用jsp編譯的servlet的service方法;生成響應內容
7.服務端將響應內容返回至客戶端。
1.2. BES中jsp編譯時機
相關配置
BES中JSP網頁由JspServlet處理,可以通過web.xml配置JspServlet。其中常用jsp編譯相關初始化參數如下:
參數 |
說明 |
development |
默認值爲true,即開發模式,表明jsp開發中,若更改了jsp,則根據modificationTestInterval參數檢查是否重編譯jsp。 若設置爲false,表示生產模式,可以設置checkInterval大於0,開啓後臺線程每隔checkInterval時間,根據modificationTestInterval參數檢查是否重編譯jsp。 |
checkInterval |
後臺單獨線程檢查生產模式下jsp是否需要被重新編譯的時間間隔,默認值爲0,單位爲秒。 若該參數設置大於0且development爲false時,開啓檢查線程並根據modificationTestInterval參數再次檢查是否重編譯jsp,否則不開啓檢查編譯線程。 |
modificationTestInterval |
默認值爲0,單位爲秒,即每次檢查是否編譯jsp時,直接對比jsp文件和jsp編譯的class的時間戳,若jsp文件時間戳大於編譯的class的時間戳,則重新編譯jsp。 若該參數設置大於0,則每隔該參數指定時間再對比jsp文件和jsp編譯的class的時間戳,若jsp文件時間戳大於編譯的class的時間戳,則重新編譯jsp。 |
生產模式配置:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>development</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> |
編譯時機
編譯方式 |
編譯時機 |
後臺單獨線程編譯 |
前置條件:JspServlet配置爲生產模式(development爲false), checkInterval大於0。 編譯時機:請求處理線程找到jsp文件後,編譯成servlet,在初始化servlet時,啓動後臺編譯線程。然後,每隔checkInterval時間再檢查是否重新編譯jsp。 檢查方法: 每隔modificationTestInterval(大於0)時間對比jsp文件和jsp編譯的class的時間戳,若jsp文件時間戳大於編譯的class的時間戳,則重新編譯jsp。否則,每次檢查都對比。若對比以前編譯的jsp時間戳時,發現jsp編譯文件不存在,即時間戳爲0,則會重新編譯jsp。 |
部署加載應用線程編譯 |
前置條件:部署應用時開啓JSP預編譯。 編譯時機:應用部署時,部署加載線程編譯應用中所有jsp。應用訪問時,不再編譯jsp。即使重啓應用且jsp編譯文件不存在,請求處理線程也不會再編譯jsp文件。 |
請求處理線程編譯 |
前置條件:JspServlet配置爲生產模式。 編譯時機:部署應用後,第一次訪問jsp時,請求處理線程找到jsp文件後,將jsp編譯成servlet;以後每次訪問,請求處理線程不再重編譯jsp,直到重啓應用後,第一次訪問jsp,請求處理線程檢查是否重新編譯jsp, 以後訪問不再重新編譯。 檢查方法: 對比jsp文件和jsp編譯的class的時間戳,若jsp文件時間戳大於編譯的class的時間戳,則重新編譯jsp。否則,每次檢查都對比。若對比以前編譯的jsp時間戳時,發現jsp編譯文件不存在,即時間戳爲0,則會重新編譯jsp。 |
前置條件:JspServlet配置爲開發模式(development爲true)。 編譯時機:部署應用後,第一次訪問jsp時,請求處理線程找到jsp文件後,將jsp編譯成servlet;以後每次訪問jsp時,請求處理線程根據modificationTestInterval檢查是否重新編譯jsp。 檢查方法: 每隔modificationTestInterval(大於0)時間對比jsp文件和jsp編譯的class的時間戳,若jsp文件時間戳大於編譯的class的時間戳,則重新編譯jsp。否則,每次檢查都對比。若對比以前編譯的jsp時間戳時,發現jsp編譯文件不存在,即時間戳爲0,則會重新編譯jsp。 |
編譯器
由於BES存在JDTJavaCompiler和Jsr199JavaCompiler兩種編譯器,JDTJavaCompiler編譯jsp後,會把編譯生成的java和class文件放在實例的tmp中;而Jsr199JavaCompiler編譯jsp後,會把編譯生成的java和class放在BES定義的內存對象或數組中。
編譯器 |
說明 |
|
JDTJavaCompiler |
jdk1.5運行環境中,默認使用JDT編譯器,該編譯器將編譯的java和class文件存入實例tmp目錄。 |
|
Jsr199JavaCompiler |
jdk1.6以上運行環境,默認使用JSR199編譯器,該編譯器是基於jdk1.6運行時編譯新特性實現的,即將編譯後的jsp存放在內存對象或數組中,並可以通過配置將編譯的java和class存入實例的tmp目錄。 BES8.1.1默認不在tmp中生成java和class文件。而BES8.2默認生成。 生成上述文件的配置方法: 通過bes-web.xml中的keepgenerated控制是否爲jsp生成java文件,saveBytecode控制是否爲jsp生產class文件。
|
jdk1.6及以上運行環境,常有兼容tomcat的JDTJavaCompiler編譯器,將BES的Jsr199JavaCompiler改爲JDTJavaCompiler。
修改方法: BES8.2打上039補丁,然後修改DMS的web.xml如下:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>compiler</param-name> <param-value>JDTJavaCompiler</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> |
最後,重啓實例,若客戶應用是文件部署,則還需重新部署應用。
1.3. BES中jsp加載時機
加載時機 |
說明 |
編譯後,加載jsp的class |
第一次編譯或重新編譯後,第一次訪問jsp,此時會新建JasperLoader加載或重新加載jsp的新class。 |
重啓應用,加載jsp的class |
重啓應用,會新建JasperLoader加載jsp的class。 |
當訪問應用的jsp時,若需要加載jsp的class,則JasperLoader優先從內存數組中查找jsp的class,若存在,則加載內存數組中的class到jvm;若不存在,再查找實例tmp中編譯的jsp的class,若在tmp中找到該文件,則加載該class到jvm中。
注:JasperLoader加載jsp到jvm,是指將編譯後的jsp字節碼存入方法區(也稱永久代)
性能測試時,開啓jsp預編譯,一般可以減少編譯加載jsp的次數,相對於非預編譯,可以提高一定的性能。而應用在生產環境中,也該將jsp修改爲生產模式,這樣相對於開發模式,可以減少編譯加載jsp的次數,提高一定的性能。