Tomcat即是一个HTTP服务器,也是一个servlet容器,主要目的就是包装servlet,并对请求响应相应的servlet,纯servlet的web应用似乎很好理解Tomcat是如何装载servlet的,但,当使用一些MVC框架时,如spring MVC、strusts2,可能就找不出servlet在哪里?其实spring MVC框架就是一整个servlet,在web.xml中配置如下:

[html] view plaincopy
  1. <!-- Spring MVC servlet -->
  2. <servlet>
  3. <servlet-name>SpringMVC</servlet-name>
  4. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  5. <init-param>
  6. <param-name>contextConfigLocation</param-name>
  7. <param-value>classpath:spring-mvc.xml</param-value>
  8. </init-param>
  9. <load-on-startup>1</load-on-startup>
  10. <async-supported>true</async-supported>
  11. </servlet>
  12. <servlet-mapping>
  13. <servlet-name>SpringMVC</servlet-name>
  14. <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
  15. <url-pattern>/</url-pattern>
  16. </servlet-mapping>

而Struts2是基于过滤器的(过滤器也称作阀门,过滤器链相当于流水线),过滤器执行在调用servlet的service()方法之前。在web.xml的配置如下:

[html] view plaincopy
  1. <span style="font-family:Comic Sans MS;font-size:18px;"><filter>
  2. <filter-name>struts2</filter-name>
  3. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>struts2</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping></span>

他的总体结构用下图来表示。

通过上图我们可以看出Tomcat中主要涉及Server,Service,Engine,Connector,Host,Context组件,之前用过Tomcat的童鞋是不是觉得这些组件的名称有点似曾相识的赶脚,没赶脚?!您再想想。好吧,不用你想了,我来告诉你吧。其实在Tomcat二进制分发包解压后,在conf目录中有一个server.xml文件,你打开它瞄两眼看看,是不是发现server.xml文件中已经包含了上述的几个名称。

[html] view plaincopy
  1. <?xml version='1.0' encoding='utf-8'?>
  2. <!--
  3. Licensed to the Apache Software Foundation (ASF) under one or more
  4. contributor license agreements.  See the NOTICE file distributed with
  5. this work for additional information regarding copyright ownership.
  6. The ASF licenses this file to You under the Apache License, Version 2.0
  7. (the "License"); you may not use this file except in compliance with
  8. the License.  You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  10. Unless required by applicable law or agreed to in writing, software
  11. distributed under the License is distributed on an "AS IS" BASIS,
  12. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. See the License for the specific language governing permissions and
  14. limitations under the License.
  15. -->
  16. <!-- Note:  A "Server" is not itself a "Container", so you may not
  17. define subcomponents such as "Valves" at this level.
  18. Documentation at /docs/config/server.html
  19. -->
  20. <Server port="8005" shutdown="SHUTDOWN">
  21. <!-- Security listener. Documentation at /docs/config/listeners.html
  22. <Listener className="org.apache.catalina.security.SecurityListener" />
  23. -->
  24. <!--APR library loader. Documentation at /docs/apr.html -->
  25. <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  26. <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  27. <Listener className="org.apache.catalina.core.JasperListener" />
  28. <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  29. <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  30. <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  31. <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  32. <!-- Global JNDI resources
  33. Documentation at /docs/jndi-resources-howto.html
  34. -->
  35. <GlobalNamingResources>
  36. <!-- Editable user database that can also be used by
  37. UserDatabaseRealm to authenticate users
  38. -->
  39. <Resource name="UserDatabase" auth="Container"
  40. type="org.apache.catalina.UserDatabase"
  41. description="User database that can be updated and saved"
  42. factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
  43. pathname="conf/tomcat-users.xml" />
  44. </GlobalNamingResources>
  45. <!-- A "Service" is a collection of one or more "Connectors" that share
  46. a single "Container" Note:  A "Service" is not itself a "Container",
  47. so you may not define subcomponents such as "Valves" at this level.
  48. Documentation at /docs/config/service.html
  49. -->
  50. <Service name="Catalina">
  51. <!--The connectors can use a shared executor, you can define one or more named thread pools-->
  52. <!--
  53. <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
  54. maxThreads="150" minSpareThreads="4"/>
  55. -->
  56. <!-- A "Connector" represents an endpoint by which requests are received
  57. and responses are returned. Documentation at :
  58. Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
  59. Java AJP  Connector: /docs/config/ajp.html
  60. APR (HTTP/AJP) Connector: /docs/apr.html
  61. Define a non-SSL HTTP/1.1 Connector on port 8080
  62. -->
  63. <Connector port="8080" protocol="HTTP/1.1"
  64. connectionTimeout="20000"
  65. redirectPort="8443" />
  66. <!-- A "Connector" using the shared thread pool-->
  67. <!--
  68. <Connector executor="tomcatThreadPool"
  69. port="8080" protocol="HTTP/1.1"
  70. connectionTimeout="20000"
  71. redirectPort="8443" />
  72. -->
  73. <!-- Define a SSL HTTP/1.1 Connector on port 8443
  74. This connector uses the JSSE configuration, when using APR, the
  75. connector should be using the OpenSSL style configuration
  76. described in the APR documentation -->
  77. <!--
  78. <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
  79. maxThreads="150" scheme="https" secure="true"
  80. clientAuth="false" sslProtocol="TLS" />
  81. -->
  82. <!-- Define an AJP 1.3 Connector on port 8009 -->
  83. <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
  84. <!-- An Engine represents the entry point (within Catalina) that processes
  85. every request.  The Engine implementation for Tomcat stand alone
  86. analyzes the HTTP headers included with the request, and passes them
  87. on to the appropriate Host (virtual host).
  88. Documentation at /docs/config/engine.html -->
  89. <!-- You should set jvmRoute to support load-balancing via AJP ie :
  90. <Engine name="Catalina" defaultHost="192.168.1.50" jvmRoute="jvm1">
  91. -->
  92. <Engine name="Catalina" defaultHost="192.168.1.50">
  93. <!--For clustering, please take a look at documentation at:
  94. /docs/cluster-howto.html  (simple how to)
  95. /docs/config/cluster.html (reference documentation) -->
  96. <!--
  97. <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
  98. -->
  99. <!-- Use the LockOutRealm to prevent attempts to guess user passwords
  100. via a brute-force attack -->
  101. <Realm className="org.apache.catalina.realm.LockOutRealm">
  102. <!-- This Realm uses the UserDatabase configured in the global JNDI
  103. resources under the key "UserDatabase".  Any edits
  104. that are performed against this UserDatabase are immediately
  105. available for use by the Realm.  -->
  106. <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
  107. resourceName="UserDatabase"/>
  108. </Realm>
  109. <Host name="192.168.1.50"  appBase="webapps"
  110. unpackWARs="true" autoDeploy="true">
  111. <!-- SingleSignOn valve, share authentication between web applications
  112. Documentation at: /docs/config/valve.html -->
  113. <!--
  114. <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
  115. -->
  116. <!-- Access log processes all example.
  117. Documentation at: /docs/config/valve.html
  118. Note: The pattern used is equivalent to using pattern="common" -->
  119. <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
  120. prefix="192.168.1.50_access_log." suffix=".txt"
  121. pattern="%h %l %u %t "%r" %s %b" />
  122. </Host>
  123. </Engine>
  124. </Service>
  125. </Server>

Tomcat加载时相应组件(容器)的配置参数都是从这个文件读进去的,这个文件也是Tomcat性能优化的关键。 接下来我们就根据上图以及conf/server.xml的内容来一步步描述一下上面所说的各种组件吧。

Server

Server是Tomcat中最顶层的组件,它可以包含多个Service组件。在Tomcat源代码中Server组件对应源码中的  org.apache.catalina.core.StandardServer  类。StandardServer的继承关系图如下图所示:

Lifecycle是Tomcat的生命周期接口。保持组件启动和停止一致的的机制通过实现org.apache.catalina.Lifecycle接口来实现。

Service

接下来咋们来看看Service组件,Service组件相当于Connetor和Engine组件的包装器,它将一个或者多个Connector组件和一个Engine建立关联。上述配置文件中,定义一个叫 Catalina 的服务,并将Http,AJP(定向包的协议)这两个Connector关联到了一个名为 Catalina 的Service,注意一个Connetor对应处理一种协议。Service组件对应Tomcat源代码中的 org.apache.catalina.core.StandardService ,StandardService的继承关系图如下图所示:

Connector

既然Tomcat需要提供http服务,而我们知道http应用层协议最终都是需要通过TCP层的协议进行传递的,而Connector正是Tomcat中监听TCP网络连接的组件,一个Connector会监听一个独立的端口来处理来自客户端的连接。缺省的情况下Tomcat提供了如下两个Connector。我们分别描述一下:

  1. HTTP/1.1
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 上面定义了一个Connector,它缺省监听端口8080,这个端口我们可以根据具体情况进行改动。connectionTimeout定义了连接超时时间,单位是毫秒,redirectPort定义了ssl的重定向接口,根据缺省的配置,Connector会将ssl请求重定向到8443端口。
  2. AJP/1.3
    AJP表示Apache Jserv Protocol,此连接器将处理Tomcat和Aapache http服务器之间的交互,这个连接器是用来处理我们将Tomcat和Apache http服务器结合使用的情况。假如在同样的一台物理Server上面部署了一台Apache http服务器和多台Tomcat服务器,通过Apache服务器来处理静态资源以及负载均衡的时候,针对不同的Tomcat实例需要AJP监听不同的端口。

Connector对应源代码中的 org.apache.catalina.connector.Connector ,它的继承关系图如下所示:

Engine

Tomcat中有一个容器的概念,而Engine,Host,Context都属于Contanier,我们先来说说最顶层的容器Engine.
一个Engine可以包含一个或者多个Host,也就是说我们一个Tomcat的实例可以配置多个虚拟主机。
缺省的情况下<Engine name="Catalina" defaultHost="localhost">定义了一个名称为Cataline的Engine.Engine对应源代码中的org.apache.catalina.core.StandardEngine,它的继承关系图如下图所示:

Host定义了一个虚拟主机,一个虚拟主机可以有多个Context,缺省的配置如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">….</Host> 其中appBase为webapps,也就是<CATALINA_HOME>\webapps目录,unpackingWARS属性指定在appBase指定的目录中的war包都自动的解压,缺省配置为true,autoDeploy属性指定是否对加入到appBase目录的war包进行自动的部署,缺省为true.
Host对应源代码中的org.apache.catalina.core.StandardHost,它的继承关系图如下所示:

Context

在Tomcat中,每一个运行的webapp其实最终都是以Context的形成存在,每个Context都有一个根路径和请求URL路径,Context对应源代码中的org.apache.catalina.core.StandardContext,它的继承关系图如下图所示:

在Tomcat中我们通常采用如下的两种方式创建一个Context.下面分别描述一下:

  1. <CATALINA-HOME>\webapps目录中创建一个目录,这个时候将自动创建一个context,默认context的访问url为http://host:port/dirname,你也可以通过在ContextRoot\META-INF中创建一个context.xml的文件,其中包含如下的内容来指定应用的访问路径。 <Context path="/yourUrlPath" />
  2. conf\server.xml文件中增加context元素。 第二种创建context的方法,我们可以选择在server.xml文件的<Host>元素,比如我们在server.xml文件中增加如下内容:
[html] view plaincopy
  1. .......
[html] view plaincopy
  1. <span style="line-height: 1.5;">  </span><span style="line-height: 1.5;">.........</span>
[html] view plaincopy
  1. <Context path="/mypath" docBase="/Users/xxx" reloadable="true">
  2. </Context>
  3. </Host>
  4. t;/Engine>
  5. </Service>
  6. t;/Server>

这样的话,我们就可以通过 http://host:port/mypath 访问上面配置的context了。

Valve

Valve中文意思是阀门,Valve是Tomcat中责任链模式的实现,通过链接多个Valve对请求进行处理。每个容器都有一个流水线Pipeline(过滤器链),每个流水线至少有一个阀门。其中Valve可以定义在任何的Container中,上面说的Engine,Host,Context都属于容器。tomcat 默认定义了一个名为org.apache.catalina.valves.AccessLogValve的Valve,这个Valve负责拦截每个请求,然后记录一条访问日志。

通过上面的分析,我们发现Server,Service,Engine,Host,Context都实现了org.apache.catalina.Lifecycle接口,通过这个接口管理了这些核心组件的生命周期,关于这些组件的生命周期,我们在下一篇文章描述。

Tomcat总体架构(Tomcat源码解析系列二)

Tomcat源码解析系列二:Tomcat总体架构相关推荐

  1. Tomcat源码解析五:Tomcat请求处理过程

    前面已经分析完了Tomcat的启动和关闭过程,本篇就来接着分析一下Tomcat中请求的处理过程. 在开始本文之前,咋们首先来看看一个Http请求处理的过程,一般情况下是浏览器发送http请求-> ...

  2. spring源码解析系列之事件驱动模型架构

    2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本文转自"天河聊技术"微信公众号 为什么要去研究spring源码,我认为java最NX的就是我写 ...

  3. Tomcat源码解析三:tomcat的启动过程

    Tomcat组件生命周期管理 在Tomcat总体结构 (Tomcat源代码解析之二)中,我们列出了Tomcat中Server,Service,Connector,Engine,Host,Context ...

  4. Tomcat源码解析七:Tomcat Session管理机制

    前面几篇我们分析了Tomcat的启动,关闭,请求处理的流程,tomcat的classloader机制,本篇将接着分析Tomcat的session管理方面的内容. 在开始之前,我们先来看一下总体上的结构 ...

  5. Tomcat源码解析四:Tomcat关闭过程

    我们在Tomcat启动过程(Tomcat源代码阅读系列之三)一文中已经知道Tomcat启动以后,会启动6条线程,他们分别如下: [java] view plaincopy "ajp-bio- ...

  6. Tomcat源码解析六:Tomcat类加载器机制

    要说Tomcat的Classloader机制,我们还得从Bootstrap开始.在BootStrap初始化的时候,调用了org.apache.catalina.startup.Bootstrap#in ...

  7. openGauss数据库源码解析系列文章——openGauss开发快速入门(二)

    在上一篇openGauss数据库源码解析系列文章--openGauss开发快速入门(上)中,我们介绍了openGauss的安装部署方法,本篇将具体介绍openGauss基本使用. 二. openGau ...

  8. TiKV 源码解析系列文章(二)raft-rs proposal 示例情景分析

    作者:屈鹏 本文为 TiKV 源码解析系列的第二篇,按照计划首先将为大家介绍 TiKV 依赖的周边库 raft-rs .raft-rs 是 Raft 算法的 Rust 语言实现.Raft 是分布式领域 ...

  9. 外观模式源码解析(springjdbc+myabtis+tomcat)

    我们首先看一下外观模式在SpringJDBC中的一些应用,我们看一下JdbcUtils,为了更好理解,把外观模式重新讲了一下,用积分的场景,我们直接继续看源码,这个是spring.jdbc包下的,这个 ...

最新文章

  1. 1322项!这所高校国自然基金立项再创新高 | 附各高校最新统计
  2. java类加载器_类加载器ClassLoader
  3. java 注解妙用_框架开发之Java注解的妙用
  4. Orm框架介绍和常见的Android Orm框架
  5. 耳机不支持android,安卓手机为什么不能用EarPods耳机 原因分析【图解】
  6. python读取大文件内存不够_大型CSV文件(numpy)上的Python内存不足
  7. oracle:oracle学习笔记(三)
  8. linux 快组描述符,Linux 进程描述符 task struct
  9. java 含有package cmd_如何在命令提示符下编译运行含有Package的java文件
  10. Sleutel:密码治理器
  11. 2017.8.12在线笔试编程真题总结
  12. PLC编程需注意的地方
  13. PMP备考经验分享 制表很重要
  14. bootice添加黑苹果引导_黑苹果OC(OpenCore)引导升级教程
  15. 姓名降序排列语句c语言,sql语句升序降序排列20个
  16. 简易的安卓天气app(四)——搜索城市、完善页面
  17. CutefishOS 0.6 Beta 发布
  18. 记一次 打包报错:Keystore was tampered with, or password was incorrect
  19. Android初学之十二:Broadcast
  20. CentOS 7账号密码忘了怎么办?

热门文章

  1. 剑指Offer25 合并两个排序的链表
  2. Shell脚本函数(函数传参、递归、创建库)
  3. java socket 通信协议_java网络通信(基于TCP协议可靠通信的socket编程)
  4. C语言程序设计 C语言中的时间函数
  5. 如何判断Socket连接失效
  6. 爬虫模拟登陆手机验证码_Python+scrapy爬虫之模拟登陆
  7. 计算机基础知识赏花主观题,计算机研究生考什么?你知道吗?
  8. mybatis count返回null_Mybatis属性示例-Properties的三种配置方式
  9. 未找到要求的 from 关键字_性能优化|这恐怕是解释Explain关键字最全的一篇文章
  10. python常用方法总结-Python3常用函数、方法总结(持续更新…)