--转载 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厂商,来为我们进行诊断深层次的问题。

05-20 03:53