Tomcat基本组件、其功能和处理请求的过程
一、Tomcat是一个基于组件的服务器,它的构成组件都是可配置的,其中最外层的组件是Catalina Servlet容器,其他的组件按照一定的格式要求配置在这个顶层容器中
Tomcat的各个组件是在<TOMCAT_HOME>\conf\server.xml文件中配置的,如下:
XML配置文件结构
<Server> 顶层类元素:一个配置文件中只能有一个<Server>元素,可包含多个Service。
<Service> 顶层类元素:本身不是容器,可包含一个Engine,多个Connector。
<Connector/> 连接器类元素:代表通信接口。
<Engine> 容器类元素:为特定的Service组件处理所有客户请求,可包含多个Host。
<Host> 容器类元素:为特定的虚拟主机处理所有客户请求,可包含多个Context。
<Context> 容器类元素:为特定的Web应用处理所有客户请求。
</Context>
</Host>
</Engine>
</Service>
</Server>
server.xml文件的基本组成结构如下
1.Server组件
A Server element represents the entire Catalina servlet container. Therefore, it must be the single outermost element in the conf/server.xml configuration file. Its attributes represent the characteristics of the servlet container as a whole.
一个Server组件代表整个Catalina servlet容器,所以它在server.xml配置文件中必须是单个最外层元素,它的属性代表整个servlet容器的特性, 一个Server组件由一个或多个service组件组成
Common Attributes(通用属性):
1.ClassName 一个实现了org.apache.catalina.Server接口的类,如果不指定,将使用标准实现类
org.apache.catalina.core.StandardServer.
2.address 一个TCP/IP地址,默认localhost,用于指定server组件等待shutdown(关闭服务器)指令的ip地址
3.port 一个TCP/IP端口,用于指定server组件等待shutdown(关闭服务器)指令的port端口,如果设置-1,将使shutdown port失效
4.shutdown 一个命令字符串,为了关闭服务器,必须将该命令字符串通过指定ip和端口传给该Server组件
2.service组件
A Service element represents the combination of one or more Connector components that share a single Engine component for processing incoming requests. One or more Service elements may be nested inside a Server element.
一个Service组件由一个或多个Connector连接器组件组成,并且这个Service中的Connector共享一个Engine组件
Common Attributes(通用属性):
1.className 一个实现了org.apache.catalina.Service接口的类,如果不指定,将使用标准实现类org.apache.catalina.core.StandardService
2.name Service组件的展示名,如果使用标准的Catalina组件该名称将包含在log信息中,必须保持唯一性
3.Executor组件(thread pool)
The Executor represents a thread pool that can be shared between components in Tomcat.
Executor组件代表在Tomcat各组件之间可共享的一个线程池,一直以来,每个被创建的Connector组件都有自己的一个线程池,但是允许你在多个Connector之间共享一个线程池
Common Attributes(通用属性):
1.className 一个实现了org.apache.catalina.Executor 接口的类,该接口确保了两件事,1.通过它的name属性能够找到该接口实现类,2实现类的生命周期 在容器中的开始和结束,如果不指定,将使用标准实现类org.apache.catalina.core.StandardThreadExecutor
2.name 该name被用来在server.xml中其它地方获取该线程池,必须保持唯一性
默认实现类 还支持下面的属性:
1.threadPriority 该线程池线程的优先级 默认为the Thread.NORM_PRIORITY constant = 5
2.daemon 制定线程是否为守护线程(后台线程)
3.namePrefix 被该线程池创建的线程的名称前缀,线程名称组成:namePrefix+threadNumber
4.maxThreads 最大活跃线程数,默认200
5.minSpareThreads 最小活跃线程数,默认25
6.maxIdleTime 在线程数大于minSpareThreads时,一个空闲线程关闭前等待时间为多少毫秒,默认60000ms(1分钟)
7.maxQueueSize 可排列等待可用线程的可运行的最大任务数,默认Integer.MAX_VALUE
8.prestartminSpareThreads 开始Executor组件时,是否开始minSpareThreads,默认false
9.threadRenewalDelay 如果配置ThreadLocalLeakPreventionListener ,它将在更新线程池中线程前,通知Executor组件停止Context组件。 该参数为零避免在同一时间刷新所有线程,所以可设置两个线程刷新时间间隔,ms,默认1000ms,If value is negative, threads are not renewed.
4.Connector组件
A "Connector" represents an endpoint by which requests are received and responses are returned.
Connector组件是接收请求和返回响应的端点,Tomcat服务器通过Connector连接器组件与客户程序建立连接,负责接收客户的请求,以及把Tomcat服务器的响应结果发送给客户
默认的两种连接器
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443”/>
<Connector port=“8009" protocol="AJP/1.3" redirectPort="8443”/>
第一个连接器监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。
第二个连接器监听8009端口,负责和其他的HTTP服务器建立连接。在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器
Attributes(通用属性):
1.allowTrace 是否**TRACE HTTP method,boolean值 ,默认false
2.asyncTimeout 指定异步请求超时时间,单位ms,默认30000ms(30秒)
3.enableLookups 如果设置true,request.getRemoteHost() 将通过执行 DNS lookups(DNS查找)返回远程客户端实际的主机名称,如果设置false,将跳过DNS查找。默认false
4.maxHeaderCount 指定一个请求的最大请求头数量,如果超过该请求头数量的请求将被拒绝,设置<0,意味不做限制。默认100
5.maxParameterCount 指定请求参数值对的最大数量(get加Post),在这个数量内的参数,能够自动被容器解析。超过的将被忽略,该值<0意味不做限制,默认10000.注意: Fail6edRequestFilter能够用来拒绝请求,可以用来打破该限制
6.maxPostSize 指定能够被容器FORM URL parameter解析的最大字节数量。如果设置<=0将不做限制,默认2097152 (2 megabytes)
7.maxSavePostSize 指定 FORM or CLIENT-CERT authentication期间,容器缓存POST请求的最大子节数。设置-1表示不做限制,0表示不缓存,默认4096 (4 kilobytes)
8.parseBodyMethods 一个逗号分隔的HTTP方法列表,该列表中的请求体的参数将被解析, 默认POST
9.port Connector将在该端口创建一个server socket并等待连接。操作系统只允许一个server应用在一个指定ip地址下监听一个端口。如果设置为0,Tomcat将随机为gaiConnect组件分配一个空闲port。
10.protocol 设置处理请求的协议,默认是HTTP/1.1 ,该协议将使用一个自动切换机制来选择是用一个非阻塞的java NIO的连接器,还是用一个APR /本地连接器。主要是根据PATH (Windows) or LD_LIBRARY_PATH (on most unix systems)环境变量中是否包含Tomact本地库,如果包含将采用后者,否则前者。对于APR /本地连接器对于HTTPS的设置将有别于非阻塞的java NIO的连接器。
To use an explicit protocol rather than rely on the auto-switching mechanism described above, the following values may be used:
org.apache.coyote.http11.Http11Protocol - blocking Java connector
org.apache.coyote.http11.Http11NioProtocol - non blocking Java NIO connector
org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java NIO2 connector
org.apache.coyote.http11.Http11AprProtocol - the APR/native connector.
11.proxyName Connector组件正在使用代理配置,表示request.getServerName()的返回值
12.proxyPort Connector组件正在使用代理配置,表示request.getServerPort()的返回值
13.redirectPort 如果此连接器支持非SSL请求,并接收到一个请求,一个匹配的<<安全约束>要求SSL传输,卡特琳娜自动将请求重定向到指定的端口号。
14.scheme request.getScheme()的返回值,默认http,如果你希望是https可以修改成https
15.secure 设置request.isSecure()的返回值,默认false
16.URIEncoding 指定在解码URL后,用于解码URI字节的字符编码,默认 UTF-8 。但是在system property中设置org.apache.catalina.STRICT_SERVLET_COMPLIANCE 参数为true,那么ISO-8859-1将被使用
17.useBodyEncodingForURI 该参数用于指定是否用contentType中指定的编码用于URI查询参数,而不用上面的URIEncoding编码。默认false。注意该参数只正对请求的查询参数有用,并不影响path部分。如果各种其它编码设置都都指定,默认编码都是ISO-8859-1
18.useIPVHosts 将此属性设置为true,将导致Tomcat使用接收请求的IP地址,来确定将请求发送到哪个Host主机。默认false
19.xpoweredBy Set this attribute to true to cause Tomcat to advertise support for the Servlet specification using the header recommended in the specification。默认false。
5.Engine组件
An Engine represents the entry point (within Catalina) that processes every request.
Engine组件是处理客户请求的入口,代表整个处理请求的机构,一个Engine组件可以包含多个Host组件
Attributes(通用属性):
1.backgroundProcessorDelay 设置engine后台程序和它的子容器(组件)后台程序方法调用的时间间隔。如果延迟值不是负值(这意味着他们正在使用自己的处理线程),则不会调用子容器。默认是10s延迟
2.className 一个实现了org.apache.catalina.Engine接口的类,如果不指定,将使用标准实现类org.apache.catalina.core.StandardEngine
3.defaultHost 制定处理请求的主机名称
4.jvmRoute
5.name 代表该Engine的逻辑名称,被用在日志和错误信息中,在同一个Server组件中,当有多个service组件,则该名称必须保持唯一性
6.startStopThreads 指定该Engine组件并行启动Host组件的线程数,如果1.设置为0,则采用Runtime.getRuntime().availableProcessors()的返回值作为线程数,2.设置<0,则采用Runtime.getRuntime().availableProcessors() + value,如果(Runtime.getRuntime().availableProcessors() + value)<1,则为1。如果不指定,默认为1;
6.Host组件
一个Host组件代表一个虚拟主机,一个Host组件可以包含多个Context组件(web应用)。tomcat会根据请求的域名找到对应的Host,如果找不到会使用默认的Host及名为localhost的Host。
Attributes(通用属性):
1.appBase 指定虚拟主机的基本目录(发布应用的目录(webapps)),可以是绝对路径,也可以是相对$CATALINA_BASE directory的路径,默认是webapps
2.xmlBase 指定虚拟主机的XML基本目录,是一个包含context xml的目录。默认是conf/<engine_name>/<host_name>
3.createDirs 如果设置为true,会创建appBase and xmlBase属性指定的目录,默认true
4.autoDeploy 这个标志值指示Tomcat运行时是否应该定期检查新的或更新的web应用程序,如果是真的,Tomcat的定期检查appbase和xmlbase目录,如果呦更新的web应用程序或上下文xml描述符将触发web应用程序的重载。默认为true
5.backgroundProcessorDelay 设置Host后台程序和它的子容器(组件)后台程序方法调用的时间间隔。默认-1,这意味着主机将依赖其父引擎的后台处理线程
6.className 一个实现了org.apache.catalina.Host接口的类,如果不指定,将使用标准实现类org.apache.catalina.core.StandardHost
7.deployIgnore 在 autoDeploy and deployOnStartup 被设置的情况下,可以指定被忽略的目录,这是一个相对appBase的目录。指定的目录下的文件则不会被部署。可以是”.*foo.*”的表达式。
8.deployOnStartup 指定该host下的web应用在Tomcat启动时是否自动部署,默认true
9.failCtxIfServletStartFails 如果指定为true,在配置有, load-on-startup >=0的servlet启动失败,则对应的web应用也启动失败, 默认值是false。
10.name 指定Host组件的名称。该名称必须在你的Domain Name Service server有注册。除类localhost
11.startStopThreads 同Engine组件该参数的逻辑
12.undeployOldVersions 不部署旧版本的应用,默认值false
7.Context组件
一个Context组件代表一个web应用,context name 必须唯一,而context path可以不唯一。另外,有一个特殊的context有被提供,它的context path为””,这个是一个默认的context,它被用来处理所有没被其他context path匹配的请求
###名称对应表
Attributes(通用属性):
1.allowCasualMultipartParsing 如果为true,tomcat将自动解析 multipart/form-data数据。默认false
2.backgroundProcessorDelay 同Engine对应属性原理一样
3.className 一个实现了org.apache.catalina.Context接口的类,如果不指定,将使用标准实现类 org.apache.catalina.core.StandardContext
4.docBase web应用基本目录
5.path web应用的context path。如果指定为””,则表示该应用为该Host的默认应用。
二、Tomcat处理一个HTTP请求的过程
假设来自客户的请求为: http://localhost:8080/zhangboqing/welcome.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost:8080/zhangboqing/welcome.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/zhangboqing/welcome.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/zhangboqing的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7) path="/zhangboqing"的Context获得请求/welcome.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser