--轉載 http://blog.chinaunix.net/uid-25723371-id-5759072.html
目前我們在使用的基於JAVA的提供邏輯展現應用中間件有兩種,一種是以商用軟件WAS為代表的web應用中間件,另一種是以開源web應用中間件為代表的tomcat。為了更好的管理與使用這兩類中間件,所以拿出一部分時間去研究和分析這兩種中間件的共性與差異是十分必要且有價值的。只有我們真的對這兩種中間件有所認識與了解,才能夠實現物盡其用、有的放矢。衷心的希望我所做的一些基礎性的工作能夠對從事基於JAVA開發的人員帶來一些啟發。不管tomcat還是was在技術實現的技巧上還是在運行機制上都十分的博大精深,筆者在撰寫本當過程中力求嚴謹、正確,但鑒於筆者水平有限,難免文檔中所提出的觀點出現偏差,如有不當之處,請批評指正。整理本文檔的目的旨在分析比較Tomcat與WAS各自的特點及其適合的業務類型,為后續更好的使用、管理Tomcat、WAS應用中間件提供一些建議和參考。同時也希望該文檔的一些內容為從事基於tomcat、was開發與維護工作的同事提供一些有價值的信息,並將相關特性應用到相關工作之中去或者解決大家在使用tomcat或者was的過程中遇到的一些問題。
一、Tomcat與Was對標
1.實現架構比較
Tomcat與Was在實現架構上有着異曲同工之妙,tomcat是一個比較輕量級的web應用中間件,它的核心組件包含兩部分:Connector 和 Container,一個 Container 可以選擇對應多個 Connector。多個 Connector 和一個 Container 就形成了一個 Service。這與Was的設計思想相似,只是在術語上略有不同。tomcat與was都使用了模塊化思想進行設計與實現,在架構上都十分復雜,不過相對的比起來,tomcat在實現上還是比較輕量級,tomcat只是實現了處理web應用的部分功能,有很多企業級的應用都不支持,管理組件比較簡單,Was在各應用場景上的支持上十分完善且有針對不同場景的container,除此之外管理組件上也相對完善。
2.JDK的類型與版本比較
Tomcat使用了開源社區Sun的jdk,我們可以按照相應的tomcat版本的部署手冊選擇兼容的JDK版本即可。Was在開源社區jdk版本的基礎上進行了定制開發,在安裝Was時不需要考慮jdk的問題,因為Was已經將其定制化后的IBM軟件專用JDK打包到Was的安裝介質內。
3.JVM類型比較
Tomcat使用了HotSpot類型的JVM,Was使用了IBM 開發的J9 JVM虛擬機。Tomcat與Was在選擇不同的JDK作為自己的運行環境的同時,基本也就決定了后面選擇不同的虛機類型來實現各自的JAVA引擎。所以當我們在遇到JVM故障時,需要使用不同的診斷工具進行分析。這個地方是尤其需要注意的點。
4.支持功能比較
Tomcat是Apache基金會提供的Servlet容器,它支持JSP, Servlet和JDBC等J2EE關鍵技術,所以用戶可以用Tomcat開發基於數據庫,Servlet和JSP頁面的Web應用。但是,Tomcat卻不是EJB容器,也就是說,Tomcat不支持EJB。那么,使用EJB組件開發的Web應用程序就無法在Tomcat下面運行。眾所周知,EJB是分布式應用程序的核心技術,所以說凡是需要使用EJB來開發的應用就不能用Tomcat。這也是Tomcat與Was在功能上最主要的差別。雖然Was還有非常多的其他高級功能但遺憾的是很多公司拿着這些大玩意兒實際上干的也只是Tomcat的活。
5.性能比較
HotSpot使用了動態建模技術從運行應用中采樣數據,從而可以優化代碼,進而得到良好性能。它相當於以模仿人工的方法進行優化。在程序運行的開始,Java代碼仍然解釋執行,但HotSpot引擎開始進行采樣(Profiling)。HotSpot引擎可以集中精力來對HotSpot代碼進行深度優化,從而加速代碼執行的速度。由於Was采用了IBM的J9 VM虛擬機類型,由於閉源實現的原因所以關於Was的JVM內部的運行機制介紹方面的資料特別少,這里就不在贅述。按照IBM官方資料介紹其垃圾回收算法很突出,能保證應用程序在絕大多數情況下實時運行,停頓時間一般不超過3毫秒,其性能表現在業界是最好的JAVA虛擬機。但是從JVM發展歷史來看,理論上講性能最好的應該是HotSpot類型的虛擬機而非IBM的J9虛擬機。
因此筆者建議若使用IBM的軟件或者服務器時,可以考慮用J9,因為J9本身就是IBM基於自己的軟硬件系統專門進行優化設計的,性能上應該會有一定的提升,若使用開放平台還是力薦選擇HotSpot類型的虛機,因為這也是業界主流的做法。
從以上可以看出tomcat目前能夠覆蓋Was中間件80%以上的功能,也就是說Was能夠干的事情,Tomcat基本也都能干。只是tomcat在很多細節的地方做的還不夠細致,不像Was那樣像一件被精心打造的工藝品,即好用又耐看。但是Tomcat在靈活性上卻是Was做不到的,Was有商業支持,Tomcat免費,Was與Tomcat這兩款中間件是尺有所長寸有所短,用好了都能解決我們的問題。
通過查閱官方的大量資料發現不管是Tomcat還是Was在設計實現上都十分博大精深,如果真的細粒度的去分析二者之間的差別,恐怕一本書也寫不完。鑒於水平有限,我與於大師也只能蜻蜓點水、拋磚引玉了。如有不當之處,請批評指正。
二、調試與疑難排查
1.中文字符問題
a)HTML中文編碼轉換
若JSP文件中的靜態文字顯示亂碼, 則需要在之間增加中文設置代碼,
如下所示:
charset指定中文字符集,當然也可以指定其他的中文編碼,如GBK 等。
此外,修改MIME編碼也可以轉換中文字符,代碼如下所示。
htm
text/html;charset=gb2312
html
text/html;charset=gb2312
b)JSP中文編碼轉換
針對Tomcat下動態內容的中文亂碼問題,有以下幾個解決辦法:
(1)在每個JSP文件的開頭增加如下代碼:
<%@page language="java" contentType="text/html;charset=GBK"%>
(2)設置編碼參數:
request.setCharacterEncoding("gb2312");
(3)使用編碼過濾器,修改web.xml:
Set Character Encoding
SetCharacterEncodingFilter
Set Character Encoding
/*
建立類SetCharacterEncodingFilter.java:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
public class SetCharacterEncodingFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response,FilterChain chain)throws IOException,
ServletException {
request.setCharacterEncoding("GBK");
//傳遞控制到下一個過濾器
chain.doFilter(request, response);
}
}
(4)在web.xml中添加如下編碼配置:
gb2312
(5) 配置編碼過濾參數。為 server.xml中的 JspServlet 設置中文編碼, 添加如下參數:
javaEncoding
gb2312
同樣,也可以設置SSI、CGI文件的編碼參數。
(6)修改server.xml,在Connector 中加入 URIEncoding="gb2312",如
maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="gb2312" />
你還可以添加資源文件,實現國際化控制。
c)數據庫中文亂碼問題
如果是通過JDBC直接連接數據庫,配置的代碼如下所示。
jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK
如果是通過數據源連接,首先要寫在配置文件中,對於 MySQL 數據庫,Context 的
配置文件如下所示:
type="javax.sql.DataSource" />
factory
org.apache.commons.dbcp.BasicDataSourceFactory
driverClassName
com.mysql.jdbc.Driver
url
useUnicode=true&characterEncoding=GBK]]>
maxActive
100
maxIdle
30
maxWait
10000
username
root
WAS也會遇到同樣的問題,一般問題會出現jdbc或者數據庫層面,解決方法與Tomcat相同,在此不再贅述。
2.查詢超時問題
由於數據庫在應用中間件聯合使用的過程中,db更多的情況下只是作為資源池,進行被動的響應,根據應用中間件的指令進行下一步的動作,這就存在一個配合的問題,也就是當我們的應用在設置超時時間后結束了相關操作請求,卻沒有以約定的方式告訴數據庫結束相關操作,導致數據庫繼續執行本應該終止的操作,這個問題為應用帶來了兩方面的問題,第一、浪費了系統資源;第二、若是一個時間敏感性的應用,可能還會對業務造成負面的影響。對於這個問題WAS提供了一個很好的解決方案。
可以使用以下的方法設置查詢超時:
webSphereDefaultQueryTimeout 建立缺省查詢超時,此查詢超時為超時之前可執行 SQL 語句的秒數。如果 syncQueryTimeoutWithTransactionTimeout 定制屬性已啟用,那么會在 Java 事務 API (JTA) 事務期間覆蓋此缺省值。
syncQueryTimeoutWithTransactionTimeout 將 JTA 事務中的剩余時間用作 SQL 語句的缺省查詢超時。
缺省情況下,查詢超時處於禁用狀態。根據兩個數據源定制屬性的存在性和值,超時值計算為:基於事務管理器 (TM) 超時設置,當前 JTA 事務中的剩余時間syncQueryTimeoutWithTransactionTimeout
配置指定的絕對秒數 webSphereDefaultQueryTimeout然后,使用計算的超時對使用了配置的數據源的應用程序所執行的每個 SQL 語句設置查詢超時值。
配置步驟:
打開管理控制台;
轉到數據源的 WebSphere Application Server 數據源屬性面板
a.單擊資源 > JDBC > 數據源 > data_source
b.單擊 WebSphere Application Server 數據源屬性
單擊“其他屬性”下的定制屬性
單擊新建
在名稱字段中輸入 webSphereDefaultQueryTimeout
在值字段中輸入要用作缺省查詢超時的秒數。 超時值以秒計。值 0指示不會超時
單擊確定
單擊新建
在名稱字段中輸入 syncQueryTimeoutWithTransactionTimeout,在值字段中輸入 true 或 false, 值 true 指示將 JTA 事務中的剩余時間用作缺省查詢超時
單擊確定
保存更改,這些更新將在重新啟動服務器之后生效。
以上功能是是JDBC的API的一個標准的接口,Tomcat通過該接口也可以實現,但沒有Was實現起來如此的簡單,因為Was已經對該功能進行了封裝與集成。
三、診斷與調試方法
在使用 Tomcat進行應用開發的過程中,問題是難免的而且復雜多樣,這些沒有規律的錯誤就需要開發者和管理者有解決問題的方法。Tomcat 的日志文件都可以靈活配置,它們對於分析問題十分有幫助。在 server.xml中的每一個元素都有 debug 屬性,可以通過修改該屬性的值來決定是否輸出日志文件。如果為 0 則不輸出日志文件,你可以設置大於 0 的任何數值,越大則輸出越多的日志信息。有一些對象的日志級別可以到 9 甚至更高,但大部分的最大值為 3。 如果在使用 Tomcat的過程中出現了問題,就可以設置日志級別為 1 到 9之間,重啟Tomcat 來輸出日志文件。在 Tomcat 的 logs 目錄下通常包含幾個基本的日志文件,標准輸出stdout.log、錯誤輸出stderr.log,還有一些 access_log、error_log等代表各種對象信息的日志文件。在遇到問題時,只要打開了日志輸出,在這些文件中都可以找到更多的問題所在。 當然,日志輸出的同時伴隨着的是資源的占用,正常的情況下建議不打開那么多的日志輸出。
在遇到WAS相關的問題時,也有着類似功能和方法,但是其在故障診斷調試的靈活性和方法上卻不如Tomcat。但是慶幸的是我們有IBM廠商,來為我們進行診斷深層次的問題。