深入解读Tomcat (一)

来源:互联网 发布:vb 如何获取窗体控件 编辑:程序博客网 时间:2024/05/16 05:33


/**
*作者:annegu
*日期:2009-06-16
*/

出处:http://annegu.iteye.com/blog/409176 


首先搞清楚几个概念:Servlet容器与web容器。Servlet容器的主要任务是管理servlet的生命周期,而web容器更准确的说应该叫web服务器,它是来管理和部署web应用的。还有一种服务器叫做应用服务器,它的功能比web服务器要强大的多,它可以部署EJB应用,可以实现容器管理的事务,一般的应用服务器有weblogic和websphere等,它们都是商业服务器,功能强大但都是收费的。web容器最典型的就是tomcat,apache了。

Tomcat是一个免费的开源的Serlvet容器,也就是说它可以处理servlet请求。但它也不仅仅是一个servlet容器,它也是一个web容器,具有传统web服务器的功能,比如处理html页面等。但是它处理静态html,css,js的能力不如Apache,Apache只是web容器,不能用来处理jsp和servlet请求,但是它在对文字,图片,js,css等内容的请求有自己的一套管理方法,非常优秀,因此一般用来处理对这类静态资源的请求。因此,我们可以在部署应用的时候把tomcat和apache结合起来,让apache来负责处理静态资源的请求,而tomcat用来负责解析动态的jsp和servlet的请求。

在 Tomcat中,应用程序的部署很简单,只要讲应用打成WAR包,放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压。通常在浏览器中第一次访问某个应用的jsp时,速度都会比较慢,这是因为Tomcat要将jsp解析成servlet文件,然后进行编译。编译过一次之后,以后再次访问这个页面,速度就会很快了。另外 Tomcat也提供了一个应用:manager,访问这个应用需要用户名和密码,用户名和密码存储在一个xml文件中。通过这个应用,辅助于Ftp,可以在远程通过Web部署和撤销应用。当然本地也可以。

在了解tomcat是如何工作的之前,先了解一下tomcat server的组成(为了对层次结构理解的更清晰,我们结合着下图来看):



① Server
一个server代表了整个catalina servlet容器,其实就是BackGroud程序,在Tomcat里面的Server的用处是启动和监听服务端事件(诸如重启、关闭等命令)。

② Service
Service是由一个或多个Connector与一个Engine的组合。这些Connector共享一个Engine来处理请求。

③ Connector
Connector将在某个指定的端口上来监听客户的请求,把从socket传递过来的数据,封装成Request,传递给Engine来处理,并从Engine处获得响应并返回给客户。
Tomcat通常会用到两种Connector:
a) Http Connector 在端口8080处侦听来自客户browser的http请求。
b) AJP Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求。

④ Engine
负责处理来自相关联的service的所有请求,处理后,将结果返回给service,而connector是作为service与engine的中间媒介出现的。
一个engine下可以配置多个虚拟主机,每个虚拟主机都有一个域名。当engine获得一个请求时,它把该请求匹配到某个虚拟主机(host)上,然后把请求交给该主机来处理。
Engine有一个默认主机,当请求无法匹配到任何一个虚拟主机时,将交给默认host来处理。

⑤ Host
代表一个虚拟主机,每个虚拟主机和某个网络域名(Domain Name)相匹配。
每个虚拟主机下都可以部署一个或多个web应用,每个web应用对应于一个context,有一个context path。
当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理匹配的方法是“最长匹配”,所以一个path==””的Context将成为该Host的默认Context所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配。

⑥ Context
一个Context对应于一个Web应用,一个Web应用由一个或者多个Servlet组成Context在创建的时候将根据配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servlet类。当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类,如果找到,则执行该类,获得请求的回应,并返回。


在Container这层,包含了3种容器:Engine,Host,Context。容器里面又盛装着各种各样的组件,可以理解为提供各种各样的增值服务。
Manager:当一个容器里面装了manager组件后,这个容器就支持session管理了, 事实上在tomcat里面的session管理,就是靠的在context里面装的manager component。
Logger:当一个容器里面装了logger组件后,这个容器里所发生的事情,就被该组件记录下来了。我们通常会在logs/这个目录下看见catalina_log.time.txt以及localhost.time.txt和localhost_examples_log.time.txt。这就是因为我们分别为:engine,host以及context(examples)这三个容器安装了logger组件,这也是默认安装,又叫做标配。

下面我们来了解一下tomcat中的主要的配置文件:
① Server.xml
这个文件描述了如何启动tomcat server。

a) 在这个文件的开头我们就可以看到“<Server port="8005" shutdown="SHUTDOWN" debug="0">”,前面说到Tomcat里的Server的用处是启动和监听服务端事件,这里的“SHUTDOWN”就是server在监听服务端事件的时候所使用的命令字,server在端口8005处等待关闭命令,如果接收到”SHUTDOWN”字符串则关闭服务器。

b) 下面看一下connector的配置:

Java代码 复制代码 收藏代码
  1. <Connector port="8080" protocol="HTTP/1.1" URIEncoding="GBK"  
  2. maxThreads="150"      
  3.           minSpareThreads="25"      
  4.           maxSpareThreads="75"    
  5.           acceptCount="100"  
  6.           connectionTimeout="20000"   
  7.           redirectPort="8443" />  

        
port:表示在端口号8080处侦听来自客户browser的HTTP1.1请求。
minProcessors :该Connector先创建5个线程放入线程池中等待客户请求,每个客户请求由一个线程负责。
minSpareThreads:表示线程池中将始终保持有这么多个线程,即使没有人用也将开这么多空线程等待。
maxSpareThreads:表示线程池中最多可以保留的空闲线程数,例如maxSpareThreads=75,某时刻有80个请求在访问服务器,然后访问结束,这80个空闲的线程不会都保留下来,tomcat会关闭5个空闲线程,最多只保留75个空闲的线程。
maxThreads:线程池中的最大线程数量,表示服务器可以最多同时处理这么多个连接请求。当线程池中现有的线程不够服务客户请求时,若线程总数不足maxThreads,则创建新线程来处理请求。
acceptCount :当现有线程已经达到最大数maxThreads时,接下来的客户请求将进入请求队列中进行排队,当排队队列中请求数超过acceptCount时,后来的请求将对其返回Connection refused错误。
redirectport :当客户请求是https时,把该请求转发到端口8443去。

c) Engine的配置
Engine用来处理Connector收到的http请求,它将请求匹配到自己的某个虚拟主机上,并把请求转交给对应的host来处理。默认的虚拟主机是localhost。
Java代码 复制代码 收藏代码
  1. <Engine name="Catalina" defaultHost="localhost">  


d) 虚拟主机host的配置
Java代码 复制代码 收藏代码
  1. <Host name="localhost"  appBase="webapps"  
  2.       unpackWARs="true" autoDeploy="true"  
  3.       xmlValidation="false" xmlNamespaceAware="false">  

appBase表示了该虚拟主机localhost的根目录是webapps/,虚拟主机会将请求匹配到自己的context路径上,并把请求转交给对应的context来处理。

e) Context的配置
Java代码 复制代码 收藏代码
  1. <Context path="/adv" reloadable="false" docBase="E:\workspace\addataextract" />  


一个Context就代表了一个web应用,path表示该web应用的路径,docBase指定了该应用的根目录所在。

② Web.xml
前面说过了一个Context对应于一个Web App,每个Web App是由一个或者多个servlet组成的,而web.xml就是web app的部署配置文件。当一个Web App被初始化的时候,它将用自己的ClassLoader对象载入web.xml中定义的每个servlet类。

它首先载入在$CATALINA_HOME/conf/web.xml中部署的servlet类,然后载入在自己的Web App根目录下的WEB-INF/web.xml中部署的servlet类。

web.xml文件有两部分:servlet类定义和servlet映射定义。每个被载入的servlet类都有一个名字,且被填入该Context的映射表(mapping table)中,和某种URL PATTERN对应。当该Context获得请求时,将查询mapping table,找到被请求的servlet,并执行以获得请求回应。

下面我们来分析一下tomcat的$CATALINA_HOME/conf/web.xml,这个文件是所有web app的共用的部署配置文件。当部署一个web app时,这个文件将首先被读取处理,然后才是web app自己的在WEB-INF目录下的web.xml文件。

Java代码 复制代码 收藏代码
  1.     <servlet>  
  2.         <servlet-name>default</servlet-name>  
  3.         <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>  
  4.         <init-param>  
  5.             <param-name>debug</param-name>  
  6.             <param-value>0</param-value>  
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>listings</param-name>  
  10.             <param-value>false</param-value>  
  11.         </init-param>  
  12.         <load-on-startup>1</load-on-startup>  
  13. </servlet>  
  14.     <servlet-mapping>  
  15.         <servlet-name>default</servlet-name>  
  16.         <url-pattern>/</url-pattern>  
  17.     </servlet-mapping>  


这个servlet是default servlet,也就是说当用户的Http请求无法匹配到任何一个servlet的时候,就执行该servlet。
这里面有个参数交listings,默认是设置为false的,因为tomcat6出于安全问题的考虑,默认是禁止目录浏览。之前版本的tomcat在访问某个目录的时候,例如test,tomcat会把test目录下的所有文件都列出来。但是这样一来的话,这个目录下的文件都变成对外可见的了。因此tomcat6默认是禁止这个功能的,当然,你可以把listings设置为true来开启这个功能。一般来说,在上到生产环境的时候,最好把listings设置为false。

Java代码 复制代码 收藏代码
  1. <servlet>  
  2.     <servlet-name>jsp</servlet-name>  
  3.     <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>  
  4.     <init-param>  
  5.         <param-name>fork</param-name>  
  6.         <param-value>false</param-value>  
  7.     </init-param>  
  8.     <init-param>  
  9.         <param-name>xpoweredBy</param-name>  
  10.         <param-value>false</param-value>  
  11.     </init-param>  
  12.     <load-on-startup>3</load-on-startup>  
  13. </servlet>  
  14. <servlet-mapping>  
  15.     <servlet-name>jsp</servlet-name>  
  16.     <url-pattern>*.jsp</url-pattern>  
  17. </servlet-mapping>  


这个jsp servlet也是很重要的,表示当请求的是一个jsp页面的时候(即请求.jsp时),将调用该servlet,它是一个jsp编译器,用来将请求的jsp页面编译成servlet再执行。
0 0
原创粉丝点击