tomcat源码解读——启动过程分析

M君 6月前 ⋅ 224 阅读

在上一篇文章中介绍了idea中tomcat源码调试环境的搭建,调试环境搭建完成之后首先配置tomcat的启动信息,配置信息如下(具体配置步骤参考源码中的README文件) 配置好了tomcat的启动信息之后,就可以开始从源码启动并调试tomcat了,在深入到tomcat的源码之前,为了对tomcat有一个更加直观的了解,可以首先分析一下tomcat的配置文件和启动的过程。

1、tomcat配置信息

<?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">
  <!-- 注册到服务容器中的监听器,下面是tomcat自己的监听器,也可以注册自定义的监听器 -->
  <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
   -->
<!-- 服务配置(一个server可以包含多个service)-->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!-- 用于配置连接器可以使用的线程池,可以使用tomcat本身的线程池,也可以使用自定义的线程池,关于为什么需要配置该线程池,没有服务器开发经验的开发者可能不太理解,也没有相关的文章介绍,可以通过了解netty的线程模型了解为什么连接器需要线程池)
    <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
         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
    -->
    <-- 连接器封装了ServerSocket用于接受客户端连接,protocol代表了该连接能处理的协议的类型,由于tomcat是http服务器,所以封装了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/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.
    -->
    <!-- https连接器配置,https本质上是tcp协议上进行了数据的加密与解密,首先通过非对称加密方式交换随机生成的对称秘钥,后续的数据传输都使用对称秘钥加密传输,详情可以在网络上搜索一下https的交互过程
    <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 a 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 -->
    <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是tomcat服务器上的总的servlet容器,包含了所有虚拟机主机的信息,通过Engine可以对tomcat上的所有的请求信息进行拦截处理 -->
    <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"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <!-- 请求认证拦截器(和应用层的拦截器原理一样,只是这种拦截器是只被tomcat内部使用的) -->
      <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>
      <!-- 虚拟机主机的配置信息:name主机的域名信息,appBase应用的根路径... -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <!-- valve是host的拦截器 -->
        <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>

2、tomcat启动

 tomcat启动信息 在我们平常使用tomcat的时候,在tomcat启动的时候会输出很多信息,但是却很少去关注具体输出的内容的意义,其实通过分析该输出内容可以了解tomcat启动的过程中具体做了些什么样的事情,下面就对tomcat其中过程中的输出内容进行分析来了解tomcat的启动过程。

(1)、加载tomcat公共的lib包
四月 22, 2018 12:39:51 下午 org.apache.catalina.startup.ClassLoaderFactory validateFile
警告: Problem with directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\lib], exists: [false], isDirectory: [false], canRead: [false]
四月 22, 2018 12:39:51 下午 org.apache.catalina.startup.ClassLoaderFactory validateFile
警告: Problem with directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\lib], exists: [false], isDirectory: [false], canRead: [false]
四月 22, 2018 12:39:51 下午 org.apache.catalina.startup.ClassLoaderFactory validateFile
警告: Problem with directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\lib], exists: [false], isDirectory: [false], canRead: [false]
四月 22, 2018 12:39:51 下午 org.apache.catalina.startup.ClassLoaderFactory validateFile
警告: Problem with directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\lib], exists: [false], isDirectory: [false], canRead: [false]

2、打印服务器配置信息:jvm信息宿主机信息,tomcat版本信息
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server version: Apache Tomcat/@VERSION@
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server built: @VERSION_BUILT@
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server number: @VERSION_NUMBER@
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: OS Name: Windows 8.1
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: OS Version: 6.3
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Architecture: amd64
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Java Home: C:\Program Files\Java\jdk1.8.0\jre
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: JVM Version: 1.8.0-b132
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: JVM Vendor: Oracle Corporation
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log

3、打印tomcat的参数配置信息
信息: CATALINA_BASE: D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: CATALINA_HOME: D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:55615,suspend=y,server=n
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dcatalina.home=D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -javaagent:C:\Users\muhong\.IntelliJIdea2017.3\system\captureAgent\debugger-agent.jar=C:\Users\muhong\AppData\Local\Temp\capture.props
四月 22, 2018 12:45:01 下午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dfile.encoding=UTF-8
四月 22, 2018 12:45:01 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent

4、打印Apr异常检测信息
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files (x86)\Lenovo\FusionEngine;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Lenovo\Bluetooth Software\;C:\Program Files\Lenovo\Bluetooth Software\syswow64;C:\Program Files (x86)\Common Files\lenovo\easyplussdk\bin;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;D:\Software\Tortoise\bin;D:\Software\nodejs\;D:\Software\python;D:\Software\apache-ant-1.8.0-bin\apache-ant-1.8.0\bin;C:\Program Files\Java\jdk1.8.0\bin;C:\Program Files\Java\jdk1.8.0\jre\bin;C:\Program Files (x86)\IDM Computer Solutions\UltraCompare\;D:\Software\NASM\;D:\Software\ultraEdit\;D:\Software\maven3.3.9\apache-maven-3.3.9\bin;D:\Software\gradle-2.2.1\bin;D:\Software\Tortoise\\bin;C:\Users\muhong\AppData\Local\Microsoft\WindowsApps;;D:\Software\MicrosoftVSCode\bin;C:\Users\muhong\AppData\Roaming\npm;.]

5、初始化连接器和协议解析器
四月 22, 2018 12:45:04 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8080"]
四月 22, 2018 12:45:04 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
四月 22, 2018 12:45:05 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-nio-8009"]
四月 22, 2018 12:45:05 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
四月 22, 2018 12:45:05 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 11787 ms

6、初始化tomcat的服务信息
四月 22, 2018 12:47:39 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service [Catalina]
四月 22, 2018 12:47:56 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/@VERSION@
四月 22, 2018 12:48:16 下午 org.apache.catalina.startup.HostConfig deployDirectory

7、部署tomcat应用
信息: Deploying web application directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\webapps\mh]
四月 22, 2018 12:50:26 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [514] milliseconds.
四月 22, 2018 12:50:26 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory [D:\Program Files\JetBrains\IntelliJ IDEA 2017.3.4\workspace\mh\tomcat\catalina-home\webapps\mh] has finished in [130,033] ms

8、启动连接器和协议解析器
四月 22, 2018 12:51:27 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
四月 22, 2018 12:51:52 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-nio-8009"]
四月 22, 2018 12:52:11 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 382149 ms

 

到目前为止已经对tomcat的启动过程和相关配置信息有了基本的了解,后续会针对tomcat的每一个启动过程结合tomcat的源码进行分析。


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: