摘自:https://www.cnblogs.com/itlaobingge/p/11963286.html
Web 容器以进程的方式在计算机上运行,我们知道进程是系统资源分配的最小单元,线程是系统任务执行的最小单元。从这个角度看,Web 容器就像是邮包收件人所居住的楼宇或小区,HTTP 这套物流快递体系只能将邮包投递到楼宇前台或者小区物业等处,而楼宇前台或小区物业并不属于物流快递体系,就像 Web 容器并不属于计算机网络基础设施一样。
之所以这样分工,原因是网络路由信息由域名服务器 DNS、路由器等设备掌握,Web 容器内部体系结构信息只有它自己知道。从 Web 容器接收到 HTTP 请求,到将其投送至特定的应用,这期间还会经历一个复杂的过程,了解这个过程对于日常开发和问题分析都会有所帮助。接下来,老兵哥我将陪着你一起来剖析这个过程。
Java 语言领域的 Web 容器类型非常多,包括 Tomcat、Jetty、Resin、Websphere、Weblogic、JBoss、Glassfish、GonAS 等,其中 Tomcat 是由 Apache Software Foundation 维护的开源 Web 容器。Tomcat 市场占用率接近 60%,截止目前是最受欢迎的 Web 容器,如下图所示横跨 Web 服务器和 Java 应用服务器。
我们就以 Tomcat 为例来看看 Web 容器的内部结构,作为符合 JAVA Servlet 标准规范的容器,Tomcat 是一款基于组件的 Java Web 应用服务器,核心组件都是灵活可配的。Tomcat 最外层是 Catalina Servlet 容器,其他组件是按照特定格式要求配置在这个顶层容器当中,配置文件就是安装目录下的:/conf/server.xml。
通过这份配置文件,我们就可以了解 Tomcat 的体系结构,示例文件如下所示(快速浏览一遍,后面详细剖析):
1 <Server port="8005" shutdown="SHUTDOWN"> 2 <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> 3 <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 4 <Listener className="org.apache.catalina.core.JasperListener" /> 5 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> 6 <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 7 <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> 8 9 <GlobalNamingResources> 10 <Resource name="UserDatabase" auth="Container" 11 type="org.apache.catalina.UserDatabase" 12 description="User database that can be updated and saved" 13 factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 14 pathname="conf/tomcat-users.xml" /> 15 </GlobalNamingResources> 16 17 <Service name="Catalina"> 18 <Connector port="8080" protocol="HTTP/1.1" maxThreads=”150″ 19 connectionTimeout="20000" 20 redirectPort="8443" /> 21 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 22 <Connector port=”8443″ maxThreads=”150″ minSpareThreads=”25″ 23 maxSpareThreads=”75″ enableLookups=”false” acceptCount=”100″ 24 debug=”0″ scheme=”https” secure=”true” 25 clientAuth=”false” sslProtocol=”TLS” /> 26 <Engine name="Catalina" defaultHost="localhost"> 27 <Realm className="org.apache.catalina.realm.LockOutRealm"> 28 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 29 resourceName="UserDatabase"/> 30 </Realm> 31 32 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> 33 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 34 prefix="localhost_access_log." suffix=".txt" 35 pattern="%h %l %u %t "%r" %s %b" /> 36 </Host> 37 </Engine> 38 </Service> 39 </Server>
如果经常使用配置 Tomcat,那么你对上述配置文件一定非常熟悉。为了方便大家理解,结合本文的主题,我们把上述这份配置文件中的关键节点提取出来,然后再逐一分析介绍:
1 <Server> 2 <Service> 3 <Connector /> 4 <Connector /> 5 <Engine> 6 <Host> 7 <Context /> 8 </Host> 9 </Engine> 10 </Service> 11 </Server>
上述结构中包含了 Tomcat 的核心组件:Server 组件在最顶层,代表整个 Tomcat 容器。一个 Server 组件中可以包含一个或多个 Service 组件。Service 在 Connector 和 Engine 外面包了一层,把它们组装在一起对外提供服务。一个 Service 可以包含多个 Connector,但是只能包含一个 Engine。不同 Connector 负责接收不同端口上相应协议的请求,而 Engine 负责处理请求。Engine 包含一个或多个 Host,Host 包含一个或多个 Context,Engine、Host、Context 都属于容器组件,一个 Host 组件代表一个虚拟主机,一个 Context 组件代表在隶属 Host 上运行的一个 Web 应用。
它是整个配置文件的唯一根元素,代表整个 Tomcat 容器,内部可以包含多个 Service。Server 主要职责就是管理多个 Service,对外提供给客户端访问,同时维护所有 Service 的生命周期,包括初始化服务、结束服务、定位客户端要访问的 Service 等等。所有 Tomcat 组件的生命周期都是通过 Lifecycle 接口来控制的,组件只要继承这个接口并实现其中的方法就可以统一被父组件控制了,这样层层递进 Server 组件就可以控制所有组件的生命周期了,而控制 Server 就是通过启动和关停 Tomcat。在前面配置示例中,Server 的配置如下所示:
<Server port="8005" shutdown="SHUTDOWN">
其中,属性 shutdown 指定关闭 Server 的指令。属性 port 指定 Server 接收 shutdown 指令的端口号,设置为“-1”可以禁掉该端口。
Service 主要职责就是将 Engine 与 Connector 装配在一起对外提供服务,一个 Service 可以包含多个 Connector,但只能包含一个 Engine,其中 Connector 负责从客户端接收请求,Engine 负责处理 Connector 接收进来的请求。如前面配置示例中,Service 的配置如下所示:
<Service name="Catalina">
我们可以通过属性 name 为 Service 指定名称,不同的 Service 负责监管其下属 Connector 所绑定的端口。
Tomcat 的工作模式可以分为下面两类:
每个 Service 可以有一个或多个 Connector,不同工作模式下,Tomcat 需要为各种类型的请求分别定义相应的 Connector,这样才能正确接收客户端对应协议的请求。定义 Connector 可以使用多种属性,某些属性只适用于某种特定的 Connector 类型。一般说来,常见的 Connector 有 4 种类型:HTTP、SSL、AJP、Proxy。
作为通信接口,Connector 为其所属特定的 Service 接收外部客户端请求,以及回送应答至外部客户端。具体职责包括创建 Request、Response 对象用于跟外部客户端交换数据,并将 Request 交给配套的 Engine 来处理。通过修改 Connector 的属性取值,我们可以控制 Service 所监听的网络协议及端口号,具体示例如下:
1 <Connector port="8080" protocol="HTTP/1.1" maxThreads=”150″ 2 connectionTimeout="20000" 3 redirectPort="8443" /> 4 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 5 <Connector port=”8443″ maxThreads=”150″ minSpareThreads=”25″ 6 maxSpareThreads=”75″ enableLookups=”false” acceptCount=”100″ 7 debug=”0″ scheme=”https” secure=”true” 8 clientAuth=”false” sslProtocol=”TLS” />
原文:https://www.cnblogs.com/xichji/p/11968746.html