赞
踩
Tomcat源码系列文章
Connector
):处理Socket
连接,负责网络字节流与Request和Response对象的转化Container
):加载和管理Servlet
,以及具体处理Request请求Server类
的实例就代表了一个Tomcat的容器
,一个Tomcat进程只会有一个Server实例Service对象(一个容器和多个连接器组合)
Tomcat支持的I/O模型
Tomcat支持的应用层协议
多种I/O模型
和应用层协议
,一个容器可能对接多个连接器Service组件
不同的端口号
来访问同一台机器
上部署的不同应用连接器对Servlet容器屏蔽了协议及I/O模型等的区别,无论是HTTP还是AJP,在容器中获取到的都是一个标准的ServletRequest对象
连接器细化功能
Servlet
容器,得到ServletResponse连接器汇总功能
Tomcat的设计者设计了3个组件来实现这3个功能,分别是Endpoint
、Processor
和Adapter
网络通信
和应用层协议解析
放在一起考虑ProtocolHandler
的接口来封装这两种变化点三个核心组件
:Endpoint、Processor和Adapter来分别做三件事情Endpoint
和Processor
放在一起抽象成了ProtocolHandler
组件,它们的关系如下图所示通信监听的接口
,是具体的Socket
接收和发送处理器,是对传输层的抽象,因此Endpoint是用来实现TCP/IP协议
的Acceptor
和SocketProcessor
线程池
来执行。而这个线程池叫作执行器(Executor)
TCP/IP协议
的,那么Processor用来实现HTTP协议
Tomcat Request和Response对象
,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象Http11Processor
等,这些具体实现类实现了特定协议的解析方法和请求处理方式CoyoteAdapter
,这是适配器模式
的经典运用
Engine
、Host
、Context
和Wrapper
Wrapper
:表示一个Servlet
,它负责管理Servlet的生命周期
Context
:表示一个Web应用程序
,是Servlet、Filter的父容器
Host
:表示一个虚拟主机
,包含主机名称和IP地址,默认是localhost
Engine
:表示顶级容器
,接受连接器的所有请求,并将响应返回给连接器
父子包含关系
,在在tomcat的conf目录下的server.xml配置文件中也有体现8005
端口监听“SHUTDOWN
”命令,如果接收到了就会关闭Tomcat
Tomcat是用
Mapper组件
来确定请求是由哪个Wrapper容器里的Servlet
来处理
URL
定位到一个Servlet
容器组件
与访问路径
的映射关系
Host容器里配置的域名
、Context容器里的Web应用路径
,以及Wrapper容器里Servlet映射的路径
多层次的Map
举例:一个网购系统
后台管理系统
,还有面向终端客户的在线购物系统
同一个Tomcat
上,为了隔离它们的访问域名,配置了两个虚拟域名
: manage.shopping.com 和 user.shopping.com
manage.shopping.com
域名去管理用户和商品,而用户管理和商品管理是两个单独的Web应用user.shopping.com
域名去搜索商品和下订单,搜索功能和订单管理也是两个独立的Web应用一个Service
组件和一个Engine
容器组件两个Host
子容器,在每个Host容器下创建两个Context
子容器多个Servlet
,Tomcat还会在每个Context容器里创建多个Wrapper
子容器每个容器都有对应的访问路径
,可以通过下面这张图来帮助理解假如有用户访问一个URL,比如图中的http://user.shopping.com:8080/order/buy
,Tomcat如何将这个URL定位到一个Servlet呢?
HTTP
连接器监听8080端口
、默认的AJP
连接器监听8009端口
web.xml
中配置的Servlet映射路径
来找到具体的Wrapper和Servlet
父子容器
都会对请求做一些处理
Adapter
会调用容器的Service方法来执行ServletEngine
容器,Engine容器对请求做一些处理后,会把请求传给自己子容器Host
继续处理,依次类推Wrapper
会调用最终的Servlet
来处理Pipeline-Valve
管道Pipeline-Valve是责任链模式
处理者
依次对请求进行处理Valve接口
public interface Valve {
// 获取下一个阀门
public Valve getNext();
// 设置下一个阀门
public void setNext(Valve valve);
// 执行业务逻辑
public void invoke(Request request, Response response);
}
Pipeline接口
Valve链表
,Valve可以插入到Pipeline中,对请求做某些处理public interface Pipeline {
// 获取基本阀门
public Valve getBasic();
// 设置基本阀门
public void setBasic(Valve valve);
// 添加阀门
public void addValve(Valve valve);
// 获取阀门数组
public Valve[] getValves();
// 删除阀门
public void removeValve(Valve valve);
// 获取首个阀门
public Valve getFirst();
}
四种容器的执行流程
链式触发
的呢,比如Engine中Pipeline需要调用下层容器Host中的Pipeline
// Calling the container
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。