Tomcat服务器的启动是基于一个server.xml文件的,Tomcat启动的时候首先会启动一个Server,Server里面就会启动Service,Service里面就会启动多个"Connector(连接器)",每一个连接器都在等待客户机的连接,当有用户使用浏览器去访问服务器上面的web资源时,首先是连接到Connector(连接器),Connector(连接器)是不处理用户的请求的,而是将用户的请求交给一个Engine(引擎)去处理,Engine(引擎)接收到请求后就会解析用户想要访问的Host,然后将请求交给相应的Host,Host收到请求后就会解析出用户想要访问这个Host下面的哪一个Web应用,一个web应用对应一个Context
-
Tomcat的结构体系
2020-08-31 23:42:20本文基于Tomcat 7,参考了 汪建的《Tomcat内核设计剖析》,也许对理解Tomcat知识体系、面试有所帮助。本文基于Tomcat 7,参考了 汪建的《Tomcat内核设计剖析》,也许对理解Tomcat知识体系、面试有所帮助。
Servlet规范
所谓Servelt规范,是一系列的接口和约定的说明。Tomcat实现了Servlet规范,因此有必要先大致了解一下Servlet规范。
1. Servlet接口
核心接口:
javax.servlet.Servlet
public interface Servlet { void init(ServletConfig config) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest req, ServletResponse res)throws ServletException, IOException; String getServletInfo(); void destroy(); }
常用Servlet:
HttpServelt
生命周期:- 加载实例化(由Web容器完成)
- 初始化(init)
- 处理请求(service)
- 销毁(destroy)
一个问题,想想看:
Servlet是单例吗?
一般来说,在Servlet容器中,每个Servlet类智能对应一个Servlet对象,所有请求都由同一个Servlet对象处理! 因此要小心并发问题!
当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml的配置实例化这个Servlet对象。当有新的客户端请求到来时,一般不会再实例化该Servlet类,也就是说会有多个线程在使用这个Servlet实例。2. ServletRequest、ServletResponse
没啥好讲的
3. ServletContext
一个Web应用对应一个
ServeltContext
接口的实例4. Filter
涉及到一个设计模式:责任链模式
5. 会话
Servlet并没有提出协议无关的会话规定,每个协议需要自己规定。
HTTP对应的会话接口为HttpSession
。实现有两种:- Cookie是常用的会话跟踪机制,其中Cookie的标准名字必须为JSESSIONID
- URL重写,即在URL后面添加一个jsessionid参数,不建议使用
5. web应用
当一个Web应用程序部署到容器中时,在Web程序开始处理客户端请求之前,必须按照下列步骤顺序执行:
- 实例化web.xml中
<listener>
元素标识的每个事件监听器的一个实例 - 对于已实例化且实现了
ServletContextListener
接口的监听器实例,调用其contextInitialized()
方法 - 实例化web.xml中
<filter>
元素标识的每个过滤器的一个实例,并调用每个过滤器的init方法来初始化 - 根据Servlet配置的load-on-startup属性大小,按照顺序实例化Servlet,并调用其init()方法(load-on-startup只有为正数才能在容器启动时加载,且数值越小越优先)
6. Servlet映射
没啥好说的,Map
Tomcat整体架构及组件
Tomcat内部主要组件
如下图
Tomcat请求流转过程
如下图
流程说明:
- 当Tomat启动后,Connector组件的接收器(Acceptor)将会监听是否有客户端套接字连接并接收Socket
- 一旦接收到客户端的连接,则将连接交给线程池Executor处理,开始执行请求响应任务
- Http11Processor组件负责从客户端连接中读取消息报文,然后开始解析HTTP的请求行、请求头部、请求体。将解析后的报文封装成Request对象,方便后面处理时通过Request对象获取HTTP协议的相关值
- Mapper组件根据HTTP协议请求行的URL属性值和请求头部的Host属性值匹配该有哪个Host、哪个Context、哪个Wrapper容器来处理请求
- CoyoteAdaptor组件负责将Connector组件和Engine容器连接起来,把前面处理过程中生成的请求对象Request和响应对象Response传递到Engine容器,调用它的管道。
- 后续Engine、Host、Context和Wrapper容器依次处理请求,并且处理时均要通过相关容器的阀门(Valve)
- Wrapper容器对应的Servlet对象处理完氢气后,会将结果输出到客户端中
对照上述的组件图,下面分别简单介绍一下几个重要的组件
Server
Tomcat最顶级的组件,代表Tomcat的运行实例,在一个JVM中只有包含一个Server。
一个Server可能会包含多个Service
对应配置文件为server.xml
Server组件图
几个重要的组件
下面介绍几个比较重要的组件
1. JreMemoryLeakPreventionListener
该组件主要是用来解决JRE库内存泄露问题的。
1.1 问题描述
Tomcat中重加载一个Web应用是通过实例化一个新的ClassLoader来实现的。如果旧的ClassLoader无法被回收,就会造成内存泄露。
案例一:如果Web应用中一些生命周期很长的单例对象(如 JRE库中的某些类)引用了Tomcat的ClassLoader(如 WebappClassLoader),且该单例对象会在Java程序整个运行周期内存在的话,就可能导致无法卸载该ClassLoader,从而出现内存泄露的情况。
案例二:如果Tomcat的ClassLoader被某个线程持有,然后该线程启动了一个新线程,并且新线程无限循环(如 JRE库中的 Disposer),那么新线程也会继承父线程的ClassLoader,从而造成Tomcat的ClassLoader无法被回收,出现内存泄露的情况。1.2 解决方法
JreMemoryLeakPreventionListener
则是用来解决这个问题的。它的主要作用是,在加载那些特殊的对象时,使用系统自己的ClassLoader,而不是Tomcat的ClassLoader。等到这些特殊的对象加载结束后,再将ClassLoader还原。这样就可以解决这个问题了。主要功能代码如下:
ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { // Use the system classloader as the victim for all this // ClassLoader pinning we're about to do. Thread.currentThread().setContextClassLoader( ClassLoader.getSystemClassLoader()); // 加载一些特殊的对象 } finally { Thread.currentThread().setContextClassLoader(loader); }
2. ThreadLocalLeakPreventionListener
这个listener主要是用来解决
ThreadLocal
内存泄露问题的2.1 问题描述
如果Tomcat Web应用的线程池ThreadLocal对象引用了其ClassLoader(如 WebappClassLoader),由于一般线程池生命周期比较长,若此线程池没有释放,则可能会导致Web应用重加载后,旧的ClassLoader无法释放,从而造成内存泄露。2.2. 解决方法
通过ThreadLocalLeakPreventionListener
类监听Server stop事件,如果发生了Server stop事件,则将线程池内的所有线程销毁,这样就可以解决这个问题了。主要功能代码如下:
Engine engine = (Engine) context.getParent().getParent(); Service service = engine.getService(); Connector[] connectors = service.findConnectors(); if (connectors != null) { for (Connector connector : connectors) { ProtocolHandler handler = connector.getProtocolHandler(); Executor executor = null; if (handler != null) { executor = handler.getExecutor(); } if (executor instanceof ThreadPoolExecutor) { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; threadPoolExecutor.contextStopping(); } else if (executor instanceof StandardThreadExecutor) { StandardThreadExecutor stdThreadExecutor = (StandardThreadExecutor) executor; stdThreadExecutor.contextStopping(); } } }
shutdown命令
Tomcat启动后,主线程会进入等待shutdown命令的环节,它会不断尝试读取客户端发送过来的消息,一旦匹配上 shutdown 命令,则会跳出循环,关闭Tomcat。而daemon线程则负责接收客户端请求,处理客户端报文。
图示如下:
相关源码如下:
org.apache.catalina.startup.Catalina#startif (await) { await(); stop(); }
org.apache.catalina.core.StandardServer#await
// Match against our command string boolean match = command.toString().equals(shutdown); if (match) { log.info(sm.getString("standardServer.shutdownViaPort")); break; } else log.warn(sm.getString("standardServer.invalidShutdownCommand", command.toString()));
Service
Service是服务的抽象,它代表请求从接收到处理的所有组件的集合。
一个Service可能会包含若干个Connector、一个Engine、若干Executor线程池组件Connector
Connect的职责:接收客户端连接,进行客户端请求处理
JIoEndpoint
JIoEndpoint为BIO模式,主要处理流程如下:
关注几个类方法:
Connector
的初始化:org.apache.catalina.connector.Connector#initInternal
Connector
的启动:org.apache.catalina.connector.Connector#startInternal
Acceptor
的处理:org.apache.tomcat.util.net.JIoEndpoint.Acceptor#run
SocketProcessor
的处理:org.apache.tomcat.util.net.JIoEndpoint.SocketProcessor#run
NioEndpoint
NioEndpoint为非NIO模式,主要处理流程如下:
几个关键组件:
LimitLatch:负责对连接数的控制,基于AQS并发框架实现
Acceptor:负责接收套接字连接并注册到通道队列里
Poller:负责轮询检查事件列表
SocketProcessor:任务定义器
Executor:负责处理套接字的连接池AprEndpoint
AprEndpoint为本地库IO模式(比较复杂,感觉不用特别关注),主要处理流程如下:
AprEndpoint有两种处理模式:
- 如果操作系统支持
TCP_DEFER_ACCEPT
参数,则Acceptor通过APR获取到套接字后,直接创建SocketWithOptionsProcessor
对象,最后直接放到线程池中执行套接字的读写和逻辑处理,整个过程都是阻塞的。 - 如果操作系统不支持
TCP_DEFER_ACCEPT
参数,则Acceptor通过APR获取到套接字后,将套接字放到待轮询队列PollSet中,而PollSet则不断通过APR检测已准备好的套接字,接着创建SocketProcessor
对象,最后放入线程池中执行,接下来的过程也是阻塞的。
TCP_DEFER_ACCEPT
参数优化:
使用了
TCP_DEFER_ACCEPT
参数优化的区别在于,三次握手之后,最后一次的ACK后连接并不会被接收,而是当客户端数据发送到来时才会被接收。这样一来有一个好处,就是连接只要被接收就肯定有数据。Engine
Engine代表全局Servlet引擎
一个Engine可以包含若干个Host容器Host
Host组件代表虚拟主机
一个Host虚拟主机可以存放若干Web应用的抽象(即 Context容器)HostConfig组件
Host容器存放的是Context级别的容器(即 Web应用)。当Tomcat启动后,需要加载Web应用,设置相关的属性和配置,这其中就要用到
HostConfig
。HostConfig
是Host容器的生命周期监听器,它实现了org.apache.catalina.LifecycleListener
接口,在其lifecycleEvent
方法中,会监听 Tomcat 启动、停止等操作,然后进行相应的操作。HostConfig 的一个重要的功能就是 Context容器(即 Web应用)的部署,其支持以下类型的Web应用部署。
- Descriptor描述符类型
- War包类型
- 目录类型
其中Descriptor类型的部署,支持 Web应用的
重部署
和重加载
;而 War包类型和目录类型,只支持 Web应用的重加载
。Context
Context组件是Web引用的抽象。(我们开发的Web应用最终部署到Tomcat中就会对应一个Context对象)
一个Context容器会有若干个Servlet(即 Wrapper容器)比较重要的组件:
- Loader组件:Web应用加载器,用于加载Web应用的资源,它要保证不同Web应用之间的资源隔离
- Manager组件:会话管理器,用于管理对应Web容器的会话
- NamingResource组件:命名资源,它负责将Tomcat配置文件的server.xml 和 Web应用的 context.xml资源和属性映射到内存中
- Mapper组件:Servlet映射器,它属于Context内部的路由映射器,只负责该Context容器的路由导航
- 过滤器组件:
FilterDef
、ContextFilterMaps
、ApplicationFilterConfig
TODO - WebappClassLoader:类加载器的隔离 TODO
- ApplicationContext:是Servlet规范中的ServletContext接口的标准实现,表示某个Web应用的运行环境。
- ServletContainerInitializer:Web容器启动时,让第三方组件做一些初始化工作
- MemoryLeakTrackingListener监听器:辅助完成关于内存泄露跟踪的工作。
Wrapper
Wrapper是Tomcat中最小的容器级别。
一般来说,一个Wrapper对应一个Servlet对象(即 所有线程共用同一个Servlet对象)。SingleThreadModel是例外,可能对应一个Servlet对象池(SingleThreadModel已经是Deprecated了)。Servlet工作机制的大致流程是:Request -> StandardEngineValve -> StandardHostValve -> StandardContextValve -> StandardWrapperValve -> 实例化并初始化Servlet对象 -> 由过滤器链执行过滤操作 -> 调用该Servlet对象的service方法 -> Response
比较重要的组件:
- 过滤器链
- Comet模式的支持
- WebSocket协议的支持
- 异步Servlet(参考Dubbo异步调用)
根据请求资源的不同,Servlet可以分为三类:
- 普通Servlet,处理普通的业务逻辑请求
- JspServlet,访问JSP页面
- DefaultServlet,访问静态资源
Valve
管道模式类似于责任链模式,顾名思义,就像一条管道将多个对象连接起来,整体看起来就像若干个阀门嵌套在管道中,而
处理逻辑就放在阀门上
。Tomcat 4个级别的容器中,分别都有自己的基础阀门。如下:
StandardEngineValve
StandardHostValve
StandardContextValve
StandardWrapperValve
Tomcat中常用的阀门有:
AccessLogValve
:记录客户端访问日志
ErrorReportValve
:将错误以HTML格式输出的阀门
PersistentValve
:将请求会话持久化的阀门
RemoteAddrValve
:访问IP控制限制的阀门
RemoteIPValve
:代理或负载均衡处理的阀门
SemaphoreValve
:控制容器并发访问的饭呢日志
Tomcat采用工厂模式(LogFactory)生成日志对象,底层使用JDK自带的日志工具(DirectJDKLog),而没有使用第三方日志工具,以减少包的引入。没有采用JDK日志工具的默认配置,而二十通过配置系统变量和重写某些类达到特定效果。
国际化
Tomcat日志的国际化,使用了JDK里面的三个类:MessageFormat、Locale、ResourceBundle,而Tomcat中引用StringManager类把这三个类封装起来,方便操作。而StringManager类采用了一个Java包对应一个StringManager对象的设计,折中的考虑使性能与资源得以同时兼顾。
Tomcat类加载
Tomcat 7中的类加载器,能够实现公共Jar的共享 和 各个Web应用之间的隔离。加载器的继承关系如下:
Tomcat中多了Common类加载器和WebApp类加载器。- Common类加载器加载Tomcat公用的一些类与组件
- WebApp类加载是用于加载Web应用程序的,每一个类加载器负责加载一个Web应用
T
omcat启动的时候,就会将Common类加载器设置为线程上下文类加载器。
相关代码:
org.apache.catalina.startup.Bootstrap#init()initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader);
会话
Web容器的会话机制补充了HTTP协议的无状态性。Tomcat在服务端使用jsessionid 与 客户端的cookie配合,完成了其的会话机制。
其jsession传递方式一般有三种:- Cookie方式
- 重写URL方式,即将jsessionid附加到url上
- 表单隐藏方式
Tomcat中Session相关的类:
- 标准会话对象:
StandardSession
- 增量会话对象:
DeltaSession
- 标准会话管理器:
StandardManager
- 持久化会话管理器:
PersistentManager
支持多种会话存储方式,主要针对的是单个会话的持久化,存储方式包括:- 文件方式存储
FileStore
- 数据库存储
JDBCStore
- 文件方式存储
- 集群增量会话管理器:
DeltaManager
- 全节点赋值
- 只复制会话增量
- 集群备份会话管理器:
BackupManager
- 集群的会话节点一般为:一主一备多备份
- 会话黏贴(Session Stick)机制:一种会话定位技术,即在Tomcat节点上生成一种包含位置信息的会话ID,它一般附带了Tomcat实例名,当客户端再次请求时,负载均衡器会解析会话ID中的位置信息并转发到相应节点上
- 集群RPC通信:
Tribes框架
-
tomcat的结构体系
2018-03-28 15:03:48以下为具体功能:Server:A Server element represents the entire Catalina servlet container. (Singleton)Service:它由一个或者多个Connector...Connector:TOMCAT有两个典型的Connector,一个直接侦听来自brow...以下为具体功能:
Server:A Server element represents the entire Catalina servlet container. (Singleton)Service:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求。Connector:- TOMCAT有两个典型的Connector,一个直接侦听来自browser的http请求,一个侦听来自其它WebServer的请求
- Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求
- Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求
Engine:- Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名
- 当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理
- Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理
Host:- 代表一个Virtual Host,虚拟主机,每个虚拟主机和某个网络域名Domain Name相匹配
- 每个虚拟主机下都可以部署(deploy)一个或者多个Web App,每个Web App对应于一个Context,有一个Context path
- 当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理
- 匹配的方法是“最长匹配”,所以一个path==”"的Context将成为该Host的默认Context
- 所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配
Context:- 一个Context对应于一个Web Application,一个Web Application由一个或者多个Servlet组成
- Context在创建的时候将根据配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servlet类
- 当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类
- 如果找到,则执行该类,获得请求的回应,并返回
个人总结tomcat大体运行流程:
tomcat服务器的启动是根据server.xml文件,tomcat的启动时候会先启动一个server(如图),server里面service,service里面包含很多connector(连接器),每一个connector都在等客户机的连接,当用户使用浏览器访问网站时候,connector进行连接,记住connector只是起到连接作用,不会处理用户的请求。connector将用户的请求转移到engine(引擎)进行处理。engine会解析到用户所想要访问的host,host会解析用户的请求发现是里面对应的哪个web应用,找到对应的context。
Tomcat Server处理一个http请求的具体过程
假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为”"的Context去处理)
7) path=”/wsota”的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector13)Connector把HttpServletResponse对象返回给客户browser
以下为大致流程图:
具体内容可参考:https://blog.csdn.net/alexdamiao/article/details/52268390
-
Tomcat体系结构
2020-02-25 19:13:48Tomcat体系结构 Tomcat是什么? Tomcat 服务器是一个基于Java语言开发的,免费的开放源代码的Web应用服务器,属于轻量级应用服务器。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了...Tomcat是什么?
Tomcat 服务器是一个基于Java语言开发的,免费的开放源代码的Web应用服务器,属于轻量级应用服务器。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。
本文所述版本:8.5.50
从整体看Tomcat
Tomcat整体结构图
先从整体上认识Tomcat内部的架构层次。如果将Tomcat内核高度抽象,则它可以看成由连接器(Connector)组件和容器(Container)组件组成。
- Connector组件(也可以叫Coyote,Coyote是Connector框架的名字)负责在服务器端处理客户端连接,包括接收客户端连接、接收客户端的消息报文以及消息报文的解析等工作。
- Container组件则负责对客户端的请求进行逻辑处理,并把结果返回给客户端。
Container组件在图中并不能找到,它其实包括4个级别的容器:Engine组件、Host组件、Context组件和Wrapper组件,Container也是整个Tomcat的核心。
从Tomcat服务器配置文件server.xml的内容格式看,它所描述的Tomcat也符合上图的层级结构,所以从server.xml文件也能看出Tomcat的大体结构,servlet配置文件参考图:
各组件介绍
Catalina
负责解析Tomcat的配置文件(server.xml) , 以此来创建服务器Server组件并进行管理。
Server
Server是最顶级的组件,它代表Tomcat的运行实例,在一个JVM中只会包含一个Server。负责组装并启动Servlet引擎。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式。在Server的整个生命周期中,不同阶段会有不同的事情要完成。为了方便扩展,它引入了监听器方式,所以它也包含了Listener组件。另外,为了方便在Tomcat中集成JNDI,引入了GlobalNamingResources组件。
Service
Service在设计上Server组件可以包含多个Service组件,每个Service组件都包含了若干用于接收客户端消息的Connector组件和处理请求的Engine组件。不同的Connector组件使用不同的通信协议,如HTTP协议和AJP协议,当然还可以有其他的协议A和协议B。若干Connector组件和一个客户端请求处理组件Engine组成的集合即为Service。此外,Service组件还包含了若干Executor组件,每个Executor都是一个线程池,它可以为Service内所有组件提供线程池执行任务。它将若干个Connector组件绑定到一个 Container。
Connector(Coyote)
Coyote(Coyote是Connector框架的名字) 是Tomcat 中连接器的组件名称 , 是对外的接口。客户端通过Coyote与服务器建立连接、发送请求并接收响应 。
-
Coyote 封装了底层的网络通信(Socket 请求及响应处理)
-
Coyote 使Catalina 容器(容器组件)与具体的请求协议及IO操作方式完全解耦
-
Coyote 将Socket 输入转换封装为 Request 对象,进一步封装后交由Catalina 容器进行处理,处理请求完成后, Catalina 通过Coyote 提供的Response 对象将结果写入输出流
-
Coyote 负责的是具体协议(应用层)和IO(传输层)相关内容
Tomcat支持多种应用层协议和I/O模型,如下:
应用层协议:
应用层协议 描述 HTTP/1.1 大部分为web应用采用的访问协议。 AJP 用户和WX集成(如Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3 HTTP/2.0 HTTP/2.0大幅度提升web性能。下一代HTTP协议,自8.9/9.0版本后开始支持 I/O模型:
IO模型 描述 NIO 非阻塞I/O,采用Java NIO类库实现。 NIO2 异步I/O,采用JDK7最新的NIO2类库实现。 APR 采用Apache可移植运行库实现,是C/C++编写的本地库。如选择此方案,需要单独安装APR库 NIO Connector结构
Coyote的内部组件及流程
EndPoint
EndPoint 是 Coyote 通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的。
ProtocolHandler
Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协议的处 理能力。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol , Http11Nio2Protocol ,Http11AprProtocol
Processor
Processor 是Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协 议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的 Socket,读取字节流解析成Tomcat Request和Response对象,并通过 Adapter将其提交到容器处理,Processor是对应用层协议的抽象
Adapter
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的 Request类来封装这些请求信息。ProtocolHandler接口负责解析请求并生成 Tomcat Request类。但是这个Request对象不是标准的ServletRequest,不 能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引 入CoyoteAdapter,这是适配器模式的经典运用,连接器调用 CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象, CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器
Container
Container组件下有几种具体的组件,分别是Engine、Host、Context和Wrapper。这4种组件(容器)是父子关系。Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。
Engine
Engine表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,每个Service组件只能包含一个Engine容器组件, 但Engine组件可以包含若干Host容器组件。
Host
代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个Context。
Context
表示一个Web应用程序, 一个Web应用可包含多个Wrapper。
Wrapper
表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器。
Tomcat启动时序图
启动脚本在mac下是startup.sh,在windows下是startup.bat。
init初始化调用栈:
Start启动调用栈:
Tomcat8.5.50默认使用NIO:
请求处理的整体过程
整体看一下客户端从发起请求到响应的整个过程在Tomcat内部如何流转。
处理细节
下面介绍请求流转的具体过程(主流程):
- 当Tomcat 启动后,Connector组件的接收器(Acceptor)将会监听是否有客户端套接字连接并接收Socket。
- 一旦监听到客户端连接,则将连接交由线程池Executor处理,开始执行请求响应任务。
- Http11NioProcessor组件负责从客户端连接中读取消息报文,然后开始解析HTTP的请求行、请求头部、请求体。将解析后的报文封装成Request对象,方便后面处理时通过Request对象获取HTTP协议的相关值。
- Mapper组件根据HTTP协议请求行的URL属性值和请求头部的Host属性值匹配由哪个Host容器、哪个Context容器、哪个Wrapper容器处理请求,这个过程其实就是根据请求从Tomcat中找到对应的Servlet。然后将路由的结果封装到Request对象中,方便后面处理时通过Request对象选择容器。
- CoyoteAdaptor组件负责将Connector组件和Engine容器连接起来,把前面处理过程中生成的请求对Request和响应对象Response传递到Engine容器,调用它的管道。
- Engine容器的管道开始处理请求,管道里包含若干阀门(Valve),每个阀门负责某些处理逻辑。可以根据自己的需要往这个管道中添加多个阀门,它会负责匹配并调用Host容器的管道。
- Host容器的管道开始处理请求,它同样也包含若干阀门(Valve),它继续往下调用匹配Context容器的管道。
- Context容器的管道开始处理请求,它负责调用Wrapper容器的管道。
- Wrapper容器的管道开始处理请求,它会执行该Wrapper容器对应的Servlet对象的处理方法,对请求进行逻辑处理,并将结果输出到客户端。
-
Tomcat的体系结构
2011-12-08 21:51:23Tomcat的体系结构,基本配置,server.xml -
tomcat体系结构
2018-04-19 21:07:00tomcat体系结构 Tomcat服务器的启动是基于一个server.xml文件的,Tomcat启动的时候首先会启动一个Server,Server里面就会启动Service,Service里面就会启动多个"Connector(连接器)",每一个连接器都...转载于:https://www.cnblogs.com/fl-index/p/8886266.html
-
Tomcat结构体系
2018-04-18 20:52:42先上一张Tomcat的顶层结构图(图A),如下: Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。 Service主要包含两个部分:Conn... -
源码分析tomcat的体系结构
2020-03-26 15:35:27源码分析tomcat的体系结构 tomcat原理: 在端口监听socket请求 解析请求 返回处理结果 tomcat的体系结构图 Server:代表整个tomcat服务器实例,tomcat只有一个server,但server至少应该包含一个service Service:... -
Tomcat体系结构与插件配置教程图解
2020-09-30 03:17:38主要介绍了Tomcat体系结构与插件配置教程图解,包括发布程序的过程和tomcat服务器体系结构,需要的朋友可以参考下 -
【tomcat】tomcat的体系结构
2016-12-20 17:34:14越来越喜欢看结构图,可以加深理解,看到这篇推文。 先markdown. 原文链接,可能需备梯子 有时间再把文章翻译过来 -
图解 Tomcat 体系结构
2008-09-10 12:34:24Apache Tomcat 是一款非常著名的开源 Servlet/JSP 容器。 Apache Tomcat 是一款非常著名的开源 Servlet/...让我们先来浏览一下 Tomcat 体系结构中的六个主要概念: Server Service Engine Host Connector Context -
tomcat体系结构学习
2020-11-01 15:48:35Tomcat是⼀个Http服务器(能够接收并且处理http请求,所以tomcat是⼀个http服务器),我们使⽤浏览器向某⼀个⽹站发起请求,发出的是Http请求,那么在远程,Http服务器接收到这个请求之后,会调⽤具体的程序(Java类... -
tomcat的体系结构
2016-08-09 11:04:39里面有一个大的service模块,在这个模块下有多个连接器不同的连接器通过不同的协议链接不同的浏览器或其他的程序。连接器就会把信息传给引擎,引擎再找host(主机(可以有多个)),然后再找web应用,然后再提供资源... -
tomcat的体系结构与请求流程
2020-03-23 10:37:25一、tomcat的体系结构 tomcat里面包含Catalina容器,coyote连接器,jasperJsp引擎,表达式预约JavaEl,命名服务Naming,服务器体重juli等这6大块。 其中Catalina是核心容器。 tomcat的catalina结构图 一个... -
tomcat 体系结构详解
2019-04-02 15:15:00下面详细介绍tomcat内部组件的作用: Tomcat是一个servlet容器,实现了对Servlet和JSP的支持,除此之外,tomcat还可以作为一个web应用服务器。独立的Servlet容器是Tomcat的默认模式。管理和运行Servlet/JSP的...