Tomcat系统架构
Tomcat 非常的模块化,只要找到最核心的模块,问题游刃而解,了解整体架构对深入了解 Tomcat 至关重要!
顶层架构
先上一张 Tomcat 的顶层结构图(图A),如下:
Tomcat 中最顶层的容器是 Server,一个 Server 可以包含至少一个 Service,用于具体提供服务。
Service 包含两个部分:Connector 和 Container。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下:
1、Connector 用于处理连接相关的事情,并提供 Socket 与 Request 和 Response 相关的转化;
2、Container 用于封装和管理 Servlet,以及具体处理 Request 请求;
一个 Tomcat 中只有一个 Server,但是可以有多个 Connectors,这是因为一个服务可以有多个连接,如同时提供 Http 和 Https 链接,也可以提供向相同协议不同端口的连接,示意图如下(Engine、Host、Context下边会说到):
多个 Connector 和一个 Container 就形成了一个 Service,但是 Service 还要一个生存的环境 Server !所以整个 Tomcat 的生命周期由 Server 控制。另外,上述的包含关系或者说是父子关系,都可以在 tomcat 的 conf 目录下的server.xml配置文件中看出(Tomcat 版本为8.0)
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<Service name="Catalina">
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log" suffix=".txt"/>
<Context docBase="E:\apache-tomcat-8.0.53\wtpwebapps\example" path="/example" reloadable="true" source="org.eclipse.jst.jee.server:example"/>
</Host>
</Engine>
</Service>
</Server>
这张结构图也能更清楚的理解:
Server 标签设置的端口号为 8005,shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭 Tomcat。
Tomcat Server处理一个HTTP请求的过程
详细过程
1、用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
2、Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。
5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。
6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。
7、Context把执行完之后的HttpServletResponse对象返回给Host。
8、Host把HttpServletResponse对象返回给Engine。
9、Engine把HttpServletResponse对象返回Connector。
10、Connector把HttpServletResponse对象返回给客户Browser。
Connector和Container的微妙关系
一个请求发送到 Tomcat 之后,首先经过 Service 然后会交给Connector,并将请求封装为 Request 和 Response 来具体处理,封装之后再交由 Container 处理,然后再返回给 Connector,最后在由通过Socket 将处理结果返回客户端,请求处理结束!
Connector 最底层使用的是 Socket 来进行连接的,Request 和 Response是按照 HTTP 协议来封装的,所以 Connector 同时需要实现TCP/IP 协议和 HTTP 协议!Tomcat 处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下 Connector!
Connector架构分析
Connector 用于接受请求并将请求封装成 Request 和 Response,然后交给 Container 进行处理,Container 处理完之后在交给 Connector 返回给客户端。
因此,我们可以把 Connector 分为四个方面进行理解:
(1)Connector如何接受请求的?
(2)如何将请求封装成Request和Response的?
(3)封装完之后的Request和Response如何交给Container进行处理的?
(4)Container处理完之后如何交给Connector并返回给客户端的?
首先看一下 Connector 的结构图(图B),如下所示:
Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler 代表不同的连接类型,比如:Http11Protocol 使用的是普通Socket来连接的,Http11NioProtocol 使用的是 NioSocket 来连接的。
#Container架构分析
Container 用于封装和管理 Servlet,以及具体处理 Request 请求,在Container 内部包含了4个子容器,结构图如下(图C):
4个子容器的作用分别是:
(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
(2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
(3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封装着一个Servlet;
下面找一个 Tomcat 的文件目录对照一下,如下图所示:
Context 和 Host 的区别是 Context 表示一个应用,我们的 Tomcat 中默认的配置下 webapps 下的每一个文件夹目录都是一个 Context,其中 ROOT 目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个 Host 站点。我们访问应用 Context 的时候,如果是 ROOT 下的则直接使用域名就可以访问。
转载自 《让面试官颤抖的Tomcat系统架构!》
还没有评论,来说两句吧...