优质博文:IT-BLOG-CN
【1】Server:Server元素在最顶层,代表整个 Tomcat容器,因此他必须是 server.xml中唯一一个最外层的元素。一个 Server元素可以有一个或多个 Service元素。
<Server port="8005" shutdown="SHUTDOWN">
</Server>
可以看到,最外层有一个 <Server>
元素,shutdown 属性表示关闭 Server的指令;port 属性表示 Server接收 shutdown指令的端口号,设置为-1可以禁掉该端口。Server 的主要任务,就是提供一个接口让客户端能够访问到这个 Service集合,同时维护它所包含的所有的 Service的生命周期,包含如何初始化,如何结束服务,如何找到客户端要访问的 Service。
【2】Service:在 Connector 和 Engine外面包一层,把它们组合在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;其中 Connector 的作用是从客户端接收请求,Engine 的作用是处理接收进来的请求。
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"></Service>
</Server>
如上图,Server 中包含一个名称为 “Catalina” 的Service。实际上,Tomcat 可以提供多个 Service,不同的 Service监听不同的端口。
【3】Connector:接收连接请求,创建 Request 和 Response对象用于和请求端交换数据;然后分配线程让 Engine来处理这个请求,并把产生的 Request 和 Response对象传给 Engine。通过配置 Connector,可以控制请求 Service的协议及端口号。
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /></Service>
</Server>
通过配置第一个 Connector,客户端可以通过 8080端口号协议访问 Tomcat。其中,protocol 属性规定了请求的协议,port 规定了请求的端口号,redirectPort 表示当强制要求 https而请求是 http时,重定向至端口号为 8443的Connector,connectionTimeout表示连接的超时时间。
在这个例子中,Tomcat 监听 Http请求,使用的是 8080端口,而不是正式的 80端口;实际上,在正式的生产环境中,Tomcat也常常监听8080端口。而不是80端口。这是因为在生产环境中,很少讲 Tomcat直接对外开放接收请求,而是在 Tomcat和客户端之间加一层代理服务器(如Nginx),用于请求的转发、负载均衡、处理静态文件等;通过代理服务器访问 Tomcat时,是在局域网中,因为一般仍使用8080端口。
第二个配置 Connector,客户端可以通过 8009端口使用 AJP协议访问 Tomcat。AJP协议负责和其他的Http服务器(如Apache)建立连接;在把 Tomcat与其他服务器集成时,就需要用到这个连接器,之所以使用 Tomcat和其他服务器集成,是因为 Tomcat可以用作 Servlet/JSP容器,但是对静态资源处理速度较慢,不如 Apache和 IIS等 HTTP服务器;因此常常将 Tomcat和 Apache等集成,前者做 Servlet容器,后者处理静态资源,而 AJP协议便负责 Tomcat与 Apache的连接。Tomcat 和 Apache等集成的原理如下图:
【4】Engine:Engine 组件在 Service 组件有且只有一个;Engine 是 Service组件中的请求处理组件。Engine组件从一个或多个Connector 中接收并处理,并将完成的响应返回给 Connector,最终传递给客户端。前面说到,Engine、Host 和 Context都是容器,但是它们不是平行关系,而是父子关系:Engine 包含 Host,Host 包含 Context。
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /><Engine name="Catalina" defaultHost="localhost"></Engine></Service>
</Server>
其中 name属性用于日志和错误信息,在整个 Server中应该是唯一的。defalutHost 属性指定了默认的 host名称,当发往本机的请求指定的 host名称不存在时,一律使用 defaultHost指定的 host进行处理;因此 defaulthost的值,必须与 Engine中的一个Host组件的 name属性值匹配。
【5】Engine 和 Host:Host 是 Engine的子容器。Engine 组件中可以内嵌1个或者多个 Host组件,每个 Host组件代表 Engine中的一个虚拟主机。Host组件至少有一个,且其中一个的 name必须与 Engine组件中的 defaultHost属性相匹配。
【6】Host 的作用:Host 虚拟主机的作用,是运行多个 Web应用(一个 Context 代表一个 Web应用),并负责安装、展开、启动、结束每个 Web应用。Host 组件代表的虚拟主机,对应服务器中一个网络名实体(如"www.test.com"或IP地址"116.25.25.25");为了使用户可以通过网络名连接Tomcat服务器,这个名字应该在DNS服务器上注册。
客户端通常使用主机名来标识它们希望连接的服务器,该主机名也会包含在 HTTP请求头中,Tomcat 从 HTTP头中提取出主机名,寻找名字匹配的主机。如果没有匹配,请求会发送至默认的主机。因此默认主机不需要再 DNS服务器中注册网络名,因为任何与所有 Host名称不匹配的请求,都会路由至默认主机。
【7】Host 的配置:name 属性指定虚拟主机的主机名,一个 Engine有且只有一个 Host组件的 name属性和 Engine组件的 defaultHost属性相匹配;一般情况下,主机名需要是在 DNS服务器中注册网络名,但是 Engine指定的 defaultHost不需要。
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /><Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /><Engine name="Catalina" defaultHost="localhost"><Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"></Host></Engine></Service>
</Server>
unpackWARs 指定了是否将代表 Web应用的 WAR文件解压;如果是 true,通过解压后的文件结构运行该 Web应用,如果是false,直接使用 WAR文件运行 Web应用。
【8】Context:Context元素代表在虚拟主机上运行的一个Web应用。在后文中,提到 Context、应用或 Web应用,他们都代指Web应用,每个 Web应用基于 WAR文件,或 WAR文件解压后对应的目录(这里称为应用目录)Context 是 Host 的子容器,每个 Host 都可以定义任意多的 Context元素。<Context>
元素的配置:Context 元素最重要的属性是 docBase 和 path,此外reloadable 属性也比较常用。
docBase 指定了该 Web应用使用 war包路径,或应用目录。需要注意的是:在自动部署场景下(配置文件位于 xmlBase中),docBase 不在 appBase目录中,才需要指定;如果 docBase指定的 war包或应用目录就在 appBase中,则不需要指定。因为 Tomcat会自动扫描 appBase中的 war包和应用目录,制定了反而造成问题。
path 指定了访问该Web应用上下文路径,当请求到来时,Tomcat 根据 Web应用的 path属性与 URL匹配程度来选择 Web应用处理相应请求。例如:Web 应用 app1的 path属性是"/app1",Web应用 app2的path属性是"/app2",那么请求/app1/index.html会交由app1来处理;而请求 /app2/index.html会交由 app2来处理。如果一个 Context元素的 path属性为"",那么这个Context是虚拟主机的默认的 Web应用;当请求的uri与所有的 path都不匹配时,使用该默认Web应用来处理。
但是,需要注意的是,在自动部署场景(配置文件位于xmlBase中),不能指定path属性,path属性由配置的文件的文件名,WAR文件的文件名或应用目录的名称自动推导出来。如扫描 Web应该时,发现xmlBase目录下的app1.xml,或appBase目录下的 app1.WAR或 app1应用目录,则该Web用于的path属性是"app1"。如果名称不是app1而是ROOT,则该Web应用时虚拟主机默认的Web应用,此时path属性推导为""。
reloadable属性指示tomcat是否在运行时监控在 WEB-INF/classes和WEB-INF/lib目录下class文件的改动。如果值为 true,那么当 class文件改动时,会重新 web应用的重新加载。在开发环境下,reloadable 设置为 ture便于调试;但是在生产环境中设置为 true会给服务器带来性能压力,因此reloadable参数的默认值为false。在该例子中,docBase 位于 Host的 appBase目录之外;path属性没有指定,而是根据 app1.xml自动推导为 “app1”。
<Context docBase="D:\Program Files\app1.war" reloadable="true"></Context>
若是自动部署(即 autoDeploy=“true”),那么 server.xml配置文件中没有 Context元素的配置。这是因为 Tomcat开启了自动部署,Web应用没有在 server.xml中配置静态部署,而是由 Tomcat通过特定的规则自动部署。