Tomcat03 - Tomcatのアーキテクチャ

1. HTTP作品

        HTTPプロトコルは、ブラウザとサーバ間のデータ転送プロトコルは、アプリケーション層のプロトコルとして、あるは、httpは(HTMLファイル、画像、その結果、など)パケットを含まない(パッケージHTTPプロトコルの下でTCP / IPプロトコルのデータに基づいて渡す​​ことです)送信、クライアントとサーバとの間で所定のメイン通信フォーマット。

図要求手順:

1.ユーザーがブラウザにURLを入力すると、ブラウザがイベントを取得し、

2.ブラウザは、サーバへのTCP接続要求を送信します

3.サービスプログラムは、ブラウザの要求を受け入れ、TCP 3ウェイハンドシェイクを介して接続を確立し

4.ブラウザは、HTTPプロトコルパケットにパッケージデータを要求します

ブラウザは、最終的にパケットネットワーク、ネットワークを介してデータパケットの送信、サーバプッシュ

パケット、同じHTTPプロトコルアンパック形式、クライアントの意図へのアクセスを取得するには、サーバーの後6

7.静的なファイルを提供するものとして、または動的なリソースを取得するためにサーバプログラムを呼び出すことにより、処理、クライアントの意図を学習した後

プロトコル形式は、パッケージHTTPに従って8.サーバの応答結果(HTML、画像、等)

9.サーバ応答データ・パケット押さネットワーク、ネットワークブラウザを介して、最終的なパケットの送信

前記データパケットはデータが想定されるHTTPプロトコルフォーマットアンパッカブラウザ、および分析データを取得した後HTML

11. HTMLファイルブラウザがページに表示されます

図から分かるように、接続を受け入れるためのプライマリサーバは、データ要求を解析し、これらのステップを処理する応答要求を送信します。

2. Tomcatの全体的なアーキテクチャ

2.1 HTTPリクエスト処理サーバ

        ブラウザは、サーバー形式にHTTPリクエストを送信するHTTPサーバは要求を受信し、我々はJavaのコードを書くことは、いわゆるサーバープログラムに対処するためのサーバプログラムを呼び出し、一般的に、異なる要求が異なるが必要ですハンドルへのJavaクラス。

        HTTPサーバーのトラフィッククラスが直接呼び出すことはありませんが、処理容器への要求は、サーブレットインターフェースの通話トラフィッククラスを介して容器なので、そこにサーブレットコンテナサーブレット・インタフェースとは、HTTPサーバの目的と切り離さトラフィッククラスを実現します。

        このサーブレットコンテナサーブレット・インタフェースとサーブレット仕様と呼ばれる仕様のセット。サーブレットコンテナを達成するために必要としてTomcat Servlet仕様は、彼らはまた、HTTPサーバの機能を持っています。私たちは、新たなビジネス機能を実現するためであればJavaプログラマとして、唯一のサーブレットを実装する、とTomcat(サーブレットコンテナ)、それはTomcatが処理されるものの残りの部分にそれを登録する必要があります。

図:

ワークフロー2.2サーブレットコンテナ

        切り離すためには、HTTPサーバーがサーブレットを呼び出すことはありませんが、Servletコンテナによって処理、聞かせてのは、ワークフローのサーブレットコンテナを見て種類かのです。

        クライアントは、顧客の要求情報をカプセル化し、サービスメソッドのサーブレットコンテナを呼び出すためのServletRequestオブジェクトとリソース、HTTPサーバーを要求すると、サーブレットコンテナは、適切なを見つけるためのマッピングURL要求とサーブレットによると、リクエストの後に取得しますサーブレットがロードされていない場合、サーブレットは、このサーブレットの反射によって作成され、初期化サーブレットを完了するために、サーブレットのinitメソッドを呼び出し、その要求を処理するサーブレットのサービスメソッドを呼び出している、たServletResponseオブジェクトはHTTPサーバに返され、HTTPサーバ応答がクライアントに送信されます。

図:

2.3 Tomcatの全体的なアーキテクチャ

Tomcatは、2つのコア機能を達成するために:

1.ソケット接続処理、およびバイトストリームオブジェクト要求と応答ネットワークの変換のために責任があります。

2.負荷管理とサーブレット、および特定の処理要求の要求。

Tomcatのは、このように2つのことを行うために、それぞれ2つのコアアセンブリのコネクタ(コネクタ)とコンテナ(コンテナ)を設計しました。コネクタは、コンテナが内部処理を担当し、外国為替を担当しています。

図:

3.コネクタ - コヨーテ

3.1はじめアーキテクチャ

        コヨーテは、Tomcatサーバーがサーバーにリクエストを送信することにより、接続を確立し、応答コヨーテを受信するクライアントのための外部インターフェース、クライアントアクセスによって提供され、コネクタフレームのTomcatの名前です。

        Coyote封装了底层的网络通信(Socket请求及响应处理),为Catalina容器提供了统一的接口,使Catalina容器与具体的请求协议及IO操作方式完全解耦。Coyote将Socket输入转换封装为Request对象,交由Catalina容器进行处理,处理请求完成之后,Catalina通过Coyote提供的Response对象将结果写入输出流。

        Coyote作为独立的模块,只负责具体协议及IO的相关操作,与Servlet规范实现没有直接关系,因此即便是Request和Response对象也并没有实现Servlet规范对应的接口,而是Catalina中将他们进一步封装为ServletRequest和ServletResponse。

如图:

3.2 IO模型与协议

        在Coyote中,Tomcat支持的多种I/O模型和应用层协议,具体包含哪些IO模型和应用层协议,如下表所示:

Tomcat支持的IO模型(自8.5/9.0版本起,Tomcat移除了对BIO的支持)

IO模型 描述
NIO 非阻塞I/O,采用Java NIO类库实现
NIO2 异步I/O,采用JDK 7最新的NIO2类库实现
APR 采用Apache可移植运行库实现,是C/C++编写的本地库,如果选择该方案,需要单独安装APR库

Tomcat支持的应用层协议:

应用层协议 描述
HTTP/1.1 这是大部分WEB应用访问的协议
AJP 用于和WEB服务器集成(如:Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3
HTTP/2 HTTP 2.0大幅度的提升了Web性能,下一代的HTTP协议,自8.5以及9.0之后开始支持

协议分层:

应用层 HTTP AJP(Processor) HTTP 2
传输层 NIO NIO2(Endpoint) APR

        在8.0 之前,Tomcat默认采用的I/O方式为BIO,之后改成了NIO,无论是NIO、NIO2还是APR,在性能方面都要优于BIO,如果采用APR,甚至可以达到Apache HTTP Server 的影响性能。

        Tomcat为了实现支持多种I/O模型和应用层协议,一个容器可以对接多个连接器,但是单独的连接器或者容器都不能对外提供服务,需要把他们组装起来才能工作,组装后的这个操作叫做Service组件。值得注意的是,Service本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把他们组装在一起,Tomcat内可能有多个Service,这样的设计也是出于灵活性的考虑,通过在Tomcat中配置多个Service,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

3.3 连接组件

如图:

3.3.1 EndPoint

        Coyote通信端点,即通信监听的接口,是具体的Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议。

        Tomcat并没有EndPoint接口,而是提供了一个抽象类AbstractEndpoint,里面定义了两个内部类:Acceptor和SocketProcessor。

1. Acceptor 用于监听Socket连接请求。

2. SocketProcessor 用于处理接收到的Socket请求,它实现了Runnable接口,在run方法中调用协议处理组件processor进行处理。为了提高处理能力,socketProcessor被提交到线程池来执行,而这个线程池叫做执行器(Executor)。

3.3.2 Processor

        Coyote处理协议的接口,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,其接收来自EndPoint的Socket,读取字节流,解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象。

3.3.3 ProtocolHandler

        Coyote协议接口,通过Endpoint和Processor实现针对具体协议的处理能力。Tomcat按照协议和I/O提供了6个实现类:

AjpNioProtocol、AjpAprProtocol、AjpNio2Protocol、Http11NioProtocol、Http11Nio2Protocol、Http11AprProtocol。

        我们在配置tomcat/conf/server.xml时,至少要指定具体的ProtocolHandler,当然也可以指定协议名称,例如:HTTP/1.1,如果安装了APR,那么将使用Http11AprProtocol,否则使用Http11NioProtocol。

3.3.4 Adaptor

        由于协议的不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来存放请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类,但是这个Request对象不是标准的ServletRequest,也就意味着不能用Tomcat Request作为参数调用容器。

        Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典应用,连接器调用CoyoteAdapter的Service方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request对象转成ServletRequest,在调用容器的Service方法。

4. Tomcat服务器配置

        tomcat服务器的配置主要集中于tomcat/conf下的catalina.policy、catalina.properties、context.xml、server.xml、tomcat-users.xml、web.xml文件。

4.1 server.xml

       是tomcat服务器的核心配置文件,包含了Tomcat的Servlet容器(Catalina)的所有配置。

如下所示,为下载之后的原版配置文件

<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- 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 port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <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 name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <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/TLS HTTP/1.1 Connector on port 8080
    -->
    <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/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation that requires the JSSE
         style configuration. When using the APR/native implementation, the
         OpenSSL style configuration is required as described in the APR/native
         documentation -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <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">
    -->
    <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) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- 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.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

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

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

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <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>

4.1.1 Server

        是server.xml的根元素,用于创建一个Server实例,默认使用的实现类是 org.apache.catalina.core.StandardServer。

<Server port="8005" shutdown="SHUTDOWN">
</Server>

port:tomcat监听的关闭服务器端口。

shutdown:关闭服务器的指令字符串。

Server内嵌的子元素为Listener、GlobalNamingResources、Service

1. Listener

默认配置的5个Listener的含义:

<!-- 用于以日志形式输出服务器、操作系统、JVM版本信息 -->
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  
  <!-- 用于加载(服务器启动)和销毁(服务器停止)APR。如果找不到APR类,则会输出日志,并不影响Tomcat启动 -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  
  <!-- 用于避免JRE内存泄漏问题 -->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  
  <!-- 用于加载(服务器启动)和销毁(服务器停止)全局命名服务 -->
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  
  <!-- 用于在Context停止时重建Executor池中的线程,以避免ThreadLocal相关的内存泄漏 -->
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

2. GlobalNamingResources

        <GlobalNamingResources>.中定义了全局命名资源

3. Service

        <Service>标签用于创建Service实例,默认使用的是org.apache.catalina.core.StandardService,默认情况下,Tomcat仅指定了Service的名称,值为“ Catalina ”。

        Service可以内嵌的元素有:Listener、Executor、Connector、Engine

3.1 Listener

        用于为Servlet添加生命周期监听器。

3.2 Executor

        用于配置Service共享线程池

3.3 Connector

        用于配置Service包含的链接器

3.4 Engine

        用于配置Service中链接器对应的Servlet容器引擎

<Service name="Catalina">
</Service >

一个Server服务器,可以包含多个Service。

5. Tomcat的启动流程

5.1 流程

 

步骤,如图:

1. 启动tomcat,需要调用bin/startup.bat,在startup.bat脚本中,调用了catalina.bat

2. 在catalina.bat脚本文件中,调用了BootStrap中的main方法

3. 在BootStrap的main方法中调用了init方法,来创建Catalina及初始化类加载器

4. 在BootStrap的main方法中调用load方法,在其中又调用了Catalina的load方法

5. 在Catalina的load方法中,需要进一步初始化的工作,并需要构造Digester对象,用于解析XML

6. 然后调用后续组件的初始化工作。

一句话来描述就,加载tomcat的配置文件,初始化容器组件,监听对应的端口号,准备接受客户端的请求。

5.2 源码解析

5.2.1 Lifecycle接口

        由于所有的组件均存在初始化,启动,停止等生命周期管理的特性,所以Tomcat在设计的时候,基于生命周期管理抽象成了一个接口Lifecycle,而组件Server、Service、Container、Executor、Connector组件,都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法

1. init():初始化组件

2. start():启动组件

3. stop():停止组件

4. destroy():销毁组件

如图:

5.1.2  各组件的默认实现

        像Server、Service、Engine、Host、Context都是接口,所以,tomcat一定对这些接口有对应的实现类。

        当前对于组件Endpoint来说,在tomcat中没有对应的Endpoint接口,但是有一个抽象类AbstractEndpoint,其下有三个实现类:NioEndpoint、Nio2Endpoint、AprEndpoint,这三个实现类,分别对应于连接器Coyote的三种IO模型:NIO、NIO2、APR,在tomcat8.5版本中默认采用的是NioEndpoint。
如图:

下面罗列一下各个接口的默认实现类:

Server——>StandardServer

Service——>StandardService

Engine——>StandardEngine

Host——>StandardHost

Context——>StandardContext

另外还有一个比较重要的接口是ProtocolHandler,它是Coyote协议接口,通过封装Endpoint和Processor,实现针对具体协议的处理能力。tomcat按照协议和IO提供了6个实现类:

AJP协议:

AjpNioProtocol 采用NIO的IO模型
AjpNio2Protocol 采用NIO2的IO模型
AjpAprProtocol 采用APR的IO模型,需要依赖APR库

在Server.xml中的配置如下:

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

 HTTP协议:

Http11NioProtocol 采用NIO的IO模型,默认使用的协议(如果服务器没有安装APR)
Http11Nio2Protocol 采用NIO2的IO模型
Http11AprProtocol 采用APR的IO模型,需要依赖与APR库

 在Server.xml中配置如下:

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

如图:

 

发布了128 篇原创文章 · 获赞 6 · 访问量 3222

おすすめ

転載: blog.csdn.net/weixin_43318134/article/details/103915555