文件结构
| <server> |
| <service> |
| <connector PORT /> |
| <engine> |
| <host name=www.a.com appBase=/www/a > |
| <context path="" docBase=/www/a /> |
| <context path="/xuexi" docBase=/www/a/xuexi /> |
| </host> |
| |
| <host> |
| <context /> |
| </host> |
| </engine> |
| </service> |
| </server> |
解释
1、server组件是管理tomcat实例的组件,可以监听一个端口,从此端口上可以远程向该实例发送shutdown关闭命令。
2、service组件是一个逻辑组件,用于绑定connector和container,有了service表示可以向外提供服务,
| 就像是一般的daemon类服务的service。可以认为一个service就启动一个JVM,更严格地说, |
| 一个engine组件才对应一个JVM(定义负载均衡时,jvmRoute就定义在Engine组件上用来标识这个JVM), |
| 只不过connector也工作在JVM中。 |
3、connector组件是 监听组件,它有四个作用:
(1).开启监听套接字,监听外界请求,并和客户端建立TCP连接;
(2).使用protocolHandler解析请求中的协议和端口等信息,如http协议、AJP协议;
(3).根据解析到的信息,使用processer将分析后的请求转发给绑定的Engine;
(4).接收响应数据并返回给客户端。
4、container是容器,它是一类组件,在配置文件(如server.xml)中没有体现出来。它包含4个容器类组件:engine容器、host容器、context容器和wrapper容器。
5、engine容器用于从connector组件处接收已建立的TCP连接,还用于接收客户端发送的http请求并分析请求,然后按照分析的结果将相关参数传递给匹配出的虚拟主机。engine还用于指定默认的虚拟主机。
6、host容器定义虚拟主机,由于tomcat主要是作为servlet容器的,所以为每个webapp指定了它们的根目录appBase。
7、context容器主要是根据path和docBase获取一些信息,将结果交给其内的wrapper组件进行处理(它提供wrapper运行的环境,所以它叫上下文context)。一般来说,都采用默认的标准wrapper类,因此在context容器中几乎不会出现wrapper组件。
8、wrapper容器对应servlet的处理过程。它开启servlet的生命周期,根据context给出的信息以及解析web.xml中的映射关系,负责装载相关的类,初始化servlet对象init()、执行servlet代码service()以及服务结束时servlet对象的销毁destory()。
9、executor 组件为每个Service组件提供线程池,使得各个connector和Engine可以从线程池中获取线程处理请求(connector),从而实现tomcat的并发处理能力。一定要注意,Executor的线程池大小是为Engine组件设置,而不是为Connector设置的,Connector的线程数量由Connector组件的acceptorThreadCount属性来设置。如果要在配置文件中设置该组件,则必须设置在Connector组件的前面,以便在Connector组件中使用executor属性来引用配置好的Executor组件。如果不显式设置,则采用Connector组件上的默认配置,默认配置如下:
(1). maxThreads:最大线程数,默认值200。
(2). minSpareThreads:最小空闲线程数,默认值25。
(3). maxIdleTime:空闲线程的线程空闲多长时间才会销毁,默认值60000即1分钟。
(4). prestartminSpareThreads:是否启动executor时就直接创建等于最小空闲线程数的线程,默认值为false,即只在有连接请求进入时才会创建。
根据上面描述的tomcat组件体系结构,处理请求的大致过程其实很容易推导出来:
Client(request)–>Connector–>Engine–>Host–>Context–>Wrapper(response data)–>Connector(response header)–>Client
撇开tomcat作为servlet容器的行为。它和apache、nginx的功能大致都能对应上。例如以nginx为例,以下是nginx提供web服务时的配置结构:
| server { |
| listen PORT; |
| server_name www.a.com; |
| location / { |
| root html; |
| } |
| location /xuexi { |
| root html/xuexi; |
| } |
| } |
engine组件则没有对应配置项,engine内可以包含多个host虚拟主机,这个功能nginx里也有
更多内容见
https://blog.csdn.net/agonie201218/article/details/110495766
https://www.cnblogs.com/kismetv/p/7228274.html
connector连接器可以对外暴漏http协议、也可以暴漏AJP协议
server.xml配置如下
| <?xml version="1.0" encoding="UTF-8"?> |
| <Server port="8005" shutdown="SHUTDOWN"> |
| <Listener className="org.apache.catalina.startup.VersionLoggerListener"/> |
| <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> |
| <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/> |
| <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/> |
| <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/> |
| <GlobalNamingResources> |
| <Resource name="UserDatabase" auth="Container" |
| type="org.apache.catalina.UserDatabase" |
| description="User database that can be updated and saved" |
| factory="org.apache.catalina.users.MemoryUserDatabaseFactory" |
| pathname="conf/tomcat-users.xml"/> |
| </GlobalNamingResources> |
| <Service name="Catalina"> |
| <Connector port="8080" protocol="HTTP/1.1" |
| connectionTimeout="20000" |
| redirectPort="8443" |
| maxParameterCount="1000" |
| /> |
| <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/> |
| <Engine name="Catalina" defaultHost="localhost"> |
| <Realm className="org.apache.catalina.realm.LockOutRealm"> |
| <Realm className="org.apache.catalina.realm.UserDatabaseRealm" |
| resourceName="UserDatabase"/> |
| </Realm> |
| |
| <Host name="www.egon1.com" appBase="/test1" unpackWARs="true" autoDeploy="true"> |
| <Context path="" docBase="/test1" reloadable="true" /> |
| <Context path="/test_uri1" docBase="xxx" reloadable="true" /> |
| <Context path="/test_uri2" docBase="yyy" reloadable="true" /> |
| </Host> |
| <Host name="www.egon2.com" appBase="/test2" unpackWARs="true" autoDeploy="true"> |
| <Context path="" docBase="" reloadable="true" /> |
| <Context path="/test_uri3" docBase="zzz" reloadable="true" /> |
| </Host> |
| <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> |
| </Host> |
| </Engine> |
| </Service> |
| </Server> |
创建目录
| mkdir /test1 |
| mkdir /test1/xxx |
| mkdir /test1/yyy |
| |
| mkdir /test2 |
| mkdir /test2/zzz |
测试代码index.jsp翻到上面五个文件夹下,输出内容分别是111、222、333、444、555
| <%@ page language="java" %> |
| <%@ page import="java.util.*" %> |
| <html> |
| <body> |
| <% out.println("hello world 111"); %> |
| </body> |
| </html> |
最后重启catalina。
| catalina.sh stop |
| catalina.sh start |
C:\Windows\System32\drivers\etc\hosts中添加如下记录:
| 192.168.71.238 www.egon1.com www.egon2.com |
有时候因为个人环境的问题影响有的浏览器会不支持多虚拟主机,换个浏览器测试就好(我用谷歌就不行,用火狐可能)
以下的访问都是匹配的context path=”具体的uri路径的” 的情况,uri路径匹配成功后,会去appBase/docBase里找index.jsp
| [root@web03 /tmp/tomcat]# curl www.egon1.com:8080/test_uri1/ |
| |
| hello world 222 |
| |
| |
| |
| [root@web03 /tmp/tomcat]# |
| [root@web03 /tmp/tomcat]# curl www.egon1.com:8080/test_uri2/ |
| |
| hello world 333 |
| |
| |
| |
| |
| [root@web03 /tmp/tomcat]# curl www.egon2.com:8080/test_uri3/ |
| |
| hello world 555 |
| |
| |
| |
| |
以下的访问都是匹配的context path=”” 的情况
用域名www.egon1.com:8080访问
访问www.egon1.com:8080/xxx
访问www.egon1.com:8080/yyy
用域名www.egon2.com:8080/访问
访问:www.egon2.com:8080/zzz