框架源码私享笔记(01)Tomcat核心架构功能 | 配置详解

打印 上一主题 下一主题

主题 1804|帖子 1804|积分 5412

读书笔记:对《活出意义来》这本书的序言特别有感触。其中:不要以成功为目标,你越是对它念念不忘,就越有可能错过它。因为成功犹如幸福,不是追求就能得到;它必须因缘际会...它实际是一个人经心全意投入并把自己置之度外时,不测获得的副产物。
  外界向你提供的目标,每每以某种奖励吸引着你追随。我们理应拒绝外在的奖励刺激-外驱力,必要自己创建’内奖‘-内驱力。即选定自己的目标,在追求目标的努力中,获得内心的秩序和成长的乐趣。
  
一、Tomcat概述
二、Tomcat核心功能
2.1 connector-网络毗连器
2.1.1 三种IO模型
2.2 container-servlet 容器
2.2.1 Container的主要功能
2.2.2 Container的容器布局
三、Tomcat架构解析
四、tomcat server.xml配置说明

【公众号搜索:拉丁解牛说技术】接待一起交换讨论。
一、Tomcat概述

Tomcat是Apache基金会基于Java开发开源的web容器。Tomcat应用服务器,又称“汤姆猫”,它开源、轻量、易于集成、社区背书支持的特性,深受Java开发者偏幸。尤其是Tomcat专注于处理servlet和jsp的出色能力深得研发者信赖(固然目前jsp用的企业已经很少,瓶颈在于互联网高并发期间配景下,jsp的响应和吞吐量很难满足需求)。
web服务器除了Tomcat,另有我们认识的Nginx、Apache。Nginx主要用于静态资源、反向署理、负载均衡服务器。而Apache服务器主要用于静态页面和http哀求,别的它有丰富的模块和插件,支持扩展实现负载均衡、虚拟主机等。
本日也是先从架构原理核心功能开头,有个大抵了解,背面在对具体某个核心组件进行详细分享。
二、Tomcat核心功能

Tomcat核心功能有2个:网络毗连器功能+servlet容器功能。
网络毗连器功能,负责是接收客户端的http哀求,并将http哀求转给对应servlet进行处理,以及将servlet处理结果返回给客户端。具体是专注处理来自外部的socket毗连哀求,并将对应IO字节流转成对应Request和Response对象。可以说,网络毗连器就是外交官,专注处理外部通讯事宜。
servlet容器功能,复杂加载和管理servlet,以及处理具体的Request哀求。servlet容器就是真正的内务管家,处理内部具体业务逻辑事宜,也就是我们的接口逻辑。

这两个核心功能对应Tomcat两个核心源码组件,分别是毗连器connector类,容器container接口。
2.1 connector-网络毗连器

connector之所以可以负责接收和响应外部的哀求,是因为内里有个协议处理器ProtocolHandler,专门负责处理socket通讯。Tomcat 8.0 支持的网络协议有http/1.1另有AJP/1.3 两个协议,而Tomcat8.5之后版本则新增支持下一代http/2.0协议。
2.1.1 三种IO模型

两种协议底层应用的网络IO模型,主要实现都是NIO,NIO2两个模型,别的另有一个APR模型。

三个IO模型核心特点和实用场景具体如下:
NIO ,全称Non-blocking I/O,是jdk1.4开始引入,并基于Java NIO类库的channel、buffer、selector去实现多路复用的NIO。具体是允许一个线程同时管理多个channel通道,当一个channel有读写IO事件,selector选择器再关照线程去处理,也就是允许每个线程管理多个IO操作,不像BIO是1V1那样干等,得当高并发毗连数多的场景。
NIO2,全称Non-blocking I/O 2,别的也叫Asynchronous I/O,所以也称为AIO。在jdk7开始引入的异步非壅闭I/O,基于jdk 7的NIO2类库实现。具体是基于事件和回调机制,通过AsynchronousSocketChannel实现异步IO操作,办理数据复制阶段壅闭问题,允许应用程序直接返回不消壅闭。NIO2比NIO得当更高并发和复杂场景的应用,比如大数据处理、高性能网络服务器。
而APR模型(Apache Portable Runtime),是通过C/C++实现封装Unix的IO操作,可以跨平台使用,由于与操作系统底层直接交互,性能优于NIO和NIO2。得当性能要求极高的静态资源和大型web高并发哀求场景。
这里附带说一下BIO,虽然BIO性能不佳,但是日常平凡性能要求场景,我们照旧经常使用和见到BIO。BIO是使用java.io里的FileInputStream和FileOutputStream进行读写操作,由于每次读写必要线程等待完成,导致效率低下性能不佳。

2.1.2 connector的核心组件

毗连器内里有2个核心组件,一个是protocolHandler协议处理器,一个是Adapter适配器。源码filed视图:

ProtocolHandler接口,用来处理具体的tcp\http哀求。
Adapter适配器,则将ProtocolHandler处理处理的http哀求Request,转换成servlet容器能处理的servletRequest。

protocolHandler内部的核心功能,是通过Endpoint和Processor两个核心组件实现具体的协议处理:
其中Endpoint负责监听端口,实现了TCP/IP协议,专门处理socket数据流信息。
而Processor实现http协议,接收Endpoint发过来的socket字节流数据,通过http协议格式解析相关数据,转换成Tomcat的Request对象,末了通过Adapter提交到servlet容器处理。

对于协议处理器,Tomcat提供了以下7个实现类,包罗我们常见的基于NIO、NIO2模型并实现http1.1协议、Ajp协议的几个处理器。

protocolHandler处理了网络毗连并得到相关哀求对象,为何不直接转给Container容器处理?
为什么必要Adapter适配器去中转?
由于每个协议格式数据不一样,Tomcat通过协议处理器,得到Tomcat的Request对象(org.apache.coyote.Request)。然而servlet容器里定义了自己的ServletRequest对象(HttpServletRequest),为了解耦两者通过Adapter适配器进行转换。
Adapter适配器的存在,就是为了桥接tomcat的Request对象与标准的ServletRequest对象之间的差异,确保Tomcat毗连器可以或许顺利地与Servlet容器进行交互,同时保持系统的机动性和扩展性。
2.2 Servlet Container容器

container容器核心功能,主要负责处理网络毗连器connector发过来的ServletRequest哀求。

2.2.1 Container的主要功能

它主要的功能有:
1、负责管理Servlet的生命周期,包罗Servlet的初始化、服务处理、销毁等。
2、负责http哀求的调度与执行。当connector毗连器接收到客户端http哀求后,会将哀求转给对应Container容器,Container根据哀求路径和配置信息,找到对应的Servlet并调用服务方法处理哀求。
3、负责响应天生HttpServletResponse对象,并返回给connector,通过connector返回给客户端。
2.2.2 Container的容器布局

Servlet web容器里,主要有四大组:engine、host、context、wrapper。彼此是父子层级关系,具体包含层级关系如下图:

Engine:代表Servlet引擎,一个Service只能有一个engine引擎,用来管理多个虚拟站点host。
Host:代表一个虚拟主机、站点。一个tomcat可以配置多个虚拟主机地点,然后内里可以包含多个context。
Context:表示一个web服务程序。也就是我们最认识的一个个应用。
wrapper:表示一个Servlet,是Container容器中最底层,没有下一级子类。
如上图所见,自上而下,有点像二叉树分散开来,tomcat通过组合模式来管理这些父子关系容器。
这四种容器,都统一实现了Container接口。他们的几个在server.xml有相关配置标签配置参数。

三、Tomcat架构解析

刚才已经对核心功能的connector、Container进行了详细介绍,接下来从团体再看。团体外部组件就比较简单。
直接看tomcat的server.xml文件可见其构成,server.xml我们非常认识,看起来更加直观,一目了然。
  1. <Server port="8005" shutdown="SHUTDOWN">
  2.   <Service name="Catalina">
  3.     <Connector port="8080" protocol="HTTP/1.1"/>
  4.     <Engine name="Catalina" defaultHost="localhost">
  5.       <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
  6.         <Context path="/ladingjieniu" docBase="ladingjieniu.war"/>  
  7.       </Host>
  8.     </Engine>
  9.   </Service>
  10. </Server>
复制代码

server:是tomcat的最顶级容器,一个tomcat里只有一个server。server表示tomcatServlet容器以及其他组件,负责组装并启动关闭connector毗连器、Servlet容器引擎。
service:一个server有多个service。service的出现,关键在于办理了网络协议解析和Servlet容器解耦问题,具体是整合多个connector毗连器和Container(内里只有一个engine Servlet引擎)绑定到一起,便于两个核心功能的维护和扩展。
connector、Container就和上文说的一致。一个主要负责处理外部的tcp、http哀求。另一个是具体负责Servlet哀求逻辑。

彼此之间的父子层级和关联数目关系如下,一个server有多个service,一个service只有一个engine引擎,一个engine可以配置多个host虚拟站点,而一个host可以有多个context web服务,一个context web服务里有多个Servlet wrapper。

四、tomcat server.xml 配置说明

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. Server是tomcat的最顶级容器,是server.xml的最外层标签,代表整个tomcat容器
  4. 参数port,是tomcat用来监听shutdown命令的TCP/IP端口号,默认为
  5. 8005。设置为-1,表示禁止通过端口关闭Tomcat,此时shutdown.bat/sh命令不能使用。
  6. 如果在一台服务器启动多个tomcat服务实例,该端口需保持差异。
  7. shutdown,用来指定shutdown 命令的别名,默认值SHUTDOWN
  8. -->
  9. <Server port="8005" shutdown="SHUTDOWN">
  10.     <!--监听器组件,不同组件功能不一样-->
  11.     <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  12.     <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
  13.    
  14.     <!--配置全局JNDI资源-->
  15.     <GlobalNamingResources>
  16.         <!-- 用户数据库Realm,配合tomcat-users.xml,管理tomcat host manager的用户身份验证 -->
  17.         <Resource name="ladingjieniu" auth="Container"
  18.                   type="org.apache.catalina.UserDatabase"
  19.                   description="User database that can be updated and saved"
  20.                   factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
  21.                   pathname="conf/tomcat-users.xml"/>
  22.     </GlobalNamingResources>
  23.     <!--
  24.      一个server里有多个service,里面有一个engine和多个connector。相当于一个服务
  25.      可以配置多个connector去监听外部请求,并在engine Servlet处理。
  26.     -->
  27.     <Service name="Catalina">
  28.         <!-- 供Service内各个Connector组件共享使用的线程池执行器,我们可以定义多个命名线程池 -->
  29.         <!--
  30.         配置连接器使用连接池参数:
  31.         maxThreads:最大并发数
  32.         minSpareThreads:线程池的核心线程数
  33.         maxIdleTime:Executor中空闲线程超时关闭的毫秒数,默认1分钟
  34.         maxConnections 与tomcat建立的最大socket连接数,默认是10000
  35.         acceptCount;请求的队列最大长度,默认是100
  36.         -->
  37.         <Executor name="tomcatThreadPool" namePrefix="ladingjieniushuojishu-exec-"
  38.             maxThreads="100" minSpareThreads="50"/>
  39.         <!-- 连接器组件,负责接收和响应连接,然后创建Request和Response对象转发给engine
  40.              默认连接器,监听端口8080,并支持HTTP/1.1协议,支持指定命名共享线程池的连接器。
  41.              port:连接器监听的请求端口,必须唯一
  42.              protocol:连接器监听的请求协议类型,默认是http/1.1
  43.              redirectPort:如果当前连接器不支持SSL(HTTPS)请求,但是收到SSL(HTTPS)请求时,Catalina将重定向至指定端口的Connector。
  44.              URIEncoding:用于解码URL的字符编码,则默认使用 UTF-8。
  45.              connectionTimeout:此连接器在建立连接之后等待请求URI的超时时间(毫秒),默认值为60000(即 60秒)。
  46.              当client与tomcat建立连接之后,在"connectionTimeout"时间之内,仍然没有得到client的请求数据,此时连接将会被断开。
  47.              maxConnections:tomcat在任何给定时间能同时接收和处理的最大连接数,默认1w。
  48.              acceptCount:当同时连接数超过maxConnections时,系统会继续接收连接,并放入Accept等待队列的长度,默认是100.
  49.              同时连接数超过maxConnections,且等待队列也放满,后续收到的请求都将被直接拒绝。
  50.             
  51.         -->
  52.         <Connector port="8080" protocol="HTTP/1.1"
  53.                    connectionTimeout="20000" executor="tomcatThreadPool"
  54.                    redirectPort="8443"/>
  55.         <!--在端口8009上定义使用AJP/1.3协议访问的连接器-->
  56.         <!--
  57.         <Connector protocol="AJP/1.3"
  58.                    address="::1"
  59.                    port="8009"
  60.                    redirectPort="8443" />
  61.         -->
  62.         <!--
  63.         请求处理组件,一个Service标签只能有一个Engine标签
  64.         Engine组件从一个或多个Connector中接收请求并处理,并将完成的响应返回给Connector,最终响应给客户端。
  65.         -->
  66.         <Engine name="Catalina" defaultHost="localhost">
  67.             <!--
  68.             一个虚拟主机,可以指定应用程序的基本目录,包含了一个或多个Web应用
  69.             默认的虚拟主机名为"localhost",
  70.             如果配置多个Host,可以让一个tomcat支持从不同的域名访问Web应用。
  71.             autoDeploy : Tomcat 在 运行时应定期检查新的或更新的 Web 应用程序。
  72.             appBase :虚拟主机的应用程序基础目录。
  73.             unpackWARs:是否将Web应用的WAR文件解压。如果为true,则先解压然后运行解压的Web应用,如果为false,直接使用WAR文件运行Web应用。
  74.             -->
  75.             <Host name="localhost" appBase="webapps"
  76.                   unpackWARs="true" autoDeploy="true">
  77.                 <!--通过日志记录在该Host中处理的相关请求-->
  78.                 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
  79.                        prefix="localhost_access_log" suffix=".txt"
  80.                        pattern="%h %l %u %t &quot;%r&quot; %s %b"/>
  81.             </Host>
  82.             <!--
  83.             支持配置多个web服务,域名映射, 需要修改本地hosts文件 。
  84.             -->
  85.             <Host name="www.ladingjieniu.com" appBase="lading" unpackWARs="true" autoDeploy="true">
  86.             <!--
  87.             Context的path,表示该 Web 应用程序的虚拟上下文路径。
  88.             docBase,表示web应用程序的物理根目录,若该路径是相对路径的话,则是相对于appBase而言,若是绝对路径,则与appBase无关。
  89.             reloadable是否支持重新加载web应用程序类,默认为false。
  90.             如果设为true,Tomcat服务器在运行时会监视在WEB-INF/classes和Web-INF/lib目录下的class文件变化,服务器自重新加载该Web应用。
  91.             -->
  92.                   <Context docBase="/app/ladingjieniu/myweb-1.0-SNAPSHOT" path="/myweb" reloadable="true" />
  93.             </Host>
  94.         </Engine>
  95.     </Service>
  96. </Server>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表