Showing posts with label Tomcat. Show all posts
Showing posts with label Tomcat. Show all posts

Saturday, June 26, 2010

Eclipse远程调试Tomcat

更多精彩请到 http://www.139ya.com

http://jarfield.javaeye.com/blog/578675

最近,一直在研究Tomcat的工作内幕,主要的方法就是参考《How Tomcat Works》 这本书和Tomcat 5.5.26的源代码。

Tomcat的代码结构还是比较清晰的,注释也比较全。但是代码毕竟是静态的,难以彻底弄清类与类之间的协作关系,以及运行时对象的交互关系。

如果能对Tomcat的启动、处理请求和停止的过程进行断点调试,看清Tomcat的每一步行踪,那么就能解决上面的问题了。

于是,又一个问题出来了:如何使用Eclipse远程调试Tomcat

上网查了一些资料,相关的文章还是很多的。我简单梳理了一下解决方案及原理,顺便熟悉了Tomcat的启动脚本。

如何远程调试JVM

远程调试Tomcat,本质上就是远程调试JVM。倒不是需要了解JVM自身的运行细节,而是要了解JVM上应用程序的运行细节。

无论如何,我们都要获取JVM运行时的内部信息(比如查看调试信息),并对JVM的运行流程进行控制(比如单步执行),才能达到调试的目的。

这个事情光靠调试器本身,肯定是做不到的。不然,JVM的安全性就大打折扣了。除非JVM提供某种“后门”,供调试器查询一些运行时信息,并允许调 试器发送一些控制命令。

不得不感慨,JVM的强大。从J2SE 1.4.2开始,就已经提出并实现了JavaTM Platform Debugger Architecture ,简称JPDA。

JPDA简介

顾名思义,JPDA为Java平台上的调试器定义了一个标准的体系结构。该体系结构包括3个主要组成部分:JVM TI、JDI和JDWP。

JVM TI的全称是Java Virtual Machine Tool Interface,它定义了JVM为了支持调试而必须提供的功能及相应的访问接口。这些访问接口是以本地语言的形式提供的,由JVM(比如Sun公司的 HotSpot VM)负责实现。

不过,JVM TI只是JVM提供的一系列函数,调试器(特别是远程的调试器)如何调用呢?其实啊,JVM TI的直接客户端并不是调试器,而是一个称为“JPDA back-end”的东东。这个东东应该是属于JVM的一部分,在SUN JRE的bin目录下可以找到jdwp.dll(jdwp.so)的库文件,这就是JPDA back-end的实现。按我理解,JPDA back-end提供了各种访问方式(共享内存,Socket),通过这些方式接收调试器的请求,然后调用JVM TI接口。

JDI的全称是Java Debug Interface,它定义了访问JVM TI接口的高层API,以纯Java语言提供,由JDK实现(在Sun JDK的tools.jar可以找到)。调试器直接使用JDI来实现调试的功能。与JPDA back-end相对应,JDI实现的角色就是JPDA front-end。

JDWP的全称是Java Debug Wire Protocol,它定义了JPDA front-end和JPDA back-end之间通讯信息的二进制格式。这里的通讯信息主要包括两种:调试器发送给JVM的请求信息和JVM发送给调试器的调试信息。

总结一下,调试器 调用JDK提供的JDI实现 (JPDA front-end),经由JDWP协议 ,和JVM自带的JPDA back-end (jdwp.dll, jdwp.so, ...)进行通讯。JPDA back-end 通过调用JVM TI接口 ,从而获知调试信息,或发送控制命令。然后,JPDA back-end 将调试信息或命令执行结果,通过JDWP协议 ,返回给调试器

如何启用JPDA

默认情况下,JVM并没有启用JPDA back-end。需要在启动JVM的命令行加载以下参数:

Java代码
  1. -Xdebug -Xrunjdwp:transport=dt_socket, address=8000,server=y,suspend=y

-Xdebug 启用调试特性

-Xrunjdwp

启用JDWP实现,它包含若干子选项:

transport=dt_socket

JPDA front-end和back-end之间的传输方法。dt_socket表示使用套接字传输。

address=8000

JVM在8000端口上监听请求。

server=y

y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是调试器。

suspend=y

y表示启动的JVM会暂停等待,直到调试器连接上。

suspend=y这个选项很重要。如果你想从Tomcat启动的一开始就进行调试,那么就必须设置suspend=y。

Tomcat的启动脚本

只要Tomcat启动时,启用了JPDA,那么就可以被调试。而Tomcat默认是不启用JPDA的,需要我们手动开启。

开启JPDA的方法也很简单,对Tomcat的启动脚本做点修改:把启动JPDA的命令行参数添加进去,就可以了。

不过Tomcat启动脚本还是有点复杂的,并不是简单的”java ...“。我们先简单的梳理一下。

在Tomcat 5.5.26发行版的bin目录下,有N多脚本,其中与Tomcat启停有关的脚本是(以Windows为例):

startup.bat //启动Tomcat

shutdown.bat //停止Tomcat

catalina.bat //包含启动/停止Tomcat的核心逻辑

startup.bat和shutdown.bat都是通过调用catalina.bat来实现启动和停止的功能,因此他俩的代码都很少。主要的逻 辑都在catalina.bat中。

catalina.bat是个强大的脚本,通过参数,可以执行各种动作,包括debug run start stop version等。

如果我们之间执行catalina.bat,就可以看到它的用法说明:

startup.bat,其实就是执行catalina.bat start;shutdown.bat,其实就是执行catalina.bat stop。

不难猜到,我们可以写一个jdpa.bat,直接调用catalina.bat jpda start,应该就可以启用JPDA。

修改启动脚本

我们拷贝一份startup.bat,把下面这行

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

修改成

call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

不过,-Xdebug -Xrunjdwp:transport=dt_socket, address=8000,server=y,suspend=y,这些选项参数怎么传递给catalina.bat呢?

看看catalina.bat前面的注释,server的值默认就是y,transport的值是变量 JPDA_TRANSPORT,address的值是变量JPDA_ADDRESS,suspend的值是变量JPDA_SUSPEND 。如果没有显式地复制,这些变量的值默认是dt_shmem jdbconn n(默认值表示使用共享内存作为传输方式)。这些默认值不是我们需要的,Eclisep的远程调试目前只支持套接字传输。在调用catalina.bat jpda start之前,我们给这些变量设置恰当的值:

set JPDA_TRANSPORT=dt_socket
set JPDA_ADDRESS=8000
set JPDA_SUSPEND=y

call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

然后,直接执行jpda.bat,Tomcat就运行在JPDA可调式模式下:

从上图可以看出,Tomcat的JPDA使用套接字传输,监听在8000端口。Tomcat的启动已经暂停,只有调试器连接上来,才会继续启动。

我把jpda.bat的完整内容列在下面,其中黑体部分,在startup.bat基础上添加的代码:

Java代码
  1. @echo off
  2. if "%OS%" == "Windows_NT" setlocal
  3. rem ---------------------------------------------------------------------------
  4. rem Jpda script for the CATALINA Server
  5. rem
  6. rem $Id: jpda.bat 302918 2004-05-27 18:25:11Z yoavs $
  7. rem ---------------------------------------------------------------------------
  8. rem Guess CATALINA_HOME if not defined
  9. set CURRENT_DIR=%cd%
  10. if not "%CATALINA_HOME%" == "" goto gotHome
  11. set CATALINA_HOME=%CURRENT_DIR%
  12. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
  13. cd ..
  14. set CATALINA_HOME=%cd%
  15. cd %CURRENT_DIR%
  16. :gotHome
  17. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
  18. echo The CATALINA_HOME environment variable is not defined correctly
  19. echo This environment variable is needed to run this program
  20. goto end
  21. :okHome
  22. set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat
  23. rem Check that target executable exists
  24. if exist "%EXECUTABLE%" goto okExec
  25. echo Cannot find %EXECUTABLE%
  26. echo This file is needed to run this program
  27. goto end
  28. :okExec
  29. rem Get remaining unshifted command line arguments and save them in the
  30. set CMD_LINE_ARGS=
  31. :setArgs
  32. if ""%1""=="""" goto doneSetArgs
  33. set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
  34. shift
  35. goto setArgs
  36. :doneSetArgs
  37. set JPDA_TRANSPORT=dt_socket
  38. set JPDA_ADDRESS=8000
  39. set JPDA_SUSPEND=y
  40. call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%
  41. :end

开始调试Tomcat

首先将Tomcat 5.5.26的源代码分为container connectors jasper servletapi build五个项目,导入到Eclipse中。启动相关的代码主要在container中,就以它为当前项目,打开”Debug Configurations“对话框。

然后创建一个”Remote Java Application“,Connection Type选择”Standard (Socket Attach)“,Host填写localhost(Tomcat所在的主机地址),Port填写8000。最后点击”Apply“保存。

首先确保已经执行了jpda.bat,Tomcat正在等待调试器连接;然后执行上述的Debug Configuration,Eclipse就可以连上Tomcat。

Tomcat的启动是从Bootstrap的main方法开始,我在第一行代码处设置了断点,Tomcat的启动就停在了这一行:

接着,让Tomcat继续执行,我们可以看到,控制台输出了启动信息。

Wednesday, April 15, 2009

tomcat6.0与tomcat5.5 的区别

更多精彩请到 http://www.139ya.com

转自: http://www.javaeye.com/problems/2428

Tomcat6.x在目录上最大的区别就是将 lib 包直接置于 CATALINA_HOME/lib 下,而tomcat 5.x 系列版本是分common/share/server 三个包存放的。再具体解释一下:

CATALINA_HOME/common
在这个目录下的lib目录,存放Tomcat 服务器和所有Web应用都能访问的JAR.

CATALINA_HOME/share
在这个目录下的lib目录,存放所有Web应用都能访问的,但Tomcat 不能访问的JAR。

CATALINA_HOME/server
在这个目录下的lib目录,存放Tomcat 服务器需要的但Web应用不能访问的JAR。
另外该目录下webapps 存放Tomcat 自带的APP-admin和manager两个应用。

common/share/server 三个包中的classes是用来存放class的,就是说你的类库不打成JAR包,而是class文件就直接放在这里。

Tomcat 6.x 在目录结构上就是针对lib包的存放位置做了调整,使应用部署更加方便。另外:
Tomcat 6.x中endorsed 从CATALINA_HOME/common移到根目录下了CATALINA_HOME\endorsed 至于其它没有太大的变化。

另外需要说明的是tomcat 5.x有目录CATALINA_HOME\conf\Catalina\localhost
在Tomcat 6.x中该目录是空的就没给你建,你可以自己建。有好几个朋友问我这个问题了,这里给你提醒一下。

至于xml文件我还没有注意到有什么变化,以后发现了大家在讨论。

Tomcat 下的9个文件夹的作用

更多精彩请到 http://www.139ya.com

转自: http://phoenix-ghk.javaeye.com/blog/367141

Tomcat 下的9个文件夹的作用
  经典Tomcat下有9个目录,分别是bin,common,conf,logs,server,shared,temp,webapps,work 目录,现在对每一目录做介绍。注意,Tomcat6.0以后就没有server和shared文件夹了,没有common文件夹,取而代之的是lib文件夹。

  tomcat根目录在tomcat中叫,文章中把tomcat解压后在c:/下。

  1./bin:存放各种平台下启动和关闭Tomcat的脚本文件。其中有个档是 catalina.bat,打开这个windos配置文件,在非注释行加入JDK路径,例如:SET JAVA_HOME=C:j2sdk1.4.2_06 保存后,就配置好tomcat环境了。startup.bat是windows下启动tomcat的文件,shutdown.bat是关闭tomcat的文件。

  2./common:在common目录下的lib目录,存放Tomcat服务器和所有web应用都能访问的JAR。

  3./shared:在shared目录下的lib目录,存放所有web应用能访问的,但Tomcat不能访问的JAR。

  4./server:在server/webapps目录中,存放Tomcat自带的两个 APP-admin和manager应用,使用来管理Tomcat-web服务用的。在server/lib目录中,存放tomcat服务器所需要的各,web应用不能访问种jar。

  5./work:Tomcat把各种由jsp生成的servlet文件放在这个目录下。work这个文件夹下面的东西建议你去看看就可以明白了 那是JSP文件编译成.java->.classes。

  6./temp:临时活页夹,Tomcat运行时候存放临时文件用的。

  7./logs:存放Tomcat的日志文件。

  8./conf:Tomcat的各种配置文件, tomcat启动的时候需要读取的配置文件:server.xml(tomcat主要配置文件)、web.xml和tomcatat- users.xml、catalina.policy(安全策略文件)等。修改了以后需要重启tomcat才能生效.最重要的是 server.xml;配置tomcat组件的XML文件server.XML其中包括:

  I.顶层类元素[Top Level Elements]:位于整个配置文件的顶层, 包括
  II.连接器类元素[Connectors ]:客户和服务(容器类元素)间的通讯接口。接受客户请求,返回响应结果;
  II.容器类元素[Containers]: 处理客户请求并且生成响应结果,包含3个:
  IV.嵌套类元素[Nested Components]: 可以加入到容器中的元素,包括:

  一个包含一个或多个,一个包含唯一一个和一个或多个,多个共享一个;一个包含多个,每个定义一个虚拟主机,包含一个或多个web应用元素是代表一个在虚拟主机上运行的Web应用。标签的描述

  Please note that for tomcat 5.x, unlike tomcat 4.x, it is NOT recommended to place elements directly in the server.xml file. Instead, put them in the META-INF/context.xml directory of your WAR file or the conf directory as described above.

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

  注意:
  默认的server.xml中,Realm元素只设置了一个className属性,但此文件中也包含几个通过JDBC连接到数据库进行验证的示例(被注释掉了),通过Realm元素我们可以实现容器安全管理(Container Managed Security)。

  还有一些元素,如Parameter,loader,你可以通过tomcat的文档获取这些元素的信息。

  9./webapps: web应用的发布目录,把 java开发的web站点或war文件放入这个目录下就可以通过tomcat服务器访问了。

  在绝大多数资料上,都只提到了conf/server.xml以及context下面的 WEB-INF/web.xml,但我发现,有时,在server.xml上面没有配置的内容,tomcat也运行着,后来发现,原来除了这两处配置外,还有一处重要的配置文件,
在TOMCAT_HOME/conf/Catalina/下面(Catalina是server.xml里的engine的名称),也是一些关键的配置文件,每个主机(server.xml里的Host),在这里有一个目录,每个主机(Host)里的一个context在该主机目录下有一个对应的xml文件,比如,根目录对应ROOT.xml,其它名为test的context对应test.xml。

  TOMCAT_HOME/conf/Catalina/hostname/context1.xml 相当于在server.xml中的Catalina引擎下的hostname主机下配置context1WEB应用。在目录里配置,和在 server.xml里配置效果是一样的,Tomcat自带的admin,自动将所有context转到目录下配置,而不是集中在server.xml。

  10、如何新建虚拟目录?
修改 Tomcat安装目录//conf//server.xml ,在下列行前


添加下列行:


表示增加虚拟目录 my,对应物理目录位置c://myjsp//test,若存在c://myjsp//test//hello.jsp,则下列地址可访问:
htpp://localhost:8080/my/hello.jsp
修改server.xml后,需要重新启动tomcat.

Tomcat笔记(1)

更多精彩请到 http://www.139ya.com

转自: http://www.javaeye.com/topic/178672

Tomcat笔记(1)


Tomcat启动分析

1 - Tomcat Server的组成部分
1.1 - Server
A Server element represents the entire Catalina servlet container. (Singleton)
1.2 - Service
A Service element represents the combination of one or more Connector components that share a single Engine
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
The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
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的结构图

3 - 配置文件$CATALINA_HOME/conf/server.xml的说明
该文件描述了如何启动Tomcat Server
















... ... ... ...










port="8080"
minProcessors="5" maxProcessors="75" acceptCount="100"
enableLookups="true"
redirectPort="8443"
debug="0"
connectionTimeout="20000"
useURIValidationHack="false"
disableUploadTimeout="true" />















































4 - Context的部署配置文件web.xml的说明
一个Context对应于一个Web App,每个Web App是由一个或者多个servlet组成的
当一个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,并执行以获得请求回应
分析一下所有的Context共享的web.xml文件,在其中定义的servlet被所有的Web App载入




















default

org.apache.catalina.servlets.DefaultServlet


debug
0


listings
true

1






invoker

org.apache.catalina.servlets.InvokerServlet


debug
0

2






jsp
org.apache.jasper.servlet.JspServlet

logVerbosityLevel
WARNING

3










default
/



invoker
/servlet/*



jsp
*.jsp







... ... ... ...






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

一、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中,与IIS中的默认文件意思相同。
 
 index.html
 index.htm
 index.jsp



2、报错文件的设置

404
/notFileFound.jsp



java.lang.NullPointerException
/null.jsp


如果某文件资源没有找到,服务器要报404错误,按上述配置则会调用\webapps\ROOT\notFileFound.jsp。
如果执行的某个JSP文件产生NullPointException ,则会调用\webapps\ROOT\null.jsp

3、会话超时的设置
设置session 的过期时间,单位是分钟;

30



4、过滤器的设置

FilterSource
project4. FilterSource



FilterSource
/WwwServlet
(/haha/*)



过滤:
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文件,在相应的位置添加下面一行:

然后重起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 6

更多精彩请到 http://www.139ya.com

Tomcat Versions : http://tomcat.apache.org/whichversion.html

Pro Apache Tomcat 6 (第3章): http://www.javaeye.com/wiki/topic/358242

Tuesday, January 13, 2009

Tomcat集群与负载均衡

更多精彩请到 http://www.139ya.com


转自: tomcat集群与负载均衡

在进入集群系统架构探讨之前,先定义一些专门术语:
1. 集群(Cluster):是一组独立的计算机系统构成一个松耦合的多处理器系统,它们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。
2. 负载均衡(Load Balance):先得从集群讲起,集群就是一组连在一起的计算机,从外部看它是一个系统,各节点可以是不同的操作系统或不同硬件构成的计算机。如一个提供Web服务的集群,对外界来看是一个大Web服务器。不过集群的节点也可以单独提供服务。
3. 特点:在现有网络结构之上,负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。集群系统(Cluster)主要解决下面几个问题:
高可靠性(HA):利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。
高性能计算(HP):即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,通常用于科学计算领域,比如基因分析,化学分析等。
负载平衡:即把负载压力根据某种算法合理分配到集群中的每一台计算机上,以减轻主服务器的压力,降低对主服务器的硬件和软件要求。

目前比较常用的负载均衡技术主要有:
  1. 基于DNS的负载均衡
  通过DNS服务中的随机名字解析来实现负载均衡,在DNS服务器中,可以为多个不同的地址配置同一个名字,而最终查询这个名字的客户机将在解析这个名字时得到其中一个地址。因此,对于同一个名字,不同的客户机会得到不同的地址,他们也就访问不同地址上的Web服务器,从而达到负载均衡的目的。

  2. 反向代理负载均衡 (Reverse Proxy)(如Apache+JK2+Tomcat这种组合)
  使用代理服务器可以将请求转发给内部的Web服务器,让代理服务器将请求均匀地转发给多台内部Web服务器之一上,从而达到负载均衡的目的。这种代理方式与普通的代理方式有所不同,标准代理方式是客户使用代理访问多个外部Web服务器,而这种代理方式是多个客户使用它访问内部Web服务器,因此也被称为反向代理模式。

  3. 基于NAT(Network Address Translation)的负载均衡技术 (如Linux Virtual Server,简称LVS)
  网络地址转换为在内部地址和外部地址之间进行转换,以便具备内部地址的计算机能访问外部网络,而当外部网络中的计算机访问地址转换网关拥有的某一外部地址时,地址转换网关能将其转发到一个映射的内部地址上。因此如果地址转换网关能将每个连接均匀转换为不同的内部服务器地址,此后外部网络中的计算机就各自与自己转换得到的地址上服务器进行通信,从而达到负载分担的目的。

介绍完上面的集群技术之后,下面就基于Tomcat的集群架构方案进行说明:

上面是采用了Apache httpd作为web服务器的,即作为Tomcat的前端处理器,根据具体情况而定,有些情况下是不需要Apache httpd作为 web 服务器的,如系统展现没有静态页面那就不需要Apache httpd,那时可以直接使用Tomcat作为web 服务器来使用。使用Apache httpd主要是它在处理静态页面方面的能力比Tomcat强多了。
1、 用户的网页浏览器做完本地 DNS和企业授权的DNS之的请求/响应后,这时候企业授权的DNS(即21cn BOSS DNS)会给用户本地的DNS服务器提供一个NAT请求分配器(即网关)IP。


2、 NAT分配器,它会根据特定的分配算法,来决定要将连接交给哪一台内部 Apache httpd来处理请求。大多数的NAT请求分配器提供了容错能力:根据侦测各种WEB服务器的失效状况,停止将请求分配给已经宕掉的服务器。并且有些分配器还可以监测到WEB服务器机器的负载情况,并将请求分配给负载最轻的服务器等等。Linux Virtual Server是一个基于Linux操作系统上执行的VS-NAT开源软件套件,而且它有丰富的功能和良好的说明文件。商业硬件解决方案 Foundry Networks的ServerIron是目前业界公认最佳的请求分配器之一。


3、 Apache httpd + Mod_JK2在这里是作为负载均衡器,那为什么要做集群呢?如果集群系统要具备容错能力,以便在任何单一的硬件或软件组件失效时还能100%可用,那么集群系统必须没有单点故障之忧。所以,不能只架设一台有mod_jk2的Apache httpd,因为如果 httpd或mod_jk2失效了,将不会再有请求被会送交到任何一个Tomcat 实例。这种情况下,Apache httpd就是瓶劲,特别在访问量大的网站。


4、 Mod_JK2负载均衡与故障复原,决定把Apache httpd当成web服务器,而且使用mod_jk2将请求传送给Tomcat,则可以使用mod_jk2的负载均衡与容错功能。在集群系统中,带有mod_jk2的Apache httpd可以做的事情包括:
A、 将请求分配至一或多个Tomcat实例上
你可以在mod_jk2的workers.properties文件中,设定许多Tomcat实例,并赋于每个实例一个lb_factor值,以作为请求分配的加权因子。


B、 侦测Tomcat实例是否失败
当Tomcat实例的连接器服务不再响应时,mod_jk2会及时侦测到,并停止将请求送给它。其他的Tomcat实例则会接受失效实例的负载。


C、 侦测Tomcat实例在失效后的何时恢复
因连接器服务失效,而停止将请求分配给Tomcat实例之后,mod_jk2会周期性地检查是否已恢复使用性,并自动将其加入现行的Tomcat实例池中。


5、 Tomcat中的集群原理是通过组播的方式进行节点的查找并使用TCP连接进行会话的复制。这里提示一下就是,对每个请求的处理,Tomcat都会进行会话复制,复制后的会话将会慢慢变得庞大。


6、 Mod_jk2同时支持会话亲和和会话复制。在tomcat 5中如何实现会话亲和和会话复制?把server.xml中的标签去掉就实现会话亲和,把标签加上就实现会话复制。


7、 会话亲和:就是表示来自同会话的所有请求都由相同的Tomcat 实例来处理,这种情况下,如果Tomcat实例或所执行的服务器机器失效,也会丧失Servlet的会话数据。即使在集群系统中执行更多的Tomcat实例,也永远不会复制会话数据。这样是提高集群性能的一种方案,但不具备有容错能力了。


8、 使用会话复制,则当一个Tomcat实例宕掉时,由于至少还有另一个Tomcat实例保有一份会话状态数据,因而数据不会丧失。但性能会有所降低。

TOMCAT集群配置

更多精彩请到 http://www.139ya.com

我的运行环境:Windows2003 Server SP4 + J2SDK1.5.0 +Tomcat5.5.9

准备软件:Tomcat 5.5.9 JDK1.5.0

一.配置过程

1、安装JDK1.5.0。采用默认安装就可以。

2、安装tomcat到C:\ tomcat 50,采用完全安装,该程序用于实现负载均衡功能。

3、将tomcat50的内容进行完全复制,生成C:\ tomcat 51、C:\ tomcat 52、C:\ tomcat 53,分别用做集群中的节点。

4、修改负载均衡规则,使其遵循轮循算法(RoundRobin)。

4.1将testLB.jsp复制到c:\tomcat50\webapps\balancer文件夹中

4.2将文件夹classes复制到c:\tomcat50\webapps\balancer\WEB-INF文件夹中

4.3修改c:\web\tomcat50\webapps\balancer\WEB-INF\web.xml文件如下:

BalancerFilter
/LoadBalancer


5、在集群中每个节点下,部署clusterapp应用。Clusterapp包含sessiondata.jsp,test.jsp,脚本。 test.jsp是用来验证节点状态的页面;sessiondata.jsp是用来响应用户所发送的请求,同时记录会话ID,会话的起始和最后时间,提供用户增加、修改、删除会话的属性字段和属性值,可以通过此来判断会话的持续与否。

6、将log4j的log4j-1.2.9.jar复制到每个%tomcat%/common/ lib下,使其将会话日志统一存储到指定的文件中。

7、修改每个tomcat的server.xml配置文件,参数如下表所示。

配置 Instance 1 Instance 2 Instance 3 Instance 4
Instance Type Load Balancer Node 1 Node 2 Node 3
Code name TC-LB TC01 TC02 TC03
Home Directory c:/tomcat50 c:/tomcat51 c:/tomcat52 c:/tomcat53
Server Port 8005 9005 10005 11005
Connector 8080 9080 10080 11080
JK2 AJP Connector 8009 9009 10009 11009
Cluster mcastAddr 228.0.0.4 228.0.0.4 228.0.0.4 228.0.0.4
Cluster mcastPort 45564 45564 45564 45564
tcpListenAddress 127.0.0.1 127.0.0.1 127.0.0.1 127.0.0.1
Cluster tcpListenPort 4000 4001 4002 4003

8、修改c:\web\tomcat50\webapps\balancer\WEB-INF\config\ruler.xml文件如下:




serverInstance="1"
maxServerInstances="3"
tcpListenAddress="127.0.0.1"
tcpListenPort="4001"
testWebPage="http://localhost:9080/clusterapp/test.jsp"
redirectUrl="http://localhost:9080/clusterapp/sessiondata.jsp" />

serverInstance="2"
maxServerInstances="3"
tcpListenAddress="127.0.0.1"
tcpListenPort="4002"
testWebPage="http://localhost:10080/clusterapp/test.jsp"
redirectUrl="http://localhost:10080/clusterapp/sessiondata.jsp" />


serverInstance="3"
maxServerInstances="3"
tcpListenAddress="127.0.0.1"
tcpListenPort="4003"
testWebPage="http://localhost:11080/clusterapp/test.jsp"
redirectUrl="http://localhost:11080/clusterapp/sessiondata.jsp" />



redirectUrl="http://localhost:8080/balancer/testLB.jsp" />

9、启动tomcat的应用。手动双击每个tomcat/bin的startup.bat程序。

二.Web请求集群环境下流程

1、启动访问起始页(http://localhost:8080/balancer/testLB.jsp)


2、JSP重定向请求到负载均衡过滤文件(http://localhost:8080/balancer/LoadBalancer)

3、负载均衡的tomcat接受请求,根据制定的负载均衡算法,重定向到可用的集群节点(TC01、TC02、TC03)

4、对应集群中节点的sessiondata.jsp(位于clusterapp应用下)页面将启动。

5、sesiondata.jsp将在web上显示会话的详细信息(如会话ID,最后访问时间)
在测试的过程中采用RoundRobin算法,通过对Instance 1发起多个http://localhost:8080/balancer/testLB.jsp测试请求,发现每个请求返回页面的端口号不完全一致,在 9080、10080、11080端口不规则的出现,即客户端的访问请求按照RoundRobin算法被重定向到不同的服务器上进行处理,说明该负载均衡规则在这个测试中得到正确的体现。在关闭集群中一个节点后再启用它,能够自动发现该节点,并为该节点分配请求。

Tomcat 相关链接

更多精彩请到 http://www.139ya.com

--------------------------------------------------
安装配置:

Tomcat 安装配置记录: http://heavyz.sourceforge.net/homepage/homepage_zh/comp/notes/tomcat-5.0.html



--------------------------------------------------
Tomcat 启动分析
Tomcat 启动分析: http://neora.javaeye.com/blog/230304


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

Tomcat Realm 配置

官方: http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html

Tomcat Realm 配置: http://www.jaxmao.org/tomcat-docs/realm-howto.html

Tomcat Realm 组件: http://gump-bean.javaeye.com/blog/199738



--------------------------------------------------
集群配置:

Tomcat5.5集群配置

Tomcat5.5集群配置 http://fanqiang.chinaunix.net/app/other/2006-07-10/4800.shtml

apache2.0.55、tomcat5.5.15、jk2.0.4、jdk1.5.6: http://sizhefang.javaeye.com/blog/34226

Tomcat结构分析

更多精彩请到 http://www.139ya.com


转自: Tomcat结构分析


1 Web服务器

通常,一个完整的Web服务器包含一个或多个“虚拟主机”.所谓虚拟主机,就是在一个物理的服务器上配置多个域名,每个域名对应相同或不同的应用.这样,客户端看起来好像是有多个主机;Web容器在收到请求时,根据客户端给出的域名来确定处理该请求的虚拟主机.在每个虚拟主机中又可以部署一个或多个Web应用.每个部署在服务器上的Web应用要提供对本应用的生命周期管理等功能. 尽管不同的Web服务器的实现各不相同,但都按照服务器-虚拟主机-应用的层次结构进行设计和管理.

2 Tomcat结构分析

Apache Tomcat是Servlet/JSP标准的参考实现,作为一个成功的、有着广泛应用的Web容器,Tomcat有着整齐而清晰的内部结构。其中关键的模块有:

Server. 一个Server模块代表了整个Tomcat容器.它的属性代表了Web容器作为一个整体的特征.一个Server模块主要包括一个或多个Service 模块以及顶层的命名资源.在运行期间,Server模块应监听port属性所指定的端口,并对于该端口接受的每一个连接读入其所传入的第1行信息并与 shutdown属性所指定的字串进行比较:如果两者相吻合,则执行关闭服务器的步骤;否则,不执行任何操作并断开连接.这种机制为容器的远程管理提供了可能.

Service.一个Service模块代表了共享同一个Container实例(通常是Engine实例)的一个或多个 Connector实例所组成的逻辑整体.该Container负责处理这个Service中所有Connector接受的请求.Service模块最主要的职责在于:允许加密的Connector以及普通的Connector连接到同一组Web应用.同一个Connector不能同时存在于两个不同的 Service中.在同一个Java虚拟机中可以同时存在多个Service实例,但这些实例除了共享最基本的Java运行时类库以外,相互之间是完全独立的.

Connector.Connector模块负责接受来自网络客户端的请求,并将请求的处理结果反馈给客户端.每个Connector实例实际上实现的是一种网络传输协议,它将通过这种协议传入的客户端请求进行分析,构造相应的Request和Response实例,找出适合相应该请求的 Container实例,调用该Container的invoke方法,并将Request和Response实例作为参数传入,最终将处理结果或者错误信息反馈给客户端.

Engine.Engine是Container的子接口,它代表了整个Servlet引擎.在运行中,Engine永远是Container层次结构的最高级,所以,其setParent()方法若如被调用将总是抛出 IllegalArgumentException异常.一个Engine的子Container通常是一个或多个的Host实例.

Host.Host 代表的实际上就是常说的“虚拟主机”的概念.在一个Tomcat Web服务器中可以同时运行多个Host,每个Host都与一个特定的主机名以及任意个“别名”相绑定.每个客户端的请求都会根据主机名映射到相应的 Host进行处理.Host的下级Container通常是一些Context实例.

Context.一个Context就是一个独立的Web应用.它包括了Web应用的所有Servlet类、JSP 文件、静态页面和图片、Jar包、环境变量、各种配置参数以及其他各种资源.Context的下级Container通常是Wrapper的实例。