引言 java
Jetty相较于Tomcat更加轻便,虽然架构更加简单,可是看起来可并不轻松。Spring是设计初衷是用来管理应用中的实例Bean,于是是基于Bean的架构;Jetty则更倾向于流程和组件的管理,采用了基于handler的架构。handler的嵌套和链式结构,LifeCycle和doStart、doHandler模式无不印证了这点。 web
本文主要从基本架构、LifeCycle结构、Handler体系结构、Jetty启动过程、接受并处理请求的流程和与Tomcat的比较来简要介绍下Jetty,细节部分后面的博文会有分析。 设计模式
Jetty的基本架构 服务器
前面的博文谈及应用服务期的架构已经说过了几个基本模块的概念,connection、Threadpool等~拷贝了许令波画的图(文中关于基本架构的描述挺详细的,参考了其目录结构哈~不过对于有些知识点有本身的见解,所以总结该文): session
该博文中谈到“Jetty 中还有一些无关紧要的组件,咱们能够在它上作扩展。如 JMX,咱们能够定义一些 Mbean 把它加到 Server 中,当 Server 启动的时候,这些 Bean 就会一块儿工做。”个人理解是,Jetty中的JMX是提供给server的Container,使得注册到server的Handler同时注册到JMX上,以便于运行时的监控和管理,应该是先有server再有JMX,而不是反过来的。 架构
LifeCycle体系结构 app
Jetty是基于Handler的架构模式,对于组件化的概念很容易理解,那Jetty又是如何管理流程和Handler的生命周期的呢,这就须要从下节的Handler的体系架构来解释,本节主要分析LifeCycle。 webapp
写文档最讨厌的就是画图,无奈有些图无法copy~ 组件化
上图包含四层涵义: 性能
一、每一个Handler都是一个LifeCycle
二、AggregateLifeCycle正如起名,汇集在一块儿的生命周期。Jetty把Handler生命周期所关联的一些subHandler注册在Hahdler上,eg:server->deployManager正是如此。
三、监听器的概念就是一个观察者模式的应用,触发于Handler的doStart,doStop,doFail等事件。
四、Jetty的LifeCycle结构主要影响Jetty的初始化,而Handler结构影响Jetty的处理功能。
Handler体系结构
既然Jetty是基于Handler的架构,那么Handler体系关乎着Jetty的方方面面:
上图有几层涵义:
一、红色的server即Jetty的核心Handler,它依赖的几个类虽然不是Handler,也在图中标出以方便理解,server须要Deploy部署,须要Connector,天然须要inner Handler,这里的红色的虚线是默认的依赖关系,嵌入式的Jetty或自定义状况下是能够变的,好比换成ResourceHandler,WebAppContext等~
二、AbatractHandlerContainer提供对嵌套Handler获取Childs的方法支持,所以位于很顶层。
三、ContextHandlerCollection不一样于普通的HandlerCollection的区别在于,提供了对于Context的支持,即依据生产的app创建app与name的映射关系并对于url请求依据该映射关系分发到指定的app中。
四、HandlerWrapper仅仅提供了简单的对于Wapper的handler等操做,其实handler操做并非主要的,Jetty中主要是用它来建立Handler的嵌套结构,就如ScopedHander同样,而handler操做大多数时候无用。
五、ScopedHandler这个真是折腾我很久,这样设计的意图着实很差理解,后面有专题解释,为理解本文,你能够将实现了继承了该类的Handler理解成已是一个完整的嵌套Handler便可。
六、ContextHandler从图中能够看到,由DeployManager生产,并和ServletHandler等构成了嵌套Handler。ContextHandler的本质可理解为ServletContext,取到ServletContext,因为嵌套Handler的构造继而会调用ServletHandler等初始化和相关操做,最后走到web应用中处理业务代码。其实这个嵌套关系是能够修改的,好比应用中用不到sessionHandler,彻底能够将其删除掉,但问题在与这种关系写在了代码中,为何就不能留在配置文件中呢?也许配置文件也能够,没有验证过。
Jetty的启动过程
实际流程比较复杂,上面的时序图是个简化版本。启动的时序图有几点须要注意:
一、红线部分的第一次其实并无handler,由于没有生产webappcontext,第二次再次调用start的时候才真的运做
二、蓝线部分描述的就是app的生产到contextHandler的生产的过程,后面的contextHandler的初始化是因为deployManager注册了事件监听器触发的。
三、最后打开Http链接,监听请求的到来
接受请求
因为Jetty默认采用NIO的方式接受请求,本文基于NIO的方式简单介绍下实现原理,由于NIO内容比较多,会在下面的文章中给出总结。
处理请求
主要介绍jetty接收到请求后如何生产并解析Request,Response等属性并最终走到handler方法体内。
这里面涉及到的connection有多个,SelectorChannelConnector、SelectorChannelEndPoint、AsyncHttpConnection,功能各不相同,下面NIO章节会详细总结。
Jetty与Tomcat的区别
因为没有研究过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 的 Vavle 设计也是与 Jetty 的 Handler 相似的方式。要本身实现一个 Vavle 与写一个 Handler 的难度不相上下。表面上看,Tomcat 的功能要比 Jetty 强大,由于 Tomcat 已经帮你作了不少工做了,而 Jetty 只告诉,你能怎么作,如何作,有你去实现。
单纯比较 Tomcat 与 Jetty 的性能意义不是很大,只能说在某种使用场景下,它表现的各有差别。由于它们面向的使用场景不尽相同。从架构上来看 Tomcat 在处理少数很是繁忙的链接上更有优点,也就是说链接的生命周期若是短的话,Tomcat 的整体性能更高。
而 Jetty 恰好相反,Jetty 能够同时处理大量链接并且能够长时间保持这些链接。例如像一些 web 聊天应用很是适合用 Jetty 作服务器,像淘宝的 web 旺旺就是用 Jetty 做为 Servlet 引擎。
另外因为 Jetty 的架构很是简单,做为服务器它能够按需加载组件,这样不须要的组件能够去掉,这样无形能够减小服务器自己的内存开销,处理一次请求也是能够减小产生的临时对象,这样性能也会提升。另外 Jetty 默认使用的是 NIO 技术在处理 I/O 请求上更占优点,Tomcat 默认使用的是 BIO,在处理静态资源时,Tomcat 的性能不如 Jetty。