Tomcat和Jetty作为Servlet引擎应用得比较广泛,虽然Jetty成长为一个优秀的Servlet引擎,但是目前Tomcat的地位仍然难以撼动。相比较来看,他们都有各自的优、缺点。
Tomcat经过尝试减的发展,已经广泛的被市场接受和认可,相比Jetty来说,Tomcat比较稳定和成熟,尤其在企业级应用方面,Tomcat仍然是第一选择。但是随着Jetty的发展,Jetty的市场份额也在不断提高,主要原因要归功于Jetty的很多优点,而这些优点也是因为Jetty在技术上的优势体现出来的。
架构比较
从架构上来说,显然Jetty比Tomcat更加简单。
Jetty的架构从前面的分析可知,他的所有组件都是基于Handler来实现的,当然他页支持JMX。但是主要的功能扩展都可以用Handler来实现。可以说Jetty是面向Handler的架构,就像Spring是面向Bean的架构,iBATIS是面向Statement的一样,而Tomcat是以多级容器构建起来的,他们的架构设计必然都有一个“元神”,所有以这个“元神”构建的其他组件都是肉身。
从设计模板角度来看,Handler的设计实际上就是一个责任链模式,接口类HandlerCollection可以帮助开发者构建一个链,而另一个接口类ScopeHandler可以帮助开发者控制这个链的访问顺序。另外一个用到的设计模板就是观察者模式,用这个设计模式控制了整个Jetty的生命周期,只要继承了LifeCycle接口,对象就可以交给Jetty来统一管理了。所以扩展Jetty非常简单,也很容易让人理解。整体架构上的简单也带来了无比的好处,Jetty可以很容易的被扩展和裁剪。
相比之下,Tomcat臃肿很多,Tomcat的整体设计很复杂,前面说了Tomcat的核心是他的容器的设计,从Server达到Service再到engine等container容器。作为一个应用服务器,这样设计无可厚非,容器的分层设计也是为了更好的扩展,但是这种扩展的方式将应用服务器的内部结构暴露给外部使用者,使得如果想扩展Tomcat,开发人员必须要首先了解Tomcat的整体设计结构,然后才能知道如何按照他的而规范来做扩展。这样就无形增加了对Tomcat的学习成本。不仅仅是容器,实际上Tomcat也有基于责任链的设计模式,像串联Pipeline的Value设计,也是与Jetty的Handler类似的方式,要自己实现一个Value与写一个Handler的难度不相上下。从表面上看,Tomcat的功能要比Jetty强大,因为Tomcat已经帮你做了很多工作,而Jetty只告诉你能怎么做,如何都由你去实现。
打个比方,就像小孩子学数学,Tomcat告诉你1+1=2、1+2=3、2+2=4这个结果,然后你可以根据这个方式得出1+1+2=4,你要计算其他数必须根据他给你的公式才能计算,而Jetty是告诉你加、减、乘、除的算法规则,然后你就可以根据这个规则自己做运算了。所以你一旦掌握了Jetty,Jetty将变得异常强大。
性能比较
单纯比较Tomcat与Jetty的性能意义不是很大,只能说在某种使用场景下他们表现得各有差异,因为他们面向的使用场景不尽相同。从架构上来看Tomcat在处理少数非常繁忙的连接上更有优势,也就是说连接生命周期如果短,Tomcat的总体性能更高。
而Jetty刚好相反,Jetty可以同时处理大量连接而且可以长时间博爱吃这些连接。例如,一些Web聊天应用非常适合用Jetty做服务器。淘宝的Web旺旺就用Jetty作为Servlet引擎。
由于Jetty的架构非常简单,作为服务器他可以按需加载组件,这样,不需要的组件就可以去掉,无形中可以减少服务器本身的内存开销,处理一次请求也可以减少产生的临时对象,这样性能也会提高。另外Jetty默认使用的是NIO技术,在处理I/O请求上更占优势,Tomcat默认使用的是BIO,在处理静态资源时,Tomcat的性能较差。
特性比较
作为一个标准的Servlet引擎,他们都支持标准的Servlet规范,还有Java EE的规范也都支持,由于Tomcat使用得更加广泛,他对这些支持得更加全面一些,有很多特性Tomcat都直接集成进来了。但是Jetty的应变更加快速,一方面是因为Jetty的开发社区更加活跃,另一方面也是因为Jetty的修改更加简单,他只要把相应的组件替换就好了。而Tomcat在整体结构上要复杂得多,修改功能比较缓慢,所以Tomcat对最新的Servlet规范的支持总是要比人们预期的晚。