1、整体结构
四张图带你了解Tomcat系统架构--让面试官颤抖的Tomcat回答系列
server.xml的整体结构如下:
<Server> <Service> <Connector /> <Connector /> <Engine> <Host> <Context /><!-- 现在常常使用自动部署,不推荐配置Context元素,Context小节有详细说明 --> </Host> </Engine> </Service> </Server>
2.tomcat服务架构

2.名词解释

Server:就是提供一个接口让客户端能够访问到这个Service集合,同时维护所有的Service的声明周期,包括如何初始化、如何结束服务、如何找到客户端要访问的Service。
如:server在维护Catalina和Catalina2这两个实例
Service:称作实例;把Connector和Engine组装在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;其中Connector的作用是从客户端接收请求,Engine的作用是处理接收进来的请求。实际上,Tomcat可以提供多个Service,不同的Service监听不同的端口。
如:service 就是在给Catalina和Catalina2各自的Connector和Engine创造运行环境
Connector:一个 Connector 关联到一个 TCP 端口,负责处理 Service 与客户端之间的交互。专门创建Request和Response对象用于和请求端交换数据;然后分配线程让Engine来处理这个请求,并把产生的Request和Response对象传给Engine。
如:在上图,service 等于Catalina2中,connector就告诉了连接这个应用,有两种协议:http和ajp 以及这两种协议需要访问的端口号
注:从上面service 和connector的解释我们知道了,tomcat就是可以创建多个线程是接收和响应请求。
Engine:从一个或多个Connector中接收请求并处理,并将完成的响应返回给Connector,最终传递给客户端。他将请求重定向到host上,同时将host的处理结果又返给connector。
如:service 为Catalina2中,指定一个默认的主机。他将请求重定向到host上,同时将host的处理结果又返给connector。
Host:是运行多个Web应用(一个Context代表一个Web应用),并负责安装、展开、启动和结束每个Web应用.host就是为context指定的web应用提供一个运行环境,并且给这个环境起了一个名字,就是虚拟主机名。
如:service 为Catalina2中,host就是在设置外网可以访问的域名,(这个域名需要在DNS中注册),通过域名也给应用创建了一个独立的运行空间。
注:域名:如:www.baidu.com 为了能让大家都能解析这个DNS.所以需要去购买域名,然后公布在公共的DNS服务器上。
Context元素代表一个Web应用。在后文中,提到Context、应用或Web应用,它们指代的都是Web应用。每个Web应用基于WAR文件,或WAR文件解压后对应的目录(这里称为应用目录)。其实就是指明web应用在哪个目录下放着的。Context是Host的子容器,每个Host中可以定义任意多的Context元素。
如:service 为Catalina中,指定应用在哪儿
3.具体解释
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOWN"> <!-- port:指定一个只监听关闭Tomcat请求的端口 shutdown:向以上端口发送的关闭服务器的命令字符串 --> <Service name="Catalina"> <!-- name:给实例起名字 --> <!--系统自带,创建线程池,一般情况下是注释掉了的--> <!-- <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> -->
<!--系统自带,未创建线程池的连接器-->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<!-- A "Connector" using the shared thread pool 这个连接器使用了线程池,一般也是注释掉了的,如果需要进行线程大小定义可以打开这个,同时需要将线程池也打开-->
<!-- <Connector executor="tomcatThreadPool" port="8080"
protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
-->
<!-- port:服务器监听客户端请求的端口。
redirectPort:服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号。
connectionTimeout:等待超时的时间数(以毫秒为单位)。
protocol:通信使用的是AJP/1.3协议。 Apache HTTP 服务器处理静态请求和 PHP;Tomcat 服务器负责处理 Java Servlet/JSP
-->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <!-- defaultHost:指定了默认的host名称,当发往本机的请求指定的host名称不存在时,一律使用defaultHost指定的host进行处理; 因此,defaultHost的值,必须与Engine中某个Host组件的name属性值匹配。 --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <!--Realm 提供的是一种安全策略 --> <Host name="localhost" appBase="/opt/project/webapps" unpackWARs="true" autoDeploy="true"> <!-- name:虚拟主机名 appBase:默认的应用路径,也就是把应用放在一个目录下,并在autoDeploy为true的情况下,可自动部署应用(即:将应用放到webapps下就可以了) unpackWARs:如果为true,则tomcat会自动将WAR文件解压;否则不解压,直接从WAR文件中运行应用程序. autoDeploy:默认为true,表示如果有新的WEB应用放到appBase目录下, Tomcat会自动载入应用,不需重启 --> <Context path="/xxx" docBase="D:\Program Files \app1.war" reloadable="true"/> <!-- path:访问的URI,访问app1的应用,只需要使用:localhost:8080/xxx 就可以访问了 docBase:WEB应用的目录 这就相当于在同一个host下,运行了两个应用,他们将根据访问的url不一样,进行区分。 使用context属于静态部署 --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> <Service name="Catalina2"> <!-- 这是另外一个实例,也可以说是在该服务器上再开了一个端口,来运行另一个web应用 --> <Connector port="8084" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina2" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="/opt/project/webapps2" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
注:上面提及到的线程池,可以有两种方式实现,但是结果都是一样的:
第一种:对定义了线程池的,可以直接在线程池中配置,线程大小
第二种:没有定义线程池的,可以在<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />中直接定义线程大小。
4.应用程序的部署
第一种:自动部署(推荐)
直接使用下面的host:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
如果有应用要部署,直接放到webapps中就可以了。这种不需要停服务
第二种:静态部署(不推荐)
使用context来定义应用所在位置
<Context docBase="D:\Program Files\app1.war" reloadable="true"/>
这个就需要重启tomcat。
5、详解请求如何查找到应用的
当请求被发送到Tomcat所在的主机时,如何确定最终哪个Web应用来处理该请求呢?
(1)根据协议和端口号选定Service和Engine
每个Service中的Connector监听的都是不同的端口。在第一部分的例子中。当请求进来时,Tomcat便可以根据协议和端口号选定处理请求的Service;Service一旦选定,Engine也就确定,因一个service只能有一个engine
(2)根据域名或IP地址选定Host
Service确定后,Tomcat在engine中寻找名称与域名/IP地址匹配的Host处理该请求。如果没有找到,则使用Engine中指定的defaultHost来处理该请求。
(3)根据URI选定Context/Web应用
会根据context中的path来找到应用,
如果是自动部署,没有context 他就会在host中指定的目录下根据URI依次查找应用
(4)举例
以请求http://localhost:8080/app1/index.html为例,首先通过协议和端口号(http和8080)选定Service;然后通过主机名(localhost)选定Host;然后通过uri(/app1/index.html)选定Web应用。
6.使用80端口访问多个service
从上面我们可以知道:我们常常http协议走的都是80端口。那么在一个tomcat里,多个service就会对http协议有出现多个端口,然而80端口端口只有一个,那我们是要在多个服务器上部署tomcat,然后每个tomcat只运行一个service吗?
答案:不是。不要忘记我们的连接协议还有一个ajp。这个协议是为了让apache和tomcat协作的。
所以,我们可以让apache做为前端代理,接收HTTP 80端口的请求,按域名通过每个tomcat实例的AJP/1.3 Connector传递请求
7.tomcat的性能优化
https://blog.csdn.net/huiyunfei/article/details/79165120
浙公网安备 33010602011771号