zoukankan      html  css  js  c++  java
  • Tomcat结构及类加载机制

    一、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.JasperListener" />
      <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>
          <!--webapps对应着文件夹webapps项目部署-->       
    <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.xml图示

    server.xml模型图:

      Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。
     
      Service主要包含两个部分:多个Connector和一个Container。一个Container可以有多个Host(虚拟主机),一个Host可以有多个Context。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下:
      1、Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化;
      2、Container用于封装和管理Servlet,以及具体处理Request请求
     
      一个Service只有一个Container,但是可以有多个Connectors。因为一个服务可以有多个连接,如同时提供Http和Https链接,也可以提供向相同协议不同端口的连接。

    Tomcat架构小结(面试回答这个):
      [1]每一个tomcat都只有一个Server,表示整个服务环境。一个Server中可以有多个Service。Server就掌管着Service的死活。
      [2]Service是对外提供服务的,每一个Service中可以有多个Connector和一个Container(Engine)。
      [3]Connector主要用来接收请求,解析请求内容,封装request和response,然后将准备好的数据交给Container处理。
      [4]Container就是我们经常说的容器,里面可以有多个Host,一个Host表示一个虚拟主机。Container处理完请求之后会将响应内容返回给Connecter,再由Connecter响应客户端。
     
    面试进阶——Connector架构
      Connector的架构: Connector最底层使用的是Socket来进行连接的,Request和Response是按照HTTP协议来封装的,所以Connector同时需要实现TCP/IP协议和HTTP协议!
     

      [1] Connector中具体用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型(如 Http11Protocol使用普通的Socket来连接,Http11NioProtocol使用NioSocket连接)。

      [2] Endpoint用于处理底层Socket的网络连接,用来实现TCP/IP协议 。

        Acceptor:用于监听和接受请求。 

        Handler:请求的初步处理。并且调用Processor。 

        AsyncTimeout:检查异步的Request请求是否超时。

      [3] Processor用于将Endpoint接收到的Socket封装成Request,用来实现HTTP协议。

      [4] Adapter用于将Request交给Container进行具体处理,即将请求适配到Servlet容器。

    面试进阶——Container架构:  

      Container就是一个Engine。Container用于封装和管理Servlet,以及具体处理Request请求。

      [1] Engine:Container(容器/引擎),用来管理多个站点,一个Service最多只能有一个Engine.

      [2] Host: 虚拟主机,一个Container可以有多个虚拟主机。

      [3] Context: 一个应用程序,就是我们平时开发的一个项目,或者说一套web引用程序。

      [4] Wrapper:  用来包装Servlet,每一个Wraper都包装着一个Servlet。

    二、类加载器流程

      JVM类加载机制:详情

        Tomcat类加载:

    JVM类加载机制

      Bootstrap 引导类加载器 :加载JVM启动所需的类,以及标准扩展类(位于jre/lib/ext下),将JVM前三个类加载器概括到一起了。

      System 系统类加载器 :加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下。

       Common 通用类加载器:加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar。

      webapp应用类加载器:每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 WEB-INF/lib下的jar文件中的class和 WEB-INF/classes下的class文件。

      JSP类加载器 :tomcat会为每一个JSP创建一个类加载器。

    加载流程

      1  使用bootstrap引导类加载器加载 JVM基本类和扩展类

      2  使用system系统类加载器加载 tomcat启动的类

      3  使用应用类加载器在WEB-INF/classes中加载

      4 使用应用类加载器在WEB-INF/lib中加载

      5 使用common类加载器在CATALINA_HOME/lib中加载

    问题1:为什么tomcat要给每个应用设置一个独立的类加载器

      一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一 个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。例如项目1使用spring5.0,项目2使用spring5.1,两项目具有相同的类,当项目1进行了加载之后,项目二如果发现类已经加载过了就不会再进行加载。

    问题2:为什么要给每个jsp文件设置一个独立的类加载器

      web容器要支持jsp的修改,我们知道,jsp文件最终也是要编译成class文件才能在虚拟机中运行,但程序运行后修改jsp已经是司空见惯的事情。 所以,web容器需要支持 jsp 修改后不用重启。

    问题3:tomcat是否违背了双亲委派模型

       是的,违背了。tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class 文件,不会传递给父类加载器。

  • 相关阅读:
    【1801視聴説2宿題】中国のリサイクル事情やごみの分別事情に対する意見
    【1701日本語新聞編集】第2回3月6日
    【1701新聞編集宿題】興味のあるネットニュース
    【1801日語写作】第2回:3月5日
    【1801日語听解4】第2回:3月3日
    【1801日本語新聞選読】第2回:3月3日
    不解压查看tar.gz包内文件
    设计模式——适配器模式
    ubuntu安装jre
    设计模式——抽象工厂模式
  • 原文地址:https://www.cnblogs.com/qmillet/p/12552336.html
Copyright © 2011-2022 走看看