(一) 版本更新
1. Tomcat3
最初的版本,也是写得不错的,特别是线程的部分;整体结构相当简单;但是比较松散;
2. TomCat4.1
A.
3. Tomcat6
(一) 启动流程
(二) 关键组件
(1) 服务器 (Server)
在 Tomcat 中,服务器代表整个 J2EE 容器,所有的服务及服务上下文均包含在服务器内。我们打开 Tomcat 源代码,可以看到 org.apache.catalina.Server 这个接口,其中比较重要的方法有 initialize( 负责 Tomcat 启动前的初始化工作 ) ,还有一些服务 (Services) 管理方法,比如 removeService() 、 addService() 、 findService() 之类的方法。
(2) 服务 (Service)
在上述的标准服务器 (StanderServer.java) 实现代码中,我们可以看到其中有一个 services 的数组,这个数组就是用来存储服务 (Service) 的。所以,我们可以这样理解,一个服务器可能有一至多个服务组成。所谓服务,就是包含一至多个连接器的组件,能够对用户请求作出响应的组件。打开 org.apache.catalina.Service.java 的源代码,我们可以看到其中含有一个连接器数组 (Connector[]) ,这表明一个 Service 有可能包含一个到多个连接器。但所有这些连接器都属于一个引擎 (Engine 或Container) 。在 Tomcat6 中, org.apache.catalina.Service 接口由 org.apache.catalina.core. StandardService 类来实现
的。
(3) 引擎 (Engine)
对一个具体的服务 (service) 来说,引擎是一个用户请求的处理管道,这个管道很特别,因为它只处理 Servlet 请求,在Tomcat 中,引擎其实就是指 Servlet 引擎。引擎从这些连接器那里接收到 Servlet 请求,然后处理它们,并将响应的结果传回到适当的连接器,从而将响应发送到客户端。简单地说,引擎的功能就是如何处理用户的 Servlet 请求。
org.apache.catalina.Engine 这个接口继承自 org.apache.catalina.Container ,说明引擎是一种特殊的 Container ,是一种专门用来处理 servlet 请求的容器。
(4) 主机 (Host)
对 Tomcat 服务器来说,主机是 Tomcats 所在机器的网络名 ( 域名 ) 。一个引擎可能包含多个主机,主机支持网络别名。例如,用户通过配置 config.xml 里面的主机 (Host) 元素,让 www.abc.com 和 abc.com 指向同一台 Tomcat 应用服务器。
A Context represents a web application. A Host may contain multiple contexts, each with a unique path. The Context interface may be implemented to create custom Contexts, but this is rarely the case because the StandardContext provides significant additional functionality. |
(5) 连接器 (Connector)
在 Tomcat 中,连接器负责和客户端进行请求响应的交流。 Tomcat 中有两种连接器 (Coyote 和 JK 连接器 ) , Coyote 连接器实现了 Http1.1 协议,我们可以将它理解为 Tomcat 的 Web 服务器部分。 JK 连接器负责处理来自第三方 Web 服务器的请求,并将请求结果发送给第三方 Web 服务器。针对 Apache Httpd Web 服务器, JK 连接器实现了 AJP 协议。
在 Tomcat6.0 中,实现 Coyote 连接器的类是 org.apache.catalina.connector.Connector 。
环境设置完成(2010-12-22)
首先,我们可以从功能的角度将 Tomcat 源代码分成 5 个子模块,它们分别是:
(三) Jsper 子模块
这个子模块负责 jsp 页面的解析, jsp 属性的验证,同时也负责将 jsp 页面动态转换为 java 代码并编译成 class 文件。在Tomcat 源代码中,凡是属于 org.apache.jasper 包及其子包中的源代码都属于这个子模块;
(四) Servlet 和 Jsp 规范的实现模块
这个子模块的源代码属于 javax.servlet 包及其子包,如我们非常熟悉的 javax.servlet.Servlet 接口、javax.servet.http.HttpServlet 类及 javax.servlet.jsp.HttpJspPage 就位于这个子模块中;
(五) Catalina 子模块
这个子模块包含了所有以 org.apache.catalina 开头的 java 源代码。该子模块的任务是规范了 Tomcat 的总体架构,定义了
Server 、 Service 、 Host 、 Connector 、 Context 、 Session 及 Cluster 等关键组件及这些组件的实现,这个子模块大
量运用了 Composite 设计模式。同时也规范了 Catalina 的启动及停止等事件的执行流程。从代码阅读的角度看,这个子模
块是我们阅读和学习的重点。
(六) Connectors 子模块
如果说上面三个子模块实现了 Tomcat 应用服务器的话,那么这个子模块就是 Web 服务器的实现。所谓连接器 (Connector)就是一个连接客户和应用服务器的桥梁,它接收用户的请求,并把用户请求包装成标准的 Http 请求 ( 包含协议名称,请求头Head ,请求方法是 Get 还是 Post 等等 ) 。同时,这个子模块还按照标准的 Http 协议,负责给客户端发送响应页面,比如在请求页面未发现时,connector就会给客户端浏览器发送标准的 Http 404 错误响应页面。
Tomcat 实现了两类连接器,除了上述实现了 Http1.1 协议的 Coyote 连接器外,还有一种 JK 连接器,JK 连接器是将Tomcat 和第三方 Web 服务器 ( 如 Apache 或 IIS Web 服务器 ) 连接起来, Tomcat 此时充当应用服务器的角色,负责处理和解释 Jsp 及 Servlet 请求。
Coyote 连接器的源代码位于以 org.apache.coyote 开头的包中, JK 连接器的代码位于以 org.apache.jk 开头的包中。
另外, Tomcat 虽然实现了 Web 服务器的功能,但是其实现不是非常完美,效率不高,所以在生产环境中,我们通常要将
Tomcat 和 Apache Web Server 配合使用,尽量利用它们各自的优势。
(七) 5) Resource 子模块
这个子模块包含一些资源文件,如 Server.xml 及 Web.xml 配置文件。严格说来,这个子模块不包含 java 源代码,但是它还
是 Tomcat 编译运行所必需的。
上面我们从模块组件的角度,简单介绍了 Tomcat 的子模块划分及其相应的功能。下面我们简单以图示意之。
从上面的Tomcat 子模块示意图中,我们可以看到,来自客户端的请求首先由 Connector 子模块进行处理,然后根据情况或者发送到第三方的 Web 服务器,或者转发到 Jsper 模块进行处理,或者转发到 Jsp/Servlet 子模块处理。
总体说来,Tomcat 通过下面三种方式处理来自客户端的请求:
(1) 如果客户端发出静态页面请求,如果没有配置第三方 Web 服务器,此时客户端的请求直接交由 Coyote Connector 子模块处理,然后返回结果;如果配有第三方应用服务器,那么客户的请求直接由第三方应用服务器响应,然后返回静态记过页面。客户端请求的执行过程如图中绿线所示。
(2) 如果客户端请求 Jsp 页面,该请求首先转发到发送 Coyote 连接器 ( 在没有配置第三方 Web 服务器的情况下 ) ,或者经过第三方 Web 服务器将客户请求转发到 JK 连接器;然后该 Jsp 请求将交给 Jsper 子模块处理, Jsper 将根据情况验证编译该 Jsp 页面,最后由 Jsp/Servlet 模块对客户请求进行处理。 Jsp 请求处理完毕,服务器首先把响应结果发送给连接器子模块,连接器子模块根据情况或将响应结果页面发送到第三方 Web 服务器,或者直接发送响应结果页面到客户端。
(3) 如果客户请求 Servlet , Tomcat 的处理流程和 Jsp 页面的请求执行流程基本类似,只不过少了一个 Jsper 子模块处理罢了。
<tomcat源码分析>
在 Sun公司提出JMX(JSR174) 以前,人们通常都是使用 SNMP对网络上的资源进行管理。 SNMP的主要问题是入门门槛太高,不容易使用。所以 Sun提出了 JSR174倡议并且提供了一套 JMX的参考实现。
从技术上说, JMX整体架构可分为三层,即资源植入层 (Instrumentation Level ,可能有更好的译法? ) 、代理层 (Agent Level) 和管理层 (Manager Level) ,简述如下:
资源植入层 (Instrumentation Level) :该层包含 MBeans及这些 MBeans所管理的资源, MBeans是一个 Java对象,它必须实现 JMX规范中规定的接口。按照 JMX规范,在 MBeans对象的接口中,我们可以指定管理层可以访问资源的哪些属性,可以调用资源的哪些方法,并且,在资源的属性发生变化是,我们的 MBeans可以发出消息,通知对这些属性变化感兴趣的其它对象。 JMX规范定义了四种 MBeans,它们分别是标准
MBeans(Standard MBeans) 、动态 MBeans(Dynamic MBeans) 、开放 MBeans(Open MBeans) 和模态MBeans(Model MBeans) 。
代理层 (Agent Level) :代理层的目的就是要把 MBeans中实现的接口暴露给管理层,该层通常由 MBean Server和 Agent Services 构成, MBean Server 就是一个 MBeans对象注册器,所有的资源 MBeans都注册到这个MBean Server ,对象管理器或者其它的管理层应用程序可以通过访问 MBean Server ,从而可以访问 MBean Server 中注册的 MBeans,当然也就可以监视和管理和这些 MBeans绑定的资源。
管理层 (Manager Level) :又称之为分布式服务层 (Distributed Services) ,顾名思义,该层主要包含一些管理应用程序,这些程序可以访问和操作 JMX代理层 (Agent Level) 。这些管理应用程序可以是一个 Web应用,也可能是一个 Java SWT应用程序。