tomcat系列之整体结构

本系列文章是基于tomcat6.0的源码。

首先分析一下tomcat的启动脚本,windows下的bat,

if "%OS%" == "Windows_NT" setlocal
rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem ---------------------------------------------------------------------------

rem Guess CATALINA_HOME if not defined
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"

rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExec

rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

:end

startup.bat脚本,主要完成了环境变量的检查,该脚本很简单,主要的工作全部委托给了catalina.bat,这个脚本是启动tomcat的主脚本,实际上catalina.bat也是检查各种环境变量的配置,并提供几种操作,比如启动,停止debug模式启动等。鉴于篇幅不一一讲解了,我们只关注一下tomcat启动的main函数在哪?bootstrap.jar就是这个jar包的main函数。org.apache.catalina.startup这个路径下的Bootstrap类。不过在分析该类时,我们先要熟悉下tomcat的结构是怎样的?

我们讲Tomcat是一个Servlet容器,通过servlet规范对外提供服务,因此Tomcat实质就是一个提供服务的容器,也就是说Tomcat是一个Server,可以把整个Tomcat抽象成一个Server。继续当我们访问某个服务的时候,通常通过浏览器输入一个类似下面的地址http://192.168.8.221:8080/explorer/loginInit.do其中指定了ip地址和端口还有详细的路径,要能对外提供服务必须指定一个自己的端口与外部通讯,然后TCP通过监听该端口,获取指定的消息并解析返回结果,整个过程可惜大概分为两个过程,监听并获取消息,处理消息,因此可以把这两部分分开来看,形成两个不同的组件,监听并获取消息的为Connector,处理消息的为Continer模块。我们知道Tomcat是一个Servlet容器,Servlet规范中曾提过应用上下文的概念,其实可以理解为我们的webapp,因此借鉴这个概念抽象出来Context概念,也是tomcat中的一个组件,为消息处理模块。但是当请求过来的时候我们怎么区分是哪个虚拟主机,来让Container来区分当然可以,不同的虚拟主机都由它来处理,但是将这个虚拟主机抽象出来似乎是个好的思路,tomcat中将该部分抽象为Host,虚拟主机可以简单的理解为域名,假如我们希望将多个域名映射到一个connector的时候,也即一个Connector组件负责和多个虚拟主机对接,也是非常不方便的,再或者我们希望针对这几个Host做一些统一的处理,比如拦截消息,非常不方便,因此tomcat抽象出来一个Engine的概念,由Engine充当Host的父组件,充当一个门面。讲了这么多Tomcat大概的体系结构图就出来了,借用网上别人的一张图:

上面图中的组件要比我们讲的详细的多,但主要的组件就那几个,Server是最顶层的抽象,一个Server下可以有多个Service,一个Service由一个Container和多个Connector组成,Container中有四个子概念,分别为Engine,Host,Context其中还有一个Wrapper图中没有画出来,Wrapper针对的是Servlet的组件。

Tomcat中有那么多的组件,就像一辆汽车,总得有人把他们组装起来才能工作吧,才能称之为Tomcat吧,没错,是需要组装起来,就像有汽车图纸一样,Tomcat中也有这样一张纸,就是server.xml:

<?xml version='1.0' encoding='utf-8'?>
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
	 注意这里,Server不是一个Container不能在它下面定义Valves(这个东西后面会提到)
 -->
 <!-- 顶层容器,配置好监听停止命令的端口-->
<Server port="8005" shutdown="SHUTDOWN">
 配置几个必须的监听器,也可以自己实现,最熟悉的是JasperListener,将我们的jsp翻译成servlet来执行
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <!--JNDI使用-->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
	   同样Service也不是Container,不能定义子组件Valves
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
	这里我们可以定义线程池,如果不定义,tomcat会使用自己的线程池来管理线程
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->

    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL HTTP/1.1 Connector on port 8080
		 连接器,消息的接受和发送都有它的一个endpoint来完成,常见的是http连接器
		 其实还有两种ajp,apr
    -->
	这里配置我们熟悉的端口8080,并且是http连接器
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
         This connector uses the JSSE configuration, when using APR, the
         connector should be using the OpenSSL style configuration
         described in the APR documentation -->
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
	AJP协议,通常的tomcat需要和web服务器比如apache来集成,那么和apache的通讯就使用到了该connector
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
	默认的Host是localhost,很熟悉吧http://localost:8080/index.html
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
	  这个配置项是来配置tomcat集群的
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->        

      <!-- The request dumper valve dumps useful debugging information about
           the request and response data received and sent by Tomcat.
           Documentation at: /docs/config/valve.html -->
      <!--
	  Valve非常重要的一个概念,这是基于将Request和Response当成消息流的方式来做的实现,
	  将请求流在不同的管道pipeline中流通,其中valve是在pipeline中定义的处理逻辑节点,也即当request
	  到该valve的时候,会执行其中的逻辑,这是很典型的责任链模式,非常常用,我们项目就是基于这个模式做的
	  扩展,形成了自己的一套框架。
      <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI
           resources under the key "UserDatabase".  Any edits
           that are performed against this UserDatabase are immediately
           available for use by the Realm.  -->
		   类似unix中的group,起到一个安全的作用,就是限制权限。
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>

      <!-- Define the default virtual host
           Note: XML Schema validation will not work with Xerces 2.2.
       -->
	   虚拟主机,定义app的基础目录,是否解压等信息
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
		单点登录的valve
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
        -->

      </Host>
    </Engine>
  </Service>
</Server>

这个就是图纸,定义了层级关系,初始化的动作由tomcat应用digester完成,简单提下digester是一个解析xml的工具也是apache的,通过定义个xml并且指定规则,来解析相应的xml,有很多优秀的解析xml工具,比如xtream使用起来非常简便。

上面就是tomcat的大体概况,详细的东西还得深入到源码去探究,怎样去下载编译tomcat源码,这里就不介绍了,网上百度一下有很多,善于借鉴别人的经验为己所用,也是一种能力。

时间: 2024-10-27 08:13:39

tomcat系列之整体结构的相关文章

Tomcat系列之Apache负载均衡请求至Tomcat及DeltaManager的使用

Tomcat系列之Apache负载均衡请求至Tomcat及DeltaManager的使用

tomcat系列之Java技术-1

Java与tomcat相关系列之一 1.Java技术包含的组件 包含四个独立且又彼此相关的技术: 1)       Java程序设计语言: 2)       JavaAPI(Java应用程序编程接口): 3)       Java class文件格式: 4)       JVM. 注:其实JVM可以理解为一个运行环境!!! 2.JVM的实现方式 1)       一次性解释器,解释字节码并执行. .javaà.class(bytecode)  即.java编译成为.class 2)       

Tomcat系列之服务器的安装与配置以及各组件详解

Tomcat系列之服务器的安装与配置以及各组件详解 大纲 一.前言 二.安装与配置Tomcat 三.Tomcat 目录的结构 四.Tomcat 配置文件 注,本文的测试的操作系统为CentOS 6.4 x86_64,软件版本为jdk-7u40.apache-tomcat-7.0.42.博文中的所有软件请到这里下载:http://yunpan.cn/QGBCLwrZnpLMS. 一.前言 在上一篇博文中我们主要讲解的Tomcat的基础知识以及相关的Java知识,对于不怎么清楚的博友可以参考一下:h

详解Tomcat系列(一)-从源码分析Tomcat的启动

在整个Tomcat系列文章讲解之前, 我想说的是虽然整个Tomcat体系比较复杂, 但是Tomcat中的代码并不难读, 只要认真花点功夫, 一定能啃下来. 由于篇幅的原因, 很难把Tomcat所有的知识点都放到同一篇文章中, 我将把Tomcat系列文章分为Tomcat的启动, Tomcat中各模块的介绍和Tomcat中的设计模式三部分, 欢迎阅读与关注. 一:通过idea搭建Tomcat源码阅读环境 首先我们到Tomcat的官网(http://tomcat.apache.org/)上下载Tomc

tomcat系列分析之生命周期管理初始化动作

tomcat中有很多组件,要对这些组件进行生命周期的管理非常困难,tomcat中采用的是抽象出一个生命周期管理接口,然后所有的组件都实现该接口,当父组件启动时,同事负责将子组件启动起来,从而完成整tomcat的初始.启动.结束等动作. 来看下tomcat启动的过程,首先构造Bootstrap类,调用其中的init方法,完成类加载器的初始化,方便后面加载类使用,然后调用其中的load方法,实际上tomcat真正的启动动作是由Catalina类完成的.而这其中在BootStrap中调用Catalin

深入理解Tomcat系列之一:系统架构

前言 Tomcat是Apache基金组织下的开源项目,性质是一个Web服务器.下面这种情况很普遍:在eclipse床架一个web项目并部署到Tomcat中,启动tomcat,在浏览器中输入一个类似http://localhost:8080/webproject/anyname.jsp的url,然后就可以看到我们写好的jsp页面的内容了.一切都是那么自然和顺理成章,然而这一切都是源于tomcat带给我们的,那么在tomcat背后,这一切又是怎么样发生的呢?带着对tomcat工作原理的好奇心,我决定

深入理解Tomcat系列之五:Context容器和Wrapper容器

前言 Context容器是一个Web项目的代表,主要管理Servlet实例,在Tomcat中Servlet实例是以Wrapper出现的.如今问题是怎样才干通过Context容器找到详细的Servlet呢?在解决问题之前.Context容器须要先启动,启动的过程就是载入个类资源文件以及打开子容器以及Pipeline管道的过程.启动Context容器后.就能够处理详细的请求了,详细是通过Request对象,从代码清单4-3的Wrapper wrapper = request.getWrapper()

Tomcat系列(2)——tomcat文件目录7个

核心部分 bin (运行脚本) conf (配置文件) lib (核心库文件) logs (日志目录) temp (临时目录) webapps (自动装载的应用程序的目录) work (JVM临时文件目录[java.io.tmpdir]) catalina.home(安装目录):指向公用信息的位置,就是bin和lib的父目录. catalina.base(工作目录):指向每个Tomcat目录私有信息的位置,就是conf.logs.temp.webapps和work的父目录. 仅运行一个Tomca

Tomcat系列(3)——Tomcat 组件及架构核心部分

1.架构图 2. 定义 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,它早期的名称为catalina,后来由Apache.Sun 和其他一些公司及个人共同开发而成,并更名为Tomcat.Tomcat 是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选,因为Tomcat 技术先进.性能