用Tomact好长时间了,终于可以抽象时间停下来,总结一下有关Tomact的内容了。
我们知道运行Tomact之后,需要对Tomact进行一些个性化的配置,大多数Tomact的配置文件放置在$CATALINA_HOME/conf下面,主要有以下几个文件
server.xml:Tomact的核心配置文件,用于配置服务器
web.xml:Servlet的标准配置文件,作用于所有站点,如果只在web项目中的话,那么只作用于单个web项目。
tomact-users.xml:用于配置的Tomact用户验证的角色,用户和密码;
catalina.policy:Tomact安全策略配置
上面四个基本上就是Tomact的最主要的几个配置文件,这篇博客就来分析第一个配置文件server.xml
<span style="font-family:Comic Sans MS;font-size:18px;"><?xml version='1.0' encoding='utf-8'?> <!--顶层元素,代表整个容器,可以包含多个Service --> <Server port="8005" shutdown="SHUTDOWN" debug="10"> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.security.SecurityListener" /> <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> <!--连接器元素,由一个或者多个Connector和一个Engine组成 ,负责所有Connector所获得的客户请求 --> <Service name="Catalina"> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> <!-- 一个Connector将在某个指定端口上,侦听客户请求,并将获得的请求交个Engine来处理 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <!--容器类元素,可以包含多个Virtual Host元素,每个虚拟主机都有一个域名。当Engine获得一个Connector发出的Http请求时,它把该请求匹配到某个Host上 然后把请求交个该Host来处理。Engine有一个默认虚拟主机localhost,当请求无法匹配到任何一个Host上的时候,将交给该默认的Host来处理 --> <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> <Engine name="Catalina" defaultHost="localhost"> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <!-- 定义一个虚拟主机,每个虚拟主机都和某个DNS相匹配,每个虚拟主机下都可以部署一个或者多个Web App,每个Web App对应于一个Context,当Host获得一个请求时,将把该请求匹配到某个Context上 --> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Valve className="org.apache.catalina.valves.RemoteAddrValve" addConnectorPort="true" invalidAuthenticationWhenDeny="true" allow=".*;8009"/> </Host> </Engine> </Service> </Server> </span>
下面通过一个客户的请求为例子,来分析一下整个过程。假设来自客户的请求为:http://localhost:8080/test/index.jsp
(1)请求被发送到本机端口8080,被那里侦听的HTTP Connector获得
(2)Connector把该请求交给它所在的Servcie的Engine来处理,并等待来自Engine的响应。
(3)Engine获得请求localhost/test/index.jsp,匹配它所拥有的虚拟主机Host;
(4)Engine匹配到名为localhost的Host(即使匹配不到也把该请求交给Host处理),因为该Host被定义为当前Engine的默认主机
(5)localhost Host获得请求/test/index.jsp,匹配它所有拥有的所有Context;
(6)Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“”处理)
(7)path="/test"的Context获得请求/index.jsp,在它的mapping table中寻找对应的Servlet
(8)Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类;
(9)HttpServletRequest对象和HttpServeltResponse对象,作为参数调用JspServlet的doGet和doPost请求
(10)Context把执行完了之后的HttpServeltResponse对象返回给Host
(11)Host把HttpServletResponse对象返回给Engine
(12)Engine把HttpServletResponse对象返回给Connector
(13)Connector把HttpServletResponse对象返回给客户浏览器
上面就是整个执行过程。