前面的http及socket两部分内容,主要是为了后面看Tomcat源码而学习的一些网络基础。从这章开始,就开始实际深入到Tomcat的‘内在’去看一看。 在分析Tomcat的源码之前,准备先看一下Tomcat的架构与一些核心类的简单分析,并简单介绍一下Tomcat是如何处理一次Http请求的。这部分内容有相当一部分来源于网络,在此,感谢原作者的贡献。
Tomcat的架构关系可以从Tomcat的配置文件server.xml中看到端倪。 从上图中可以看出Tomcat 的心脏是两个组件:Connector 和 Container,关于这两个组件将在后面详细介绍。Connector 组件是可以被替换,这样可以提供给服务器设计者更多的选择,因为这个组件是如此重要,不仅跟服务器的设计的本身,而且和不同的应用场景也十分相关,所以一个 Container 可以选择对应多个 Connector。多个 Connector 和一个 Container 就形成了一个 Service,Service 的概念大家都很熟悉了,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了。所以整个 Tomcat 的生命周期由 Server 控制。 Connector又叫连接器,它的主要任务是接收浏览器发过来的Tcp连接请求(说白了就是上一章讲的Socket请求),根据请求行,请求头,请求正文信息创建一个Request和Response(这个Request和Response我想大家都再熟悉不过了,虽然他还不是真正的HttpServletRequest与HttpServletResponse,但确实是有关的,姑且现在就当它是。这部分内容在后面的章节后讲到)。然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理这个请求的线程,处理这个请求的线程就是 Container 组件要做的事了。 在一个Service中,Connector可以有多个,每一个Connector对应了一种不同的处理协议,在Tomcat中默认支持的是Http与AJP协议,所以Tomcat中实现了HttpConnector与AjpConnector。但是Container只有一个。Connector与Container是多对一的关系。如下:
说白了,Service 只是在 Connector 和 Container 外面多包一层,把它们组装在一起,向外面提供服务,一个 Service 可以设置多个 Connector,但是只能有一个 Container 容器。 2. Tomcat处理一次请求的过程
上面的图形简单描绘了Tomcat解析一次请求的大致过程。图中只简单描绘了Tomcat处理的几个重要节点,里面包括对的很多其他组件,比如:processor,Engine,Host,Context等都没有描绘出来,这些细节在后面的章节一边学习一面总结。 在Container接收到Request后,根据Request中请求的URL,解析出要请求的Servlet,根据配置文件(一般为应用中web.xml中的Servlet或其他可访问资源)获得起路径后,使用相应的类加载器加载Servlet,然后调用其Service方法。余下的就是客户自己编写的Servlet进行工作了。 3、Tomcat核心类
Tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成,如Server、Service、Connector等,并基于JMX管理这些组件,另外实现以上接口的组件也实现了代表生存期的接口Lifecycle,使其组件履行固定的生存期,在其整个生存期的过程中通过事件侦听LifecycleEvent实现扩展。 Catalina:与开始/关闭shell脚本交互的主类,因此如果要研究启动和关闭的过程,就从这个类开始看起。 Server:是整个Tomcat组件的容器,包含一个或多个Service。 Service:Service是包含Connector和Container的集合,Service用适当的Connector接收用户的请求,再发给相应的Container来处理。 Connector:实现某一协议的连接器,如默认的有实现HTTP、HTTPS、AJP协议的。 Container:可以理解为处理某类型请求的容器,处理的方式一般为把处理请求的处理器包装为Valve对象,并按一定顺序放入类型为Pipeline的管道里。Container有多种子类型:Engine、Host、Context和Wrapper,这几种子类型Container依次包含,处理不同粒度的请求。另外Container里包含一些基础服务,如Loader、Manager和Realm。 Engine:Engine包含Host和Context,接到请求后仍给相应的Host在相应的Context里处理。 Host:就是我们所理解的虚拟主机。 Context:就是我们所部属的具体Web应用的上下文,每个请求都在是相应的上下文里处理的。 Wrapper:Wrapper是针对每个Servlet的Container,每个Servlet都有相应的Wrapper来管理。 可以看出Server、Service、Connector、Container、Engine、Host、Context和Wrapper这些核心组件的作用范围是逐层递减,并逐层包含。参考:
Tomcat 系统架构与设计模式,第 1 部分: 工作原理 |