美文网首页程序小寨
Tomcat架构介绍及配置分析

Tomcat架构介绍及配置分析

作者: 梦中一点心雨 | 来源:发表于2018-12-18 14:33 被阅读3次

    在之前的项目中,需要对项目做集群,由于项目对系统的并发要求不大,所以就采取Session共享方式实现,虽然根据在网上找的资料完成了集群,但是对Tomcat的Session的共享的底层原理一直比较好奇,正好借此机会,调试一下Tomcat源码,略作分析。

    • bin

      存放启动和关闭Tomcat的脚本文件

    • conf

      存放Tomcat的各种配置文件

    • lib

      存放Tomcat的依赖jar包

    • logs

      存放Tomcat的日志文件

    • temp

      存放Tomcat运行中产生的临时文件

    • webapps

      web应用所在目录,即供外界访问的web资源的存放目录

    • work

      Tomcat的工作目录

    1. conf/配置文件说明

    1.1 catalina.properties

    Tomcat的catalina.properties文件位于%CATALINA_HOME%/conf/目录下面,该文件主要配置tomcat的安全设置、类加载设置、不需要扫描的类设置、字符缓存设置四大块。

    • 安全设置

      package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat.
      package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat.
      
    • 类加载设置

      tomcat的类加载顺序为:

      Bootstrap ---> System ---> /WEB-INF/classes ---> /WEB-INF/lib/*.jar ---> Common

      注: Common的配置是通过catalina.properties的commons.loader设置的

      common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
      

      类加载顺序:

      ${catalina.base}/lib 未打包的类和资源文件

      ${catalina.base}/lib/*.jar JAR文件

      ${catalina.home}/lib 未打包的类和文件

      ${catalina.home}/lib/*.jar JAR文件

      默认情况下,会加载以下内容:

      • annotations-api.jar — JavaEE注释类
      • catalina.jar — 执行Tomcat的Catalina Servlet容器部分
      • catalina-ant.jar — Tomcat Catalina Ant 任务
      • catalina-ha.jar — 高可用包
      • catalina-tribes.jar — 组通信包
      • ecj-*.jar — Eclipse JDT Java 编译器
      • el-api.jar — EL 2.2 API.
      • jasper.jar — JSP 运行时编译器
      • jasper-el.jar — EL表达式的实现
      • jsp-api.jar — JSP 2.2 API.
      • servlet-api.jar — Servlet 3.0 API.
      • tomcat-api.jar — 由Tomcat定义的几个接口
      • tomcat-coyote.jar — Tomcat连接器和使用程序类
      • tomcat-dbcp.jar — 基于Apache Commons Pool和Apache Commons DBCP的数据库连接池
      • tomcat-i18n-*.jar* — 包含其他语言的资源约束的可选JAR,默认捆绑包含在每个单独的应用中,如果不需要国际化,可以删除
      • tomcat-jdbc.jar — Tomcat JDBC数据库连接池
      • tomcat-util.jar — Tomcat的各种组件使用的常见类
      • tomcat7-websocket.jar — WebSocket 1.1 实现
      • websocket-api.jar — WebSocket 1.1 API

      注: CATALINA_HOME是Tomcat的安装目录,CATALINA_BASE是Tomcat的工作目录,一个Tomcat可以通过配置CATALINA_BASE来增加多个工作目录,也就是增加多个实例。多个实例各自可以有自己的conf,logs,temp,webapps。

      server.loader和shared.loader

      在common.loader加载完毕后,tomcat启动程序会检查catalina.properties文件中配置的server.loader和shared.loader是否设置。如果设置,读取tomcat下对应的server和shared这两个目录的类库。server和shared是对应tomcat目录下的两个目录,在Tomcat中默认是没有,catalina.properties中默认也是没有设置其值。设置方法如下:

      server.loader=${catalina.base}/server/classes,${catalina.base}/server/lib/*.jar
      shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar
      

      同时需要在tomcat目录下创建server和shared目录结构并将公用的、应用类放到里面。类加载顺序为:

      Bootstrap ---> System ---> /WEB-INF/classes ---> /WEB-INF/lib/*.jar ---> Common ---> Server ---> Shared

    • 字符缓存设置

      # String cache configuration.
      tomcat.util.buf.StringCache.byte.enabled=true
      #tomcat.util.buf.StringCache.char.enabled=true
      #tomcat.util.buf.StringCache.trainThreshold=500000
      #tomcat.util.buf.StringCache.cacheSize=5000
      

    总结: Tomcat可以通过catalina.properties的server和shared,为webapp提供公用类库。使一些公用的、不需要与webapp放在一起的设置信息单独保存,在更新webapp的war的时候无需更改webapp的设置。

    1.2 catalina.policy

    包含由Java Security Manager实现的安全策略声明,它替换了安装java时带有的java.policy文件。这个文件用来防止欺骗代码或JSP执行带有像System.exit(0)这样可能影响容器的破坏性代码,只有当Tomcat用-security命令行参数启动时这个文件才会被使用。

    1.3 context.xml

    这个通用context.xml可被所有的web应用程序使用,这个文件默认地可以设置到何处访问各web应用程序中的web.xml文件。context.xml文件的作用和server.xml中<Context>标签作用相同。在tomcat5.5之后,对Context的配置不推荐在server.xml中进行配置,而是在/conf/context.xml中进行独立的配置。因为server.xml是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而context.xml文件则不然,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),就会自动重新加载这个文件,而不需要重启服务器。

    默认的context.xml如下:

    <Context>
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    </Context>
    

    以下给出一个JNDI数据源的配置:

    <Resource name="jdbc/mysql"
            auth="Container"
            type="com.alibaba.druid.pool.DruidDataSource"
            maxActive="100"
            maxIdle="30"
            maxWait="10000"
            username="root"
            password="root"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/test"
    />
    

    context.xml的作用范围

    • tomcat server级别

      在/conf/context.xml里配置

    • Host级别

      在/conf/Catalina/${hostName}里添加context.xml,继而进行配置。

    • web app级别

      在/conf/Catalina/${hostName}里添加${webappName}.xml,继而进行配置。

    1.4 server.xml

    tomcat的主要配置文件,解析器用这个文件在启动时根据规范创建容器。

    默认的server.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
        <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>
      <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="localhost">
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
          </Host>
        </Engine>
      </Service>
    </Server>
    

    Server是顶级元素,代表一个Tomcat实例。可以包含一个或多个Service,每个Service都有自己的Engines和Connectors。

    Server元素

    • className

      使用Java实现类的名称。这个类必须实现org.apache.catalina.Server接口。如果没有指定类名,将会使用标准实现。

    • address

      server在这个TCP/IP地址上监听一个shutdown命令。如果没有指定地址,将会使用localhost。

    • port

      server在这个端口上监听一个shutdown命令。设置为-1表示禁用shutdown命令。

    • shutdown

      连接到指定端口的TCP/IP收到这个命令字符后,将会关闭Tomcat。

    Listeners元素

    Server可以包含多个监听器。一个监听器监听指定事件,并对其作出响应。

    GlobalResourcesLifecycleListener作用于全局资源,保证JNDI对资源的可达性,比如数据库。

    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    
    • SSLEngine

      使用的SSLEngine名称。off:不适用SSL,on:使用SSL但不指定引擎。默认值是on。会初始化本地SSL引擎,对于使用SSLEnabled属性的APR/native connector来讲,该选项必须可用。

    • SSLRandomSeed

      指定伪随机数生成器(PRNG)的随机数种子源,默认值为builtin。在开发环境下,可能要将其设置为/dev/urandom,以获得更快的启动速度。

    • FIPSMode

      设置为on会请求OpenSSL进入FIPS模式(如果OpenSSL已经处于FIPS模式,将会保留该模式)。该设置为enter会强制OpenSSl进入FIPS模式(如果OpenSSL已经处于FIPS模式,将会产生一个错误)。设置为require要求OpenSSL已经处于FIPS模式(如果OpenSSL当前没有处于FIPS模式将会产生一个错误)。

    GlobalNamingResources元素全局命名资源

    GlobalNamingResources元素定义了JNDI(Java命名和目录接口)资源,其允许Java软件客户端通过名称搜寻和查找数据。默认配置定义了一个名称为UserDatabase的JNDI,通过“conf/tomcat-users.xml”得到一个用于用户授权的内存数据库。

    <GlobalNamingResources>
        <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>
    

    也可以定义其他全句话JNDI资源来实现连接池,比如MySQL数据库。

    Services元素

    一个Service可以连接一个或多个Connectors到一个引擎。默认配置定义了一个名为“Catalina”的Service,连接了两个Connectors:HTTP和AJP到当前的引擎。

    <Service name="Catalina">
       <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
       <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
       <Engine name="Catalina" defaultHost="localhost">
         <Realm className="org.apache.catalina.realm.LockOutRealm">
           <Realm className="org.apache.catalina.realm.UserDatabaseRealm"               
                  resourceName="UserDatabase"/>
         </Realm>
         <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
           <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                  prefix="localhost_access_log" suffix=".txt"
                  pattern="%h %l %u %t &quot;%r&quot; %s %b" />
         </Host>
       </Engine>
    </Service>
    
    • className

      该实现使用的Java类名称。这个类必须实现org.apache.catalina.Service接口。如果没有指定类名称,将会使用标准实现。

    • name

      Service的显示名称,如果采用了标准的Catalina组件,将会包含日志信息。每个Service与某个特定的Server关联的名称必须是唯一的。

    Connectors元素

    一个Connector关联一个TCP端口,负责处理Service与客户端之间的交互。默认配置定义了两个Connectors。

    • HTTP/1.1

      处理HTTP请求,使得Tomcat成为一个HTTP服务器。客户端可以通过Connector向服务器发送HTTP请求,接收服务器端的HTTP响应信息。

      <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
      

      与生产服务默认使用80端口不同,Tomcat HTTP服务默认在TCP端口8080上运行。可以选择1024到65535之间的任意数字作为端口号来运行Tomcat服务器,前提是该端口没有被任何其他应用使用。connectionTimeOut属性定义了这个connector在链接获得同意之后,获得请求URI line(请求信息)响应的最大等待时间毫秒数。默认为20秒。redirect属性会把SSL请求重定向到TCP的8443端口。

    • AJP/1.3

      Apache JServ Protocol connector处理Tomcat服务器与Apache HTTP服务器之间的交互。

      <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
      

      可以将Tomcat和Apache HTTP服务运行在一起,Apache HTTP服务器处理静态请求和PHP;Tomcat服务器负责处理Java Servlet/JSP。

    容器

    包含了Engine、Host、Context和Cluster的Tomcat称为容器。最高级的是Engine,最底层的是Context。某些组件,比如Realm和Value,也可以放在容器中。

    Engine引擎

    引擎是容器中最高级别的部分。可以包含一个或多个Host。Tomcat服务器可以配置为运行在多个主机名上,包括虚拟主机。

    <Engine name="Catalina" defaultHost="localhost">
    

    Catalina引擎从HTTP connector接收HTTP请求,并根据请求头部信息中主机名或IP地址重定向到正确的主机上。

    • backgroundProcessorDelay

      这个值表示了在这个引擎和它的子容器上调用backgroundProcess方法之间间隔的秒数,包括所有host和context。值为非负时不会调用子容器(意味着其使用自身的处理线程)。设置为正值会产生一个衍生线程。等待指定的时间之后,该线程会在这个引擎和它的所有子容器上调用backgroundProcess方法。如果没有指定,默认值为10,即会有10秒的延迟。

    • className

      实现该引擎使用的Java类名。该类必须实现org.apache.catalina.Engine接口。如果没有指定,会使用标准值。

    • defaultHost

      默认主机名,定义了处理指向该服务器的请求所在主机的名称,但名称不是在这个文件中配置。

    • jvmRoute

      在负载均衡场景下必须定义该参数,来保证session affinity可用,对于集群中所有Tomcat服务器来讲定义的名称必须是唯一的,该名称将会被添加到生成的会话标示符中,因此,允许前端代理总是将特定会话转发到同一个Tomcat实例。

    • name

      Engine的逻辑名称,用在日志和错误信息中。当在相同的Server中使用多个Service元素时,每个Engine必须制定一个唯一的名称。

    • startStopThreads

      Engine在启动Host子元素时将会并发使用的线程数。如果设置为0,将会使用Runtime.getRuntime().availableProcessors()的值。设置为负数,将会使用Runtime.getRuntime().availableProcessors() + value的值,如果结果小于1,将会使用1个线程。如果没有指定,默认值为1。

    Realm元素

    一个Realm(域)就是一个包含user、password和role认证(比如访问控制)的数据库。你可以在任何容器中定义Realm,例如Engine、Host、Context和Cluster。

    <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
    </Realm>
    

    默认配置定义了一个Catalina Engine的Realm(UserDatabaseRealm),对用户访问engine的权限进行控制。其使用定义在GlobalNamingResources中,名字为UserDatabase的JNDI。

    除了UserDatabaseRealm以外,还有:JDBCRealm(授权用户是否可以通过JDBC驱动连接到关系型数据库);DataSourceRealm(通过JNDI连接到数据库);JNDIRealm(连接到一个LDAP目录);MemoryRealm(将XML文件加载到内存)。

    • className

      使用Java实现类的名称。这个类必须实现org.apache.catalina.Realm接口。

    Hosts

    一个Host定义了在Engine下的一个虚拟机,反过来其又支持多个Context(web应用)。

    <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">
    

    默认配置定义了一个名为localhost的主机。appBase属性定义了所有webapp的根目录,在这种情况下是webapps。默认情况下,每一个webapp的URL和它所在的目录名称相同。例如,默认的Tomcat安装目录的webapps下提供了四个web应用:docs、examples、host-manager和manager。只有ROOT是个例外,它用一个空字符串定义。也就是说,它的URL是http://localhost:8080/。unpackWARs属性指定了放到webapps目录下的WAR-file是否应该被解压。对于unpackWARs=“false”,Tomcat将会直接从WAR-file运行应用,而不解压,这可能导致应用运行变慢。autoDeploy属性指定了是否自动部署放到webapps目录下的应用。

    • appBase

      虚拟机应用的根目录。该目录是一个可能包含部署到虚拟机上web应用的路径名。也可能是一个指定的绝对路径名,或者是一个相对于$CATALINA_BASE目录的路径名。如果没有指定,默认会使用webapps。

    • xmlBase

      虚拟机XML根目录。该目录是一个可能包含部署到虚拟机上context XML描述符的路径名。也可能是一个指定的绝对路径名,或者是一个相对于$CATALINA_BASE目录的路径名。如果没有指定,默认会使用conf/目录。

    • createDirs

      如果设置为true,Tomcat将会在启动阶段,尝试创建一个由appBase和xmlBase属性定义的目录。默认值为true。如果设置为true,并且目录创建失败,将会打印出一个错误信息,但是不会终止启动过程。

    • autoDeploy

      该属性的值指明了在Tomcat运行的时候,是否需要定义检查新的或者更新后的web应用。如果为true,Tomcat会定义检查appBase和xmlBase目录,并对找到的新web应用和context XML描述符进行部署。更新web应用或XML上下文描述符将会触发web应用的重载。默认值为true。

    • backgroundProcessorDeploy

      表示在调用这台主机的backgroundProcess方法和它的子容器方法,包括所有的context,之间延迟的秒数。如果延迟值不是负数的话,不会调用子容器(意味着会使用它们自己的处理线程)。设置为正数会产生衍生线程。在等待指定的时间之后,线程将会在该host上调用backgroundProcess方法,包括它的所有子容器。host将会使用后台进程执行web应用部署相关的任务。如果没有指定,默认值为-1,意味着host将会依赖于它的父引擎的后台处理线程。

    • className

      使用的Java实现类的名称。该类必须实现org.apache.catalina.Host接口。

    • deployIgnore

      一个正则表达式,定义了在自动部署和启动时部署的情况下需要忽略的目录。这就允许我们在版本控制系统中保持自己的配置,例如,不会将.svn或者git文件夹部署到appBase目录下。该正则表达式是相对于appBase的。同时也是固定的,意味着是相对于整个文件或目录的名称进行的。因此,foo只会匹配名称为foo的文件或目录,而不会匹配foo.war等名称的文件或目录。如果想让“foo”匹配任意名称,可以使用“.*foo.*”。

    • deployOnStartup

      指定在Tomcat启动时是否需要自动部署host下的web应用。默认值为true。

    • failCtxlfServletStartFails

      设置为true时,如果它的任意一个load-on-startup >= 0的servlet停止自身启动后,停止启动它的每一个子context。每一个子context可能覆盖这个属性。如果没有指定,将会使用默认值false。

    • name

      通常是虚拟主机的网络名称,注册在你的域名服务器上。无论指定的主机名称是什么样的,Tomcat在内部都会将其转换为小写。嵌套在Engine内部的Host,其中必须有一个Host的名称匹配Engine的默认Host设置。

    • startStopThreads

      Host在启动子Context元素时会并发使用的线程数。如果自动部署被使用的话将会使用该线程池部署新的Context。值为0时将会使用Runtime.getRuntime().availableProcessors()的值。值为负数时将会使用Runtime.getRuntime().availableProcessors()加上该值得和,小于1时将会使用1个线程。如果没有指定,会使用默认值1。

    • undeployOldVersion

      该选项的值决定Tomcat,即自动部署进程部分,是否会检查并发部署的过时web应用,任何找到的应用都会被移除。只有在autoDeploy为true的情况下才会生效。如果没有指定将会使用默认值false。

    Value

    Value(阀门)作为请求的前置处理程序,可以在请求发送到应用之前拦截HTTP请求。可以定义在任何容器中,比如Engine、Host、Context和Cluster。默认配置中,AccessLogValue会拦截HTTP请求,并在日志文件中创建一个切入点

    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    
    • className

      设置为org.apache.catalina.ha.tcp.ReplicationValue

    • filter

      对于已知文件扩展名或url,可以在请求中使用Value通知cluster没有修改session,对于本次变化cluster没有必要通知session管理者。如果请求匹配该过滤器模型,cluster会假设session没有发生变化。一个filter样例大概是这样的filter=“.*.gif|.*.js|.*.jpeg|.*.jpg|.*.png|.*.htm|.*.html|.*.css|.*.txt”。filter使用java.util.regex的正则表达式。

    • primaryIndicator

      布尔值,如果为true,replication value将会把primaryIndicatorName属性定义的名称插入到request属性中,该值无论是Boolean.TRUE或者Boolean.FALSE,都会被放入request属性中。

    • primaryIndicatorName

      默认值为org.apache.catalina.ha.tcp.isPrimarySession,这个值定义了一个request属性的名称,值是一个布尔值,表示会话所在的服务器是否为主服务器。

    • statistics

      布尔值,如果想让value手机请求的统计数据,设置为true,默认值为false。

    • RemoteAddrValue

      阻截来自特定IP地址的请求。

    • RemoteHostValue

      阻截基于主机名称的请求。

    • RequestDumperValue

      记录了请求的详细信息。

    • SingleSignOnValue

      当置于a下时,允许单点登录到该主机下的所有应用上。

    1.5 tomcat-users.xml

    用于访问tomcat管理应用程序时的安全性设置,用server.xml中引用的默认的用户数据库域(UserDatabase Realm)使用它,所有的凭证默认都是被注释的,如需授权和访问控制,或配置角色,可参考以下配置。

    <role rolename="manager"/>
    <role rolename="manager-gui"/>
    <role rolename="admin"/>
    <role rolename="admin-gui"/>
    <user username="admin" password="admin" roles="admin-gui,admin,manager-gui,manager"/>
    

    这样tomcat7首页上的Server Status、Manager App、Host Manager就都可以点击登录进去。

    tomcat6配置:

    <role rolename="admin"/>
    <role rolename="manager"/>
    <user username="admin" password="admin" roles="admin,manager"/>
    

    1.6 web.xml

    默认的web.xml文件可被所有的web应用程序使用,这个web.xml文件会设置jspservlet以支持应用程序处理jsps,并设置一个默认的servlet来处理静态资源和html文件,它还设置默认的回话超时以及像index.jsp,index.html这类欢迎文件,并且它为最通用的扩展文件设置默认的MIME类型。

    一般在Java工程中,web.xml用来初始化工程配置信息,比如welcome页面,filter,listener,servlet,servlet-mapping,启动加载级别等等。

    当应用程序被部署到tomcat时,它会用[engine name]/[host name]/[context-path name].xml创建与context.xml等效的文件,如用户也在$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default文件,在这个文件中特定主机下的所有web应用程序将对主机器虚拟环境采用一系列默认设置。

    下面就详细介绍一下web.xml中常用的标签及其功能。

    <description>,<display-name>,<icon>

    • <description>

      <description>项目描述</description> <!--对项目作出描述-->
      
    • <display-name>

      <display-name>项目名称</display-name> <!--定义项目的名称-->
      
    • <icon>及<small-icon>,<large-icon>

      <icon> icon元素包含small-icon和large-icon两个子元素,用来指定web站台中小图标和大图标的路径。

      <!--small-icon元素应指向web站台中某个小图标的路径,大小为16X 16 pixel,但是图像文件必须为GIF或JPEG格式,扩展名必须为.git或.jpg-->
      <small-icon>/路径/smallicon.gif</small-icon>
      <!--large-icon元素应指向web站台中某个大图标路径,大小为32X 32pixel,但是图像文件必须为GIF或JPEG的格式,扩展名必须为.git或.jpg-->
      <large-icon>/路径/largeicon.jpg</large-icon>
      

      例如:

      <display-name>Demo Example</display-name>
      <description>JSP 2.0 Demo Example</description>
      <icon>
        <small-icon>/images/small.gif</small-icon>
            <large-icon>/images/large.gif</large-icon>
      </icon>
      

    <context-param>

    <context-param>元素含有一对参数名和参数值,用作应用的servlet上下文初始化参数。参数名在整个web应用中必须是唯一的。

    例如:

    <context-param>
        <param-name>name</param-name>
        <param-value>haha</param-value>
    </context-param>
    

    此处设定的参数,在JSP页面可以使用${initParam.name}来获取。

    在Servlet中可以使用下列方式获取:

    String name = getServletContext().getInitParamter("name");
    

    <filter>

    filter元素用于指定web容器中的过滤器。

    在请求和响应对象被servlet处理之前或之后,可以使用过滤器对这两个对象进行操作。通过filter-mapping元素,过滤器被映射到一个servlet或一个URL模式。这个过滤器的filter元素和filter-mapping元素必须具有相同的名称。

    filter元素用来声明filter的相关设定,filter元素除了下面介绍的子元素之外,还包括<icon>,<display-name>,<description>,<init-param>,其用途一样。

    例如:

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    

    <filter-mapping>

    filter-mapping元素用来声明web应用中的过滤器映射。过滤器可被映射到一个servlet或一个URL模式。将过滤器映射到一个servlet中会造成过滤器作用于servlet上。将过滤器映射到一个URL模式中则可以将过滤器应用于任何资源,只要该资源的URL与URL模式匹配。过滤是按照部署描述符的filter-mapping元素出现的顺序执行的。

    filter-mapping元素的两个主要子元素filter-name和url-pattern用来定义Filter对应的URL。还有servlet-name和dispatcher子元素,不是很常用。

    特别说明一下dispatcher,设置Filter对应的请求方式,有:REQUEST,INCLUDE,FORWAR,ERROR四种,默认为REQUEST。

    例如:

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    <servlet>

    在web.xml中完成一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称,使用servlet-mapping元素将定制的URL与刚分配的名称相关联。

    例如:

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    

    <servlet-mapping>

    servlet-mapping元素包含两个子元素servlet-name和url-pattern,用来定义servlet所对应的URL。

    例如:

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

    <listener>

    listener元素用来注册一个监听器类,可以在web应用中包含该类。使用listener元素,可以收到事件什么时候发生以及用什么作为响应的通知。

    listener元素用来定义Listener接口,它的主要子元素为<listener-class>

    例如:

    <listener>
        <listener-class>com.gnd.web.listener.TestListener</listener-class>
    </listener>
    

    <session-config>

    session-config包含一个子元素session-timeout,定义web应用中session的有效期限。

    例如:

    <session-config>
        <session-timeout>900</session-timeout>
    </session-config>
    

    <mime-mapping>

    mime-mapping包含两个子元素extension和mime-type,定义某个扩展名和某一MIME Type做对应。

    <extension>扩展名名称</extension>

    <mime-type>MIME格式</mime-type>

    例如:

    <mime-mapping>
        <extension>doc</extension>
        <mime-type>application/vnd.ms-word</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>xls</extension>
        <mime-type>application/vnd.ms-excel</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>ppt</extension>
        <mime-type>application/vnd.ms-powerpoint</mime-type>
    </mime-mapping>
    
    

    <welcome-file-list>

    welcome-file-list包含一个子元素welcome-file,用来定义首页列表。

    welcome-file用来指定首页文件名称,服务器会按照设定的顺序来找首页。

    例如:

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    

    <error-page>

    error-page元素包含三个子元素error-code,exception-type和location。

    将错误代码后异常的种类对应到web应用资源路径。

    例如:

    <error-page>
        <error-code>404</error-code>
        <location>error404.jsp</location>
    </error-page>
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>error404.jsp</location>
    </error-page>
    

    <jsp-config>

    jsp-config元素主要用来设定jsp的相关配置,jsp-config包括taglib和jsp-property-group两个子元素,其中taglib元素在JSP1.2时就已经存在,而jsp-property-group是JSP2.0新增的元素。

    <taglib>

    taglib元素包含两个子元素taglib-uri和taglib-location,用来设定JSP网页用到的TagLibrary路径。

    <taglib-uri>URI</taglib-uri>

    taglib-uri定义TLD文件的URI,JSP网页的taglib指令可以经由这个URI存取到TLD文件。

    <taglib-location>/WEB-INF/lib/xxx.tld</taglib-location>

    TLD文件对应web应用的存放位置。

    <jsp-property-group>

    jsp-property-group元素包含8个子元素,分别为:

    <description>Description</description> 此设定的说明

    <display-name>Name</display-name> 此设定的名称

    <url-pattern>URL</url-pattern> 设定值所影响的范围,如*.jsp

    <el-ignored>true/false</el-ignored> 是否支持EL语法

    <scripting-invalid>true/false</scripting-invalid> 是否支持java代码片段<%...%>

    <page-encoding>UTF-8</page-encoding> 设置JSP页面的编码

    <include-prelude>.jspf</include-prelude> 设置JSP页面的抬头,扩展名为.jspf

    <include-coda>.jspf</include-coda> 设置JSP页面的结尾,扩展名为.jspf

    例如:

    <jsp-config>
            <taglib>
                <taglib-uri>Taglib</taglib-uri>
                <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
            </taglib>
            <jsp-property-group>
                <description>Configuration JSP example</description>
                <display-name>JspConfig</display-name>
                <url-pattern>/*</url-pattern>
                <el-ignored>true</el-ignored>
                <page-encoding>UTF-8</page-encoding>
                <scripting-invalid>true</scripting-invalid>
            </jsp-property-group>
        </jsp-config>
    

    <resource-ref>

    resource-ref元素包含五个子元素description,res-ref-name,res-type,res-auth,res-sharing-scope,利用JNDI取得应用可利用资源。

    <res-auth>Application/Container</res-auth> 资源由Application或Container来许可。

    <res-sharing-scope/>Shareable|Unshareable<res-sharing-scope/> 资源是否可以共享,默认值为Shareable

    例如:

    <resource-ref>
            <res-ref-name>jdbc/Druid</res-ref-name>
            <res-type>com.alibaba.druid.pool.DruidDataSource</res-type>
            <res-auth>Container</res-auth>
        </resource-ref>
    

    1.7 loggin.properties

    JULI记录器使用默认日志配置,它默认地使用ConsoleHandler和fileHandler设置应用程序或者程序包的日志级别。

    2. 启动流程分析

    2.1 Idea调试Tomcat源码环境搭建

    首先下载Tomcat源码,读者可自行去Tomcat官网 下载,若执行力差的同学也可直接从此处pull。

    Tomcat源码导入到开发工具中的方法有多种,笔者采用最直接的方式,解压源码包后直接导入到开发工具中,导入之后的源码并不能直接运行,还需要几个依赖包,读者可从此处的lib目录下获取,也可自行搜集。

    找好依赖包也并不能让Tomcat源码正常运行,还需要为Bootstrap这个启动类增加几个启动参数。

    -Dcatalina.home=/Users/chenmin/GitHub/tomcat
    -Dcatalina.base=/Users/chenmin/GitHub/tomcat
    -Djava.endorsed.dirs=/Users/chenmin/GitHub/tomcat/endorsed
    -Djava.io.tmpdir=/Users/chenmin/GitHub/tomcat/temp
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
    -Djava.util.logging.config.file=/Users/chenmin/GitHub/tomcat/conf/logging.properties
    

    上面的参数具体代表的意思就不一一详述了,其实光看名字就知道都是干嘛用的了。

    以上准备步骤做好之后,就可以直接运行Bootstrap类,运行Tomcat源码进行调试了。

    2.2 Tomcat Server的组成

    2.2.1 整体说明

    在上面对配置文件的说明中,通过server.xml的解释,我们知道server.xml中最顶级的元素是server,而server.xml中的每一个元素我们都可以把它看做是Tomcat中的某一个部分。所以我们可以参照着server.xml来分析源码。

    Tomcat最顶层的容器叫Server,它代表着整个Tomcat服务器。Server中至少要包含一个Service来提供服务。Service包含两部分:Connector和Container。Connector负责网络连接,request/response的创建,并对Socket和request、response进行转换等,Container用于封装和管理Servlet,并处理具体的request请求。

    一个Tomcat中只有一个Server,一个Server可以有多个Service来提供服务,一个Service只有一个Container,但是可以有多个Connector(一个服务可以有多个连接)。

    [图片上传失败...(image-e1071d-1545114777128)]

    2.2.2 各组件详解

    可结合conf/配置文件说明中的server.xml的说明来看

    • Server

      Server代表整个Servlet容器

    • Service

      Service是由一个或多个Connector以及一个Engine,负责处理所有Connector所获得的客户请求的集合。

    • Connector

      Connector将在某个指定端口上侦听客户请求,并将获得的请求交给Engine来处理,从Engine处获得回应并返回给客户端。

      Tomcat有两个默认的Connector,一个直接监听来自浏览器的http请求,一个监听来自其他WebServer的请求。

      Coyote Http/1.1 Connector在端口8080上监听来自浏览器的http请求

      Coyote AJP/1.3 Connector在端口8009上监听来自其他WebServer的servlet/jsp代理请求。

    • Engine

      Engine下可以配置多个虚拟主机,每个虚拟主机都有一个域名,当Engine获得一个请求时,Engine会把该请求匹配到某个Host上,然后把该请求交给该Host来处理。

      Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理。

    • Host

      代表一个虚拟主机,每个虚拟主机和某个网络域名相匹配。每个虚拟主机下都可以部署一个或者多个WebApp,每个WebApp对应于一个Context,有一个ContextPath。当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理。匹配的方法是“最长匹配”,所以一个path==“”的Context将成为该Host的默认Context,所有无法和其他Context的路径名匹配的请求都将最终和该默认Context匹配。

    • Context

      一个Context对应于一个Web Application(Web应用),一个Web应用有一个或多个Servlet组成,Context在创建的时候将根据配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servlet类。如果找到,则执行该类,获得请求的回应,并返回。

      Tomcat各组件关系图(此图来此网上)

      [图片上传失败...(image-41dc76-1545114777128)]

    相关文章

      网友评论

        本文标题:Tomcat架构介绍及配置分析

        本文链接:https://www.haomeiwen.com/subject/kdqlkqtx.html