JSP預編譯的必要性
本文著眼於移除潛在的系統性能瓶頸,它通過解決一個最普通的問題??在服務器運行時間中的JSP (JavaServer Page)編譯的系統開銷問題,這個問題困擾著幾乎所有的J2EE發展計劃。雖然JSP是在J2EE應用范圍內呈現動態HTML視圖的理想選擇,但在某種程度上它們會影響性能,這比錯誤的更令人討厭,給人的第一感覺是該程序很慢。
根據J2EE規范,JSP主要是HTML文件,在它裡面包含著Java代碼用來和其他的系統組件進行交互以及動態的顯示信息。規范規定所有的J2EE編譯應用服務器應當支持JSP,客戶請求一個特定的JSP,將:
轉換JSP從HTML格式成為servlet類型的Java類(Java源格式),用簡寫的JSP符號代替完全符合規定的Java語法
將新產生的Java源文件編譯成.class字節碼形式
在新編譯的類上執行適當的接口方法並且對客戶端請求返回響應。
雖然從發展的觀點來看對於在表示層內管理動態HTML的產生這是最好的途徑,但它影響到服務器的運行時間環境,要求JSP被解析、轉變成Java代碼,並且在它去處理一個特定的客戶端請求之前被編譯。對最終用戶明顯的影響是,一個響應將會被延遲知道給定的JSP文件被編譯通過。考慮到一個特定的用戶請求可能用到兩個或多個JSP文件,因此編譯狀態必需的時間增加了很多倍。
對第一個請求一個特定的JSP頁面並且迫使被請求的文件進行初始編譯的終端用戶,會感覺應用程序很慢並且沒有響應。 雖然這樣的感覺可能存在,但是對於特定的JSP文件的編譯過程通常在給定的應用服務器虛擬機實例的生命周期中完成一次。 因此,它對性能總體上的影響被考慮成一種障礙,而不是對應用程序總響應時間的一個嚴重的障礙。然而,在生產環境中為了傳送基於JSP的J2EE應用程序的生產系統,必須克服JSP的缺陷並且對最終用戶進行透明的編譯。
這樣,生產環境如何能受益於JSP文件,還要避免運行時編譯的性能打擊?答案是簡單的:執行一個一般作為JSP預編譯的過程。 借用JSP預編譯,已經被預編譯的在脫機環境中的JSP文件和他們的編譯結果被部署在生產環境中。如果結果類文件的預編譯和部署正確的完成,應用程序服務器將會為JSP文件運行先前的編譯類,並且在運行中將不強制對特定的請求進行再編譯。 這樣產生了一種情況,應用程序的操作避免了多余的編譯開銷,允許系統管理員移除對系統總性能會造成影響的一個已知的瓶頸。
不同的方法論和途徑
沒有人懷疑JSP預編譯的承諾聽起來令人興奮。 然而,為了要實現這樣的承諾,你必須首先了解能夠執行這個技術的不同途徑,以及它們各自優點和缺點。
運行應用程序進行強制預編譯
用於實現JSP預編譯最顯而易見的方法是在產品發布前,通過請求在應用程序中的所有可能的JSP頁面,因此編譯在終端用戶訪問站點前完成。它既可以通過第一次人工浏覽整個站點時完成也可以通過從測試系列應用程序或其他腳本語言的客戶端(例如LoadRunner 或 SilkPerformer)發動自動請求來實現。 當使用這種方法(可能是所有的JSP預編譯方法中的最簡單的而又較下策的一個方法)時,他的缺點很快就顯現出來了。也許最大的缺點是很難實現跨集群環境,在集群環境中,用該方法對於單一節點的實例發送的請求依集群中的節點數量成倍的增加。而且,當這個集群是由一個或更多的Web服務器或硬件負載權衡者來代理時,更難保證在一個集群的環境中每個服務器實例都進行JSP預編譯,因為一般沒有方法來搞清代理最初把請求轉到哪個應用服務器。此外,在應用服務器每次重啟時,這個方法必須執行,當站點很小時,不能一次實現所有的編譯就會很痛苦。因此,我們不推薦這種JSP預編譯的方法。
使用編譯工具來實現預編譯
因為人工執行一個站點應用程序來強制JSP預編譯在真實的產品環境中是一個較大的缺點,在預編譯運行期間選擇編譯JSP,使其變成為servlets變得更令人心動。幸運地,WLS提供了二個方法。第一種方法在服務器啟動部署一個特定的Web應用程序的時候執行預編譯(declarative預編譯),第二種方法是命令行Java工具(weblogic.jspc)允許過程在完全脫機的情況下處理(程序方式的預編譯)。兩種方法都有它們的優點,程序方式的預編譯在兩者中有更靈活的選項,並且提供更讓人無法抗拒的理由來使用它。