[转]Tomcat启动分析

 [转]Tomcat启动分析

原帖

http://docs.huihoo.com/apache/tomcat/heavyz/01-startup.html

以下摘录了部分

------------------------------------------------------------------------------------

1 - Tomcat Server的组成部分

1.1 - Server

A Server element represents the entire Catalina servlet container. (Singleton)

1.2 - Service


Service是这样一个集合:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求

1.3 - Connector

一个Connector将在某个指定端口上侦听客户请求,并将获得的请求交给Engine来处理,从Engine处获得回应并返回客户
TOMCAT有两个典型的Connector,一个直接侦听来自browser的http请求,一个侦听来自其它WebServer的请求
Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求
Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求

1.4 - Engine


Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名
当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理
Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理

1.5 - Host

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

1.6 - Context

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

2 - Tomcat Server的结构图

 

5 - Tomcat Server处理一个http请求的过程

假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp

1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7) path="/wsota"的Context获得请求/wsota_index.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

--------------------------------------------------------------------------

Servlet、jsp、http协议

   当我们在web浏览器中输入一个httpURL时,浏览器首先将其封装为http请求报文,该报文中还会包含本地用户的一些信息,如浏览器、操作系统等信息。

   这些请求的发起,还包括页面中的一个超文本链接或一个表单的提交。所谓表单,是包含在标签<form></form>间的信息,当用户按提交按钮后,将发出一个http请求,默认情况下,该请求需要的页面是当前页面,方法为get,将提交该表单中所有定义的数据。但可以通过<form action="reg.jsp" method="post">来指定请求的页面以及请求的方法。如果使用get方法,这些提交的信息将作为url的一部分提交到web服务器,如果使用post方法,则提交的信息将封装到实体主体部分中去。

    当web服务器得到该报文后,如果是自己可以处理的请求,则直接返回页面,否则将请求转发给其它程序处理(这需要通过配置才能让web服务器知道转发给谁)。如果是对servlet或jsp的请求,则该请求会转发给servlet容器。

    现在servlet容器收到请求后,首先会将报文信息(也可能是web服务器解析后传递过来的数据结构?)封装为一个HttpServletRequest的对象,同时根据请求查找相应的HttpServlet类(根据web-inf目录下web.xml中给出的servlet-class信息,到web-inf/classes下找相应的类),找到后,创建该类实例(如果该类已经装入内存,则直接从内存创建,这也是为什么在tomcat中,如果修改内容后必须重新起动的原因,而对于发布的web应用,在servlet容器起动时,也会进行一些预处理,可能是对每个web应用中web.xml文件进行处理,servlet容器起动后加入的web应用对servlet容器是不知道的,因此必须重启,至少tomcat如此)。然后根据请求是get或post(当然还有其它命令,如head,但一般应用中主要是这两个),分别调用HttpServlet类实例的doGet或doPost方法,同时传入HttpServletRequest的对象以及作为响应请求的HttpServletResponse对象。

现在进入doGet(或doPost)方法,在方法中,从HttpServletRequest对象中得到用户提交的信息,进行处理,然后通过HttpServletResponse对象输出相应的页面。doGet和doPost可以给出两个完全不同的响应页面,但一般情况下,doPost会直接调用doGet。从面向对象的角度来说,一个servlet应该只对应一个页面。

   当doGet(或doPost)方法结束后,HttpServlet类就完成了工作,现在是servlet容器的任务了。它得到了HttpServlet类处理后的HttpServletResponse对象,根据该对象,容器封装http响应报文(或者填充web服务器可以理解的数据结构?),返回给web服务器。

     Web服务器将响应报文传递给浏览器。浏览器解析响应报文,显示页面。

   对于jsp文件,首先会被编译为相应的servlet,在tomcat中,name.jsp会被编译为name_jsp.class,它的package为org.apache.jsp,原有的html信息被放入编译后的方法中,由JspWriter定义的out对象输出。因此当我们写jsp中的java代码时,至少由两个对象是可以直接使用的,即HttpServletRequest的对象request以及HttpServletResponse对象response。

------------------------------------------------------------

TOMCAT简述(转)

一、Tomcat背景 
  自从JSP发布之后,推出了各式各样的JSP引擎。Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JSP服务器,当然同时也支持Servlet, 这样Tomcat就诞生了。Tomcat是jakarta项目中的一个重要的子项目,其被JavaWorld杂志的编辑选为2001年度最具创新的java产品,同时它又是sun公司官方推荐的servlet和jsp容器,因此其越来越多的受到软件公司和开发人员的喜爱。servlet和jsp的最新规范都可以在tomcat的新版本中得到实现。其次,Tomcat是完全免费的软件,任何人都可以从互联网上自由地下载。Tomcat与Apache的组合相当完美。 

二、Tomcat目录 
tomcat 
|---bin Tomcat:存放启动和关闭tomcat脚本; 
|---conf Tomcat:存放不同的配置文件(server.xml和web.xml); 
|---doc:存放Tomcat文档; 
|---lib/japser/common:存放Tomcat运行需要的库文件(JARS); 
|---logs:存放Tomcat执行时的LOG文件; 
|---src:存放Tomcat的源代码; 
|---webapps:Tomcat的主要Web发布目录(包括应用程序示例); 
|---work:存放jsp编译后产生的class文件; 


三、Tomcat类加载 
Bootstrap($JAVA_HOME/jre/lib/ext/*.jar) 
System($CLASSPATH/*.class和指定的jar) 
Common($CATALINA_HOME/common 下的classes,lib,endores三个子目录) 
Catalina ($CATALINA_HOME/server/下的classes和lib目录仅对Tomcat可见) 
&Shared($CATALINA_HOME/shared/下的classes和lib目录以及$CATALINA_HOME/lib目录)仅对Web应用程序可见,对Tomcat不可见WebApp($WEBAPP/Web-INF/*仅对该WEB应用可见classes/*.class lib/*.jar) 


加载类和资源的顺序为: 
1、/Web-INF/classes 
2、/Web-INF/lib/*.jar 
3、Bootstrap 
4、System 
5、$CATALINA_HOME/common/classes 
6、$CATALINA_HOME/common/endores/*.jar 
7、$CATALINA_HOME/common/lib/*.jar 
8、$CATALINA_HOME/shared/classes 
9、$CATALINA_HOME/shared/lib/*.jar 

四、server.xml配置简介: 
下面讲述这个文件中的基本配置信息,更具体的配置信息请参考tomcat的文档: 
    server: 
          1、port 指定一个端口,这个端口负责监听关闭tomcat的请求 
          2、shutdown 指定向端口发送的命令字符串 
    service: 
          1、name 指定service的名字 
    Connector (表示客户端和service之间的连接): 
          1、port 指定服务器端要创建的端口号,并在这个断口监听来自客户端的请求 
          2、minProcessors 服务器启动时创建的处理请求的线程数 
          3、maxProcessors 最大可以创建的处理请求的线程数 
          4、enableLookups 如果为true,则可以通过调用request.getRemoteHost()进行DNS查 
询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip 
地址 
          5、redirectPort 指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的 
端口号 
          6、acceptCount 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理 
队列中的请求数,超过这个数的请求将不予处理 
          7、connectionTimeout 指定超时的时间数(以毫秒为单位) 
    Engine (表示指定service中的请求处理机,接收和处理来自Connector的请求): 
          1、defaultHost 指定缺省的处理请求的主机名,它至少与其中的一个host元素的name 
属性值是一样的 
    Context (表示一个web应用程序): 
          1、docBase 应用程序的路径或者是WAR文件存放的路径 
          2、path 表示此web应用程序的url的前缀,这样请求的url为 
http://localhost:8080/path/**** 
          3、reloadable 这个属性非常重要,如果为true,则tomcat会自动检测应用程序的 
/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,我们可 
以在不重起tomcat的情况下改变应用程序 
    host (表示一个虚拟主机): 
          1、name 指定主机名 
          2、appBase 应用程序基本目录,即存放应用程序的目录 
          3、unpackWARs 如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接 
从WAR文件中运行应用程序 
    Logger (表示日志,调试和错误信息): 
          1、className 指定logger使用的类名,此类必须实现org.apache.catalina.Logger 接口 
          2、prefix 指定log文件的前缀 
          3、suffix 指定log文件的后缀 
          4、timestamp 如果为true,则log文件名中要加入时间,如下 
例:localhost_log.2001-10-04.txt 
   Realm (表示存放用户名,密码及role的数据库): 
          1、className 指定Realm使用的类名,此类必须实现org.apache.catalina.Realm接口 
   Valve (功能与Logger差不多,其prefix和suffix属性解释和Logger 中的一样): 
          1、className 指定Valve使用的类名,如用org.apache.catalina.valves.AccessLogValve 
类可以记录应用程序的访问信息 
    directory(指定log文件存放的位置): 
    1、pattern 有两个值,common方式记录远程主机名或ip地址,用户名,日期,第一行 
请求的字符串,HTTP响应代码,发送的字节数。combined方式比common方式记 
录的值更多 

五、web.xml配置简介: 
�1、默认(欢迎)文件的设置 
� 在tomcat4/conf/web.xml中,<welcome-file-list>与IIS中的默认文件意思相同。 
� �<welcome-file-list> 
��� <welcome-file>index.html</welcome-file> 
��� <welcome-file>index.htm</welcome-file> 
��� <welcome-file>index.jsp</welcome-file> 
�� </welcome-file-list> 

�2、报错文件的设置 
��<error-page> 
���<error-code>404</error-code> 
���<location>/notFileFound.jsp</location> 
��</error-page> 
��<error-page> 
���<exception-type>java.lang.NullPointerException</exception-type> 
���<location>/null.jsp</location> 
��</error-page> 
��如果某文件资源没有找到,服务器要报404错误,按上述配置则会调用/webapps/ROOT/notFileFound.jsp。 
��如果执行的某个JSP文件产生NullPointException ,则会调用/webapps/ROOT/null.jsp 

�3、会话超时的设置 
��设置session 的过期时间,单位是分钟; 
��<session-config> 
���<session-timeout>30</session-timeout> 
��</session-config> 

�4、过滤器的设置 
��<filter> 
���<filter-name>FilterSource</filter-name> 
���<filter-class>project4. FilterSource </filter-class> 
��</filter> 
��<filter-mapping> 
���<filter-name>FilterSource</filter-name> 
���<url-pattern>/WwwServlet</url-pattern> 
���(<url-pattern>/haha/*</url-pattern>) 
��</filter-mapping> 

��过滤: 
��1) 身份验证的过滤Authentication Filters 
��2) 日志和审核的过滤Logging and Auditing Filters 
��3) 图片转化的过滤Image conversion Filters 
��4) 数据压缩的过滤Data compression Filters 
��5) 加密过滤Encryption Filters 
��6) Tokenizing Filters 
��7) 资源访问事件触发的过滤Filters that trigger resource access events XSL/T 过滤XSL/T filters 
��9) 内容类型的过滤Mime-type chain Filter 注意监听器的顺序,如:先安全过滤,然后资源, 
然后内容类型等,这个顺序可以自己定。 

六、管理 
    1、用户配置 
      在进行具体Tomcat管理之前,先给tomcat添加一个用户,使这个用户有权限来进行管理。 
      打开conf目录下的tomcat-users.xml文件,在相应的位置添加下面一行: 
    <user name="user" password="user" roles="standard,manager"/> 
    然后重起tomcat,在浏览器中输入http://localhost:8080/manager/,会弹出对话框,输入上面的用户 
名和密码即可。 

    2、应用程序列表 
      在浏览器中输入http://localhost:8080/manager/list,浏览器将会显示如下的信息: 
    OK - Listed applications for virtual host localhost 
    /ex:running:1 
    /examples:running:1 
    /webdav:running:0 
    /tomcat-docs:running:0 
    /manager:running:0 
    /:running:0 
     上面显示的信息分别为:应用程序的路径、当前状态、连接这个程序的session数 

   3、重新装载应用程序 
      在浏览器中输入 http://localhost:8080/manager/reload?path=/examples,浏览器显示如下: 
    OK - Reloaded application at context path /examples    
这表示example应用程序装载成功,如果我们将server.xml的Context元素的reloadable属性设为true,则没必要利用这种方式重新装载应用程序,因为tomcat会自动装载。 

4、显示session信息 
    在浏览器中输入http://localhost:8080/manager/sessions?path=/examples,浏览器显示如下: 
    OK - Session information for application at context path /examples Default maximum session inactive 
interval 30 minutes 

5、启动和关闭应用程序 
   在浏览器中输入http://localhost:8080/manager/start?path=/examples和 
http://localhost:8080/manager/stop?path=/examples分别启动和关闭examples应用程序。 

------------------------------------------

   Tomcat的过滤器主要由Filter、FilterChain组成,FilterChain包含一个Filter数组.当Wrapper执行FilterChain的doFilter(request,response)方法时,FilterChain首先调用第一个Filter的doFilter(request,response,filterchain)方法,当第一个filter做完过滤操作后,它又会调用filterchain的doFilter方法,此时filterchain的当前filter已变为第二个filter,第二个filter又执行dofilter方法,依此类推,直至所有过滤器都执行完毕 

Java代码 
1.public interface Filter {   
2.        .....          
3.        //执行过滤   
4.        public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;   
5.  
6.}   
7.  
8.public interface FilterChain {   
9.    public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;   
10.}  


2.实现例子

Java代码 
1.class ApplicationFilterChain implements FilterChain {   
2.      
3.   //pos为当前filter的所在位置,n为filters数组的长度   
4.   if (pos < n) {   
5.            //pos++执行后,把filterchain的当前filter指向下一个   
6.            ApplicationFilterConfig filterConfig = filters[pos++];   
7.            Filter filter = null;   
8.            try {   
9.                filter = filterConfig.getFilter();   
10.  
11.                //filter执行过滤操作   
12.                filter.doFilter(request, response, this);   
13.            }   
14.            ...   
15.   }   
16.}   
17.  
18.  
19.class SampleFilter implements Filter {   
20.      ........   
21.      public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)   
22.        throws IOException, ServletException {   
23.            
24.         //do something    
25.         .....   
26.         //request, response传递给下一个过滤器进行过滤   
27.         chain.doFilter(request, response);   
28.    }   
29.         
30.} 

------------------------------------------------------

摘录,全部请参见

http://www.cnblogs.com/pcbird/archive/2007/07/09.html

6.声明过滤器

servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器,但为了使用与过滤器有关的元素,必须在web.xml中使用版本2.3的DTD。
过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前,必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时,执行链中的下一个过滤器。如果没有其他过滤器,servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权,因此,它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出,过滤器可将响应对象包裹在一个替身对象(stand-in object)中,比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后,过滤器可检查缓冲区,如有必要,就对它进行修改,然后传送到客户机。
例如,程序清单5-11帝国难以了一个简单的过滤器,只要访问相关的servlet或JSP页面,它就截取请求并在标准输出上打印一个报告(开发过程中在桌面系统上运行时,大多数服务器都可以使用这个过滤器)。

程序清单5-11 ReportFilter.java
package moreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

/** Simple filter that prints a report on the standard output 
* whenever the associated servlet or JSP page is accessed.
* <P>
* Taken from More Servlets and JavaServer Pages
* from Prentice Hall and Sun Microsystems Press,
http://www.moreservlets.com/.
* © 2002 Marty Hall; may be freely used or adapted.
*/

public class ReportFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest)request;
System.out.println(req.getRemoteHost() +
" tried to access " +
req.getRequestURL() +
" on " + new Date() + ".");
chain.doFilter(request,response);
}

public void init(FilterConfig config)
throws ServletException {
}

public void destroy() {}
}

一旦建立了一个过滤器,可以在web.xml中利用filter元素以及filter-name(任意名称)、file-class(完全限定的类名)和(可选的)init-params子元素声明它。请注意,元素在web.xml的web-app元素中出现的次序不是任意的;允许服务器(但不是必需的)强制所需的次序,并且实际中有些服务器也是这样做的。但这里要注意,所有filter元素必须出现在任意filter-mapping元素之前, filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。
例如,给定上述的ReportFilter类,可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter(位于moreservlets程序包中)相关联。
<filter>
<filter-name>Reporter</filter-name>
<filter-class>moresevlets.ReportFilter</filter-class>
</filter>
一旦命名了一个过滤器,可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。
首先,可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名(此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明)关联。例如,下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName 的servlet或JSP页面,就运行名为Reporter的过滤器。
<filter-mapping>
<filter-name>Reporter</filter-name>
<servlet-name>SomeServletName</servlet-name>
</filter-mapping>
其次,可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如,相面的程序片段指示系统只要访问Web应用中的任意URL,就运行名为Reporter的过滤器。
<filter-mapping>
<filter-name>Reporter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
例如,程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上,程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项,可看到下面的标准输出形式的调试报告(换行是为了容易阅读)。
audit.irs.gov tried to access 
http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html
on Tue Dec 25 13:12:29 EDT 2001.

程序清单5-12 Web.xml(说明filter用法的摘录)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<filter>
<filter-name>Reporter</filter-name>
<filter-class>moresevlets.ReportFilter</filter-class>
</filter>
<!-- ... -->
<filter-mapping>
<filter-name>Reporter</filter-name>
<servlet-name>PageName</servlet-name>
</filter-mapping>
<!-- ... -->
<servlet>
<servlet-name>PageName</servlet-name>
<jsp-file>/RealPage.jsp</jsp-file>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name> PageName </servlet-name>
<url-pattern>/UrlTest2/*</url-pattern>
</servlet-mapping>
<!-- ... -->
</web-app>

原文地址:https://www.cnblogs.com/01picker/p/4439987.html