tomcat学习笔记系统架构和原理

Posted 拐柒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tomcat学习笔记系统架构和原理相关的知识,希望对你有一定的参考价值。

Tomcat

b/s(浏览器/服务器模式) 浏览器是客户端(发送http请求)

浏览器访问服务器的流程

http请求只是定义了数据的组织格式(通信格式),是一个应用层协议,数据传输依靠的是TCP/IP协议。
1、用户输入url地址,然后出发访问,或者是搜索框输入关键词进行搜索。
2、浏览器发起TCP连接请求(三次握手)
3、服务器接受请求建立连接
4、浏览器生成HTTP格式的数据包
5、通过TPC/IP发送请求数据包
6、服务器解析HTTP格式数据包
7、服务器执行请求
8、服务器生成HTTP格式的数据包
9、服务器通过TPC/IP发送响应数据包给浏览器
10、浏览器解析HTTP格式的数据包
11、浏览器呈现静态数据给用户,静态数据(html/js/图片)

tomcat请求处理大致过程

tomcat是一个http服务器,能够接受并且处理http请求
如果tomcat直接调用业务处理类完成业务处理的话,那么tomcat便和我们的java类耦合在一起了。tomcat显然不是这么做的。
HTTP服务器接受到请求之后,吧请求交给Servlet容器来处理,servlet容器通过servlet接口调用业务类。servlet接口和servlet容器一套内容被称作servlet规范

tomcat既按照servlet规范的要求去实现了servlet容器规范,同时也是一个HTTP服务器。
1、HTTP服务器会把请求信息使用ServletRequest对象封装起来
2、进一步调用servlet容器中的某个具体的servlet
3、根据url和servlet的映射关系,找到相应的servlet
4、如果servlet还没有被加载,就用反射机制创建这个servlet,并调用servlet的init方法来完成初始化
5、接着调用这个具体的servlet的servcie方法来处理请求,请求处理结果使用servletResponse对象封装
6、把servletResponse对象返回给HTTP服务器,HTTP服务器会把相应发送给客户端

tomcat系统总体架构

通过上述,tomcat有两个非常重要的功能需要完成
1、要和客户端浏览器进行交互进行socket通信,将字节流和request/response对象进行转换。
2、servlet处理业务逻辑

tomcat有两个重要组件,一个是Connector连接器组件,一个是Container容器组件。
连接器:和客户交互(socket通信),对应角色是http服务器功能
容器组件:处理业务逻辑(对应角色:servlet容器)

coyote 连接器组件

1、coyote封装了底层的网络通信(socket请求及相应处理)
2、coyote是catalina容器(容器组件)与具体的请求协议及io操作方式的完全解耦
3、coyote将socket输入转换封装为Request对象,进一步封装后交友catalina容器进行处理,处理请求完成后,catalina通过coyote提供的response对象将结果写入输出流
4、coyote负责的具体协议(应用层)和io相关内容

应用层默认协议是HTTP/1.1,传输层默认的io模型是NIO

coyote内部组件和工作流程

EndPoint:通信端点,即终端,通信监听的接口,是具体socket接受和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的
Processor 是协议处理接口,应用协议解析处理,processor接受来自EndPoint的socket,读取字节流解析成tomcat Request和Response对象,并通过Adapter将其提交到容器处理,processor是应用层协议的抽象。
Adapter:由于协议不同,客户端发过来的请求信息也不尽相同,tomcat定义了自己的request类,但是这个对象不是标准的servletrequest,不能用tomcatrequest作为参数来调用容器,引入coyoteAdapter,这是适配器模式的经典应用,连接器嗲用coyoteAdapter的service方法,传入的是tomcat request对象,coyoteAdapter将tomcat request对象转换为servletRequest,在调用容器。

servlet容器Catalina

tomcat是一个由一系列可配置(conf/server.xml)的举荐构成的web容器,而catalina是tomcat的servlet容器
从另一个角度来说,tomcat本质上就是一个servlet容器,因为catalina才是tomcat的核心,其他模块都是为Catalina提供支撑的。
tomcat往往我们认为是Catalina的一个实例。
Catalina实例通过加载server.xml完成其他实例的创建,创建并管理一个server,server创建并管理多个服务,每个服务又可以有多个connector和一个container。
**catalina:**负责解析tomcat配置文件,一次来创建服务器server组件并进行管理
**server:**服务器标识整个catalina servlet容器以及其他组件,负责组装启动servlet引擎,tomcat连接器,server通过实现lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式
**service:**服务是server内部的组件,一个server包含多个service,他讲若干个connector组件绑定到了一个contaner
**container:**容器,负责处理用户的servlet请求,并返回对象给web用户的模块

tomcat核心配置文件server.xml

<?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实例,子标签有listner和service、GlobalNamingResources -->
 <!-- 监听8005端口执行关闭 -->
<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,子标签:listener,excutor,connector,engine -->
  <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"/>
    -->
<!-- 默认情况下,Service 并未添加共享线程池配置。 如果我们想添加⼀个线程池, 可以在 -->
<!-- <Service> 下添加如下配置: -->
<!-- name:线程池名称,⽤于 Connector中指定 -->
<!-- namePrefix:所创建的每个线程的名称前缀,⼀个单独的线程名称为 -->
<!-- namePrefix+threadNumber -->
<!-- maxThreads:池中最⼤线程数 -->
<!-- minSpareThreads:活跃线程数,也就是核⼼池线程数,这些线程不会被销毁,会⼀直存在 -->
<!-- maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位 -->
<!-- 毫秒 -->
<!-- maxQueueSize:在被执⾏前最⼤线程排队数⽬,默认为Int的最⼤值,也就是⼴义的⽆限。除⾮特 -->
<!-- 殊情况,这个值 不需要更改,否则会有请求不会被处理的情况发⽣ -->
<!-- prestartminSpareThreads:启动线程池时是否启动 minSpareThreads部分线程。默认值为 -->
<!-- false,即不启动 -->
<!-- threadPriority:线程池中线程优先级,默认值为5,值从1到10 -->
<!-- className:线程池实现类,未指定情况下,默认实现类为  -->
<!-- org.apache.catalina.core.StandardThreadExecutor。如果想使⽤⾃定义线程池⾸先需要实现 -->
<!-- org.apache.catalina.Executor接⼝ -->
	<Executor name="commonThreadPool"
	 namePrefix="thread-exec-"
	 maxThreads="200"
	 minSpareThreads="100"
	 maxIdleTime="60000"
	 maxQueueSize="Integer.MAX_VALUE"
	 prestartminSpareThreads="false"
	 threadPriority="5"
	 className="org.apache.catalina.core.StandardThreadExecutor"/>

    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         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,端口8080,请求协议,连接超时,重定向端口 -->
	
	<!--
port:
 端⼝号,Connector ⽤于创建服务端Socket 并进⾏监听, 以等待客户端请求链接。如果该属性设置
为0, Tomcat将会随机选择⼀个可⽤的端⼝号给当前Connector 使⽤
protocol:
 当前Connector ⽀持的访问协议。 默认为 HTTP/1.1 , 并采⽤⾃动切换机制选择⼀个基于 JAVA
NIO 的链接器或者基于本地APR的链接器(根据本地是否含有Tomcat的本地库判定)
connectionTimeOut:
Connector 接收链接后的等待超时时间, 单位为 毫秒。 -1 表示不超时。
redirectPort:
 当前Connector 不⽀持SSL请求, 接收到了⼀个请求, 并且也符合security-constraint 约束,
需要SSL传输,Catalina⾃动将请求重定向到指定的端⼝。
executor:
 指定共享线程池的名称, 也可以通过maxThreads、minSpareThreads 等属性配置内部线程池。
URIEncoding:
 ⽤于指定编码URI的字符编码, Tomcat8.x版本默认的编码为 UTF-8 , Tomcat7.x版本默认为ISO-
8859-1
-->
<!--org.apache.coyote.http11.Http11NioProtocol , ⾮阻塞式 Java NIO 链接器-->
    <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 an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
	<!-- 处理ajp协议 -->
    <!-- <Connector protocol="AJP/1.3" -->
               <!-- address="::1" -->
               <!-- port="8009" -->
               <!-- 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">
    -->
	<!--
	name: 用于指定Engine 的名称, 默认为Catalina
	defaultHost:默认使⽤的虚拟主机名称, 当客户端请求指向的主机⽆效时, 将交由默认的虚拟主机处
	理, 默认为localhost
	-->
    <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="www.abc.com"  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" />
        -->
<!--
 docBase:Web应⽤⽬录或者War包的部署路径。可以是绝对路径,也可以是相对于 Host appBase的
相对路径。
 path:Web应⽤的Context 路径。如果我们Host名为localhost, 则该web应⽤访问的根路径为: 
 http://localhost:8080/web_demo。
-->
		<Context docBase="D:\\ChromeCoreDownloads\\ROOT" path="/root"></Context>

        <!-- 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>
	  
	  
	  <Host name="www.def.com"  appBase="webapps2"
            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>

以上是关于tomcat学习笔记系统架构和原理的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat核心原理--学习笔记

Tomcat核心原理--学习笔记

Tomcat核心原理--学习笔记

Tomcat 架构原理解析到架构设计借鉴

好文!!!Tomcat 架构原理探秘

架构学习笔记:淘宝的 14 次架构演进之路