源码解读——Jetty

引言

Jetty相较于Tomcat更加轻便,虽然架构更加简单,但是看起来可并不轻松。Spring是设计初衷是用来管理应用中的实例Bean,因而是基于Bean的架构;Jetty则更倾向于流程和组件的管理,采用了基于handler的架构。handler的嵌套和链式结构,LifeCycle和doStart、doHandler模式无不印证了这点。

本文主要从基本架构、LifeCycle结构、Handler体系结构、Jetty启动过程、接受并处理请求的流程和与Tomcat的比较来简要介绍下Jetty,细节部分后面的博文会有分析。

Jetty的基本架构

前面的博文谈及应用服务期的架构已经说过了几个基本模块的概念,connection、Threadpool等~拷贝了我的同事许令波画的图(文中关于基本架构的描述挺详细的,参考了其目录结构哈~不过对于有些知识点有自己的看法,因此总结该文):

upload successful

该博文中谈到“Jetty 中还有一些可有可无的组件,我们可以在它上做扩展。如 JMX,我们可以定义一些 Mbean 把它加到 Server 中,当 Server 启动的时候,这些 Bean 就会一起工作。”我的理解是,Jetty中的JMX是提供给server的Container,使得注册到server的Handler同时注册到JMX上,以便于运行时的监控和管理,应该是先有server再有JMX,而不是反过来的。

LifeCycle体系结构

Jetty是基于Handler的架构模式,对于组件化的概念很容易理解,那Jetty又是如何管理流程和Handler的生命周期的呢,这就需要从下节的Handler的体系架构来解释,本节主要分析LifeCycle。

upload successful

写文档最讨厌的就是画图,无奈有些图没法copy~

上图包含四层涵义:

1、每个Handler都是一个LifeCycle

2、AggregateLifeCycle正如起名,聚集在一起的生命周期。Jetty把Handler生命周期所关联的一些subHandler注册在Hahdler上,eg:server->deployManager正是如此。

3、监听器的概念就是一个观察者模式的应用,触发于Handler的doStart,doStop,doFail等事件。

4、Jetty的LifeCycle结构主要影响Jetty的初始化,而Handler结构影响Jetty的处理功能。

Handler体系结构

既然Jetty是基于Handler的架构,那么Handler体系关乎着Jetty的方方面面:

upload successful

上图有几层涵义:

  1. 红色的server即Jetty的核心Handler,它依赖的几个类虽然不是Handler,也在图中标出以方便理解,server需要Deploy部署,需要Connector,自然需要inner Handler,这里的红色的虚线是默认的依赖关系,嵌入式的Jetty或自定义情况下是可以变的,比如换成ResourceHandler,WebAppContext等~
  2. AbatractHandlerContainer提供对嵌套Handler获取Childs的方法支持,因此位于很顶层。
  3. ContextHandlerCollection不同于普通的HandlerCollection的区别在于,提供了对于Context的支持,即依据生产的app建立app与name的映射关系并对于url请求依据该映射关系分发到指定的app中。
  4. HandlerWrapper仅仅提供了简单的对于Wapper的handler等操作,其实handler操作并不是主要的,Jetty中主要是用它来创建Handler的嵌套结构,就如ScopedHander一样,而handler操作大多数时候无用。
  5. ScopedHandler这个真是折腾我好久,这样设计的意图着实不好理解,后面有专题解释,为理解本文,你可以将实现了继承了该类的Handler理解成已经是一个完整的嵌套Handler即可。
  6. ContextHandler从图中可以看到,由DeployManager生产,并和ServletHandler等构成了嵌套Handler。ContextHandler的本质可理解为ServletContext,取到ServletContext,由于嵌套Handler的构造继而会调用ServletHandler等初始化和相关操作,最后走到web应用中处理业务代码。其实这个嵌套关系是可以修改的,比如应用中用不到sessionHandler,完全可以将其删除掉,但问题在与这种关系写在了代码中,为什么就不能留在配置文件中呢?也许配置文件也可以,没有验证过。

Jetty的启动过程

upload successful

实际流程比较复杂,上面的时序图是个简化版本。启动的时序图有几点需要注意:

  1. 红线部分的第一次其实并没有handler,因为没有生产webappcontext,第二次再次调用start的时候才真的运作
  2. 蓝线部分描述的就是app的生产到contextHandler的生产的过程,后面的contextHandler的初始化是由于deployManager注册了事件监听器触发的。
  3. 最后打开Http连接,监听请求的到来

接受请求

由于Jetty默认采用NIO的方式接受请求,本文基于NIO的方式简单介绍下实现原理,因为NIO内容比较多,会在下面的文章中给出总结。

upload successful

处理请求

主要介绍jetty接收到请求后如何生产并解析Request,Response等属性并最终走到handler方法体内。

upload successful

这里面涉及到的connection有多个,SelectorChannelConnector、SelectorChannelEndPoint、AsyncHttpConnection,功能各不相同