Tomcat启动脚本浅析

本文以Tomcat5.0.28为例,讨论一下Tomcat的启动过程及常见问题。大家都知道,Tomcat最普遍的启动方法就是在DOS 命令行窗口中执行Tomcat的bin目录下的startup.bat文件(双击该文件即可启动)。 
1. startup.bat脚本解析 
下面我们首先来看看startup.bat脚本是如何启动Tomcat的。Startup脚本非常明了,它的主要任务就是先设置CATALINA_HOME 的环境变量,让该环境变量指向Tomcat的安装目录;然后在安装目录的bin子目录下找catalina.bat文件,如果找不到,就打印出错误信息并 退出,如果在bin目录下找到catalina.bat文件,就准备执行该文件。不过,在执行该文件之前,startup脚本还做了一件工作,那就是寻找 参数。startup脚本可以带多个参数,在Java主类中,第一个参数为args[0],而在MS-DOS脚本中,第一个参数可以通过”%1”得到,如 果您想要得到DOS脚本中得到第二个参数,调用”%2”。但是,在脚本参数数目未知的情况下,我们就只能通过goto循环调用shift命令来获得脚本的 所有参数,下面这个简单的实验脚本有助于我们理解如何使用shift命令。 
Java代码  
  1. @echo off   
  2. echo Print parameters by %%1 and shift loop   
  3. :loopStart   
  4. if ""%1""=="""" goto loopEnd   
  5. echo Paramter is %1   
  6. shift   
  7. goto loopStart   
  8. :loopEnd   

如果把上面的脚本保存成test.bat并在DOS中执行该脚本,执行结果如下。 
下面就是Startup.bat脚本的详细注释,如果想要在DOS脚本中注释一行,前面加上rem即可,这相当于Java的双斜杠(//)注释,下面程序中,凡是以REM开头然后接着中文的行,都是笔者加上的注释,以帮助读者理解该脚本。 

Java代码  
  1. @echo off   
  2. if "%OS%" == "Windows_NT" setlocal   
  3. rem ---------------------------------------------------------------------------   
  4. rem Start script for the CATALINA Server   
  5. rem   
  6. rem $Id: startup.bat,v 1.6 2004/05/27 18:25:11 yoavs Exp $   
  7. rem ---------------------------------------------------------------------------   
  8.   
  9. rem 首先定义一个变量 CURRENT_DIR,然后把当前目录作为一个字符串赋给它   
  10. rem Guess CATALINA_HOME if not defined   
  11. set CURRENT_DIR=%cd%   
  12.   
  13. rem 如果CATALINA_HOME变量已经赋值,程序转到gotHome行继续   
  14. if not "%CATALINA_HOME%" == "" goto gotHome   
  15.   
  16. rem 把当前目录的值作为字符串赋给 CATALINA_HOME变量   
  17. set CATALINA_HOME=%CURRENT_DIR%   
  18.   
  19. rem 如果当前目录的bin子目录下发现catalina.bat文件,程序转到okHome行继续   
  20. rem 否则执行下一行“cd..”。   
  21. Rem 因为缺省情况下当前目录就是bin目录,所以缺省情况下程序不转入okHome行   
  22. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   
  23.   
  24. rem 回上层目录   
  25. cd ..   
  26.   
  27. rem 把当前目录的上层目录作为字符串赋给再次CATALINA_HOME变量,覆盖第一次的赋值   
  28. set CATALINA_HOME=%cd%   
  29.   
  30. rem 重新回到当前目录   
  31. cd %CURRENT_DIR%   
  32.   
  33. :gotHome   

rem 如果在当前目录的父目录的bin子文件夹下发现catalina.bat文件,程序转到okHome行继续 
rem 否则程序打印两行错误信息,然后退出 
Java代码  
  1. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   
  2. echo The CATALINA_HOME environment variable is not defined correctly   
  3. echo This environment variable is needed to run this program   
  4. goto end   
  5. :okHome   

rem 设置一个变量,存储catalina.bat的完整路径 
set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat 
rem 再次检查catalina.bat是否存在,如果不存在,打印两行错误信息,退出 
Java代码  
  1. rem Check that target executable exists   
  2. if exist "%EXECUTABLE%" goto okExec   
  3. echo Cannot find %EXECUTABLE%   
  4. echo This file is needed to run this program   
  5. goto end   
  6. :okExec   

rem 检查脚本是否带参数,如果发现参数,把第一个参数赋值给 CMD_LINE_ARGS变量 
rem 如果脚本带有多个参数,程序设置了一个循环setArgs, 
rem 不断把所带的参数加到CMD_LINE_ARGS变量中 
Java代码  
  1. rem Get remaining unshifted command line arguments and save them in the   
  2. set CMD_LINE_ARGS=   
  3. :setArgs   
  4. if ""%1""=="""" goto doneSetArgs   
  5. set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1   
  6. shift   
  7. goto setArgs   
  8. :doneSetArgs   

rem 执行catalina.bat脚本,该脚本的第一个参数为start,后面的参数是从本脚本中传入的call "%EXECUTABLE%" start %CMD_LINE_ARGS% 
:end 
那么读者也许要问,问什么要通过startup脚本来调用catalina脚本,直接一个脚本不更方便吗?细心的读者或许会发现,在缺省情况下,startup脚本只能放在两个位置,一是Tomcat的安装目录,一个就是Tomcat安装目录的bin子目录。这是什么意思呢?如果Tomcat安装目录是C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28,那么startup脚本只能放在C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\目录或者C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\bin目录下才能运行,如果拷贝startup文件到其它目录,我们就会看到下面的错误(以Tomcat运行在C:\carl目录下为例): 
C:\carl>startup 
CATALINA_HOME C:\ 
The CATALINA_HOME environment variable is not defined correctly 
This environment variable is needed to run this program 
那么,如果我们想让Tomcat在桌面上能成功启动,那么该怎么办呢?当然,我们首先想到的是为startup创建一个快捷方式,然后拷贝该快捷方式到桌面,这是一种办法。另一种办法就是修改startup.bat文件,在startup.bat脚本的第八行处添上一句脚本,让 CATALINA_HOME变量指向用户Tomcat的安装路径,这样,startup.bat就可以拷贝到机器的任何目录执行。这个startup.bat脚本就是提供给使用者用来修改的,我们可以在其中设置JAVA_HOME,CATALINA_HOME等环境变量,但我们并不需要深入到较为复杂的catalina.bat脚本中,这正是startup.bat脚本的真正用意所在。我们知道,软件设计模式中有一个重要的原则就是开闭原则,即我们可以允许别人扩展我们的程序,但在程序发布后,我们拒绝任何修改,因为修改会产生新的Bug,使得我们已经Bug-free的程序又要重新测试。开闭原则是面向对象世界中的一个非常重要的原则,我们可以把这个原则从Java类扩展至源代码级别。startup脚本就是要求用户不要修改catalina.bat脚本,这是符合软件设计思想的。我们如果想要彻底贯彻这个重要的软件设计原则,可以写一个新脚本tomcat.bat,脚本内容大致如下: 
Java代码  
  1. set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09   
  2. set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28   
  3. call %CATALINA_HOME%\bin\startup.bat  

这个tomcat.bat文件可以存放在任何目录并能执行,并且不需要修改tomcat自带的任何脚本及其它环境变量,这就彻底贯彻了开闭原则。 
Java代码  
  1. 2. Catalina.bat脚本解析  

当startup脚本完成环境变量的设置后,就开始调用catalina.bat脚本来启动Tomcat。Catalina脚本的主要任务是根据环境变量和不同的命令行参数,拼凑出完整的java命令行,调用Tomcat的主类org.apache.catalina.startup.Bootstrap来启动Tomcat。我们先不解析该脚本,而是写一个简单的测试脚本来调用这个程序,看看测试结果,从而理解该脚本的调用方法。 
测试脚本如下: 
请将JAVA_HOME环境变量修改到您的JDK安装目录 
rem set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat 
我们把上面的脚本保存为start_tomcat_nothing.bat文件,然后在MS-DOS下执行,我们将看到如下的执行结果。 
这个脚本并没有成功启动Tomcat,但是它给我们提供调用catalina.bat脚本的方法,请阅读上面窗口中的加亮部分。Catalina.bat的调用方法为 catalina后面加上具体命令参数,这个命令参数有以下9种。 具体解释如下: 
debug 在调试器中启动Tomcat  
debug -security 带有安全管理器的调试器中,调用catalina脚本来启动Tomcat  
jpda start 调用catalina脚本,在JPDA调试器中启动Tomcat  
run  在当前窗口内调用catalina脚本来启动Tomcat(不切换窗口)  
run -security  带有安全管理的情况下,在当前窗口内调用catalina脚本来启动Tomcat(不切换窗口) 
start  开始一个新的DOS窗口,并在其中启动Tomcat(切换至新窗口) 
start -security 带有安全管理的情况下,在新的DOS窗口中启动Tomcat(切换至新窗口) 
stop catalina脚本执行停止命令来关闭Tomcat  
version  您使用的Tomcat版本 
看完上面的解释,我们对Tomcat的启动参数有所了解。好,咱们写一个最简单的脚本来测试一下,拷贝刚才start_tomcat_nothing.bat脚本,将它重新命名为start_tomcat_version.bat,该脚本的内容和start_tomcat_nothing.bat脚本几乎一致,只是最后一行多加了一个version命令,start_tomcat_version.bat脚本全部内容如下: 
rem 请将JAVA_HOME环境变量修改到您的JDK安装目录 
set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat version 

我们可以在DOS下观察该脚本的执行结果。 
该脚本顺利执行,执行的结果告诉我们当前Tomcat的版本号为5.0.28。有兴趣的读者朋友可以试试其它的8个命令参数,这些命令参数有时对我们非常有用。举例来说,有时候我们正常启动Tomcat时,Tomcat弹出一个DOS窗口,但是瞬间消失,我们看不出到底哪里出了问题,也无任何启动日志可看。在这种情况下,我们可以使用run命令在同一个窗口内启动Tomcat,不让Tomcat弹出新的DOS窗口,好让我们看看Tomcat到底为什么没有启动。测试这个问题的简单方法如下。 
首先,请到Tomcat安装目录下的bin子目录,把Tomcat的启动jar文件bootstrap.jar重命名为bootstrap_1.jar,然后点击startup.bat文件启动,我们会看到一个小黑窗口闪了一下,但是Tomcat并没有正常启动,这是因为startup.bat执行的是Tomcat的缺省命令start,该命令将在开始一个新的DOS窗口,并在其中启动Tomcat。在这种情况下,我们就要借重于run命令了,我们改以下我们上面的start_tomcat_version.bat脚本,将version命令改为run命令,然后另存为start_tomcat_run.bat,该脚本全部内容如下: 

rem 请将JAVA_HOME环境变量修改到您的JDK安装目录 
set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat run 

脚本的执行结果如下: 
请观察上面窗口中的加亮部分,这部分向我们清楚地展示Tomcat的启动错误,没有找到Tomcat的启动主类Bootstrap。这是因为我们人为地把Tomcat的启动jar文件包从bootstrap.jar重命名为bootstrap_1.jar,这个bootstrap.jar文件既然不存在,那包含在这个文件的Bootstrap.class文件当然也就找不到了。 
现在,我们再回过头看看这个catalina.bat脚本。为简单起见,我们假定该脚本带缺省命令行参数start,看看catalina脚本的执行流程。如果您对catalina的security命令有兴趣,请参考Sun公司的文档http://java.sun.com/j2se/1.5.0/docs/guide/security/smPortGuide.html;如果您对jpda命令有兴趣,不妨浏览一下http://java.sun.com/javase/technologies/core/toolsapis/jpda/ 文档。让我们打开catalina脚本,首先请注意这个脚本第二行有一个setlocal的命令,这个命令表明catalina中的环境变量只在本脚本中起作用,对其它程序和命令不起作用,这就意味着这个脚本中的环境变量是局部变量,不是全局变量,不会影响其它脚本和操作系统环境。 
然后我们会看到长达34行的注释,这是优秀程序员必须学会的基本功之一。这些注释写得非常简洁明了,详细说明了各个环境变量的意义和用途。紧接着,如果发现CATALINA_HOME变量没有定义,该脚本试图设置该变量,这和startup.bat的第一节完全类似,在此不再赘述。然后该脚本调用setclasspath.bat到JAVA_HOME的bin目录下寻找java.exe、javaw.exe、jdb.exe和javac.exe所在的路径,并把这些exe文件的文件名和路径赋值到相应的环境变量_RUNJAVA、_RUNJAVAW、_RUNJDB和_RUNJAVAC中。再接下来,catalina脚本判断是否定义有环境变量CATALINA_BASE,CATALINA_TMPDIR,如果定义了它们,就执行相应的操作。因为我们在此并没有定义它们,所以执行不到这些操作。然后,catalina脚本将在本窗口内打印出四个环境变量的值,这四个环境变量我们非常熟悉,一旦启动Tomcat,我们必定能看到CATALINA_BASE,CATALINA_HOME,CATALINA_TMPDIR和JAVA_HOME。然后catalina脚本根据其后跟的不同命令,拼凑出完整的JAVA命令行并执行。下面是该脚本的详细注释: 
Rem 获得标准的环境变量,因为setenv.bat不存在,所以下面这两句不执行 
rem Get standard environment variables 
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" 
Rem 调用setclasspath.bat脚本,获得标准的环境变量 
rem Get standard Java environment variables 
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath 
echo Cannot find %CATALINA_HOME%\bin\setclasspath.bat 
echo This file is needed to run this program 
goto end 
:okSetclasspath 
set BASEDIR=%CATALINA_HOME% 
call "%CATALINA_HOME%\bin\setclasspath.bat" 

rem根据不同情况在classpath中加上不同的jar包 
rem Add on extra jar files to CLASSPATH 
if "%JSSE_HOME%" == "" goto noJsse 
set CLASSPATH=%CLASSPATH%;%JSSE_HOME%\lib\jcert.jar;%JSSE_HOME%\lib\jnet.jar;%JSSE_HOME%\lib\jsse.jar

:noJsse 

Rem 注意下面的这个jar文件是tomcat的启动包 
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\bootstrap.jar 

rem 我们没有定义CATALINA_BASE,下面这节不执行 
if not "%CATALINA_BASE%" == "" goto gotBase 
set CATALINA_BASE=%CATALINA_HOME% 
:gotBase 
rem 我们没有定义CATALINA_ TMPDIR,下面这节将忽略 
if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir 
set CATALINA_TMPDIR=%CATALINA_BASE%\temp 

:gotTmpdir 

Rem 打印4个我们非常熟悉的环境变量 
rem ----- Execute The Requested Command --------------------------------------- 
echo Using CATALINA_BASE:   %CATALINA_BASE% 
echo Using CATALINA_HOME:   %CATALINA_HOME% 
echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR% 
echo Using JAVA_HOME:   %JAVA_HOME% 

rem 定义一些环境变量 
set _EXECJAVA=%_RUNJAVA% 
rem 这是Tomcat启动的主类 
set MAINCLASS=org.apache.catalina.startup.Bootstrap 
rem 这是catalina脚本的缺省命令start 
set ACTION=start 
set SECURITY_POLICY_FILE= 

set DEBUG_OPTS= 
set JPDA= 

rem 我们的第一个参数命令是start,下面这节将忽略不执行 
if not ""%1"" == ""jpda"" goto noJpda 
set JPDA=jpda 

if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport 

set JPDA_TRANSPORT=dt_shmem 

:gotJpdaTransport 

if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress 
set JPDA_ADDRESS=jdbconn 
:gotJpdaAddress 
shift 

:noJpda 

rem 我们的第一个参数命令是start,所以程序将走到doStart标签处执行 
if ""%1"" == ""debug"" goto doDebug 
if ""%1"" == ""run"" goto doRun 
if ""%1"" == ""start"" goto doStart 
if ""%1"" == ""stop"" goto doStop 
if ""%1"" == ""version"" goto doVersion 

rem 如果catalina后跟的命令不是debug, run, start, stop或version, 
rem 该脚本将打印出catalina的用法,然后结束。 
Rem 详情请见我们前面的测试脚本start_tomcat_nothing.bat及相应的结果窗口 
echo Usage: catalina ( commands ... ) 
echo commands: 
echo   debug   Start Catalina in a debugger 
echo   debug -security   Debug Catalina with a security manager 
echo   jpda start   Start Catalina under JPDA debugger 
echo   run   Start Catalina in the current window 
echo   run -security   Start in the current window with security manager 
echo   start   Start Catalina in a separate window 
echo   start -security   Start in a separate window with security manager 
echo   stop   Stop Catalina 
echo   version   What version of tomcat are you running? 
goto end 

rem 执行debug命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doDebug 
shift 
set _EXECJAVA=%_RUNJDB% 
set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\jakarta-tomcat-catalina\catalina\src\share" 

if not ""%1"" == ""-security"" goto execCmd 
shift 
echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

:doRun 
shift 
if not ""%1"" == ""-security"" goto execCmd 
shift 
echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

rem 执行start命令 
:doStart 
Rem 将参数列表指针指向下一个参数 
shift 
rem 设置Tomcat启动窗口的标题,缺省值为Tomcat 
if not "%OS%" == "Windows_NT" goto noTitle 
set _EXECJAVA=start "Tomcat" %_RUNJAVA% 
goto gotTitle 
:noTitle 
set _EXECJAVA=start %_RUNJAVA% 
:gotTitle 

Rem 检查第二个命令参数是否为-security,我们没有第二个命令参数,脚本将执行至execCmd标签处 
if not ""%1"" == ""-security"" goto execCmd 
shift 

echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

rem 执行stop命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doStop 
shift 
set ACTION=stop 
goto execCmd 

rem 执行version命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doVersion 
%_EXECJAVA% -classpath "%CATALINA_HOME%\server\lib\catalina.jar" org.apache.catalina.util.ServerInfo 
goto end 
rem 执行命令,首先看看命令行参数是否不只一个,我们本例只有一个start参数,所以下面这节将不执行 

:execCmd 
rem Get remaining unshifted command line arguments and save them in the 
set CMD_LINE_ARGS= 
:setArgs 
if ""%1""=="""" goto doneSetArgs 
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 
shift 

goto setArgs 
:doneSetArgs 

Rem 执行java命令行 
rem Execute Java with the applicable properties 
rem 检测JPDA和Security变量,我们本例没有定义他们,下面两句将忽略 
if not "%JPDA%" == "" goto doJpda 
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity 

rem 程序将执行下面的java命令,在新窗口内启动Tomcat 
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% 

Rem catalina至此结束,下面代码我们将忽略。 
goto end 
:end 




<Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JasperListener" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
      <!-- 全局命名资源,来定义一些外部访问资源,其作用是为所有引擎应用程序所引用的外部资源的定义 --!>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <!-- 定义的一个名叫“UserDatabase”的认证资源,将conf/tomcat-users.xml加载至内存中,在需要认证的时候到内存中进行认证 -->
      <Service name="Catalina">
      <!-- # 定义Service组件,同来关联Connector和Engine,一个Engine可以对应多个Connector,每个Service中只能一个Engine --!>
        <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
        <!-- 修改HTTP/1.1的Connector监听端口为80.客户端通过浏览器访问的请求,只能通过HTTP传递给tomcat。  -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="test.com">
        <!-- 修改当前Engine,默认主机是,www.test.com  -->
        <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
        </Realm>
        # Realm组件,定义对当前容器内的应用程序访问的认证,通过外部资源UserDatabase进行认证
          <Host name="test.com"  appBase="/web" unpackWARs="true" autoDeploy="true">
          <!--  定义一个主机,域名为:test.com,应用程序的目录是/web,设置自动部署,自动解压    -->
            <Alias>www.test.com</Alias>
            <!--    定义一个别名www.test.com,类似apache的ServerAlias -->
            <Context path="" docBase="www/" reloadable="true" />
            <!--    定义该应用程序,访问路径"",即访问www.test.com即可访问,网页目录为:相对于appBase下的www/,即/web/www,并且当该应用程序下web.xml或者类等有相关变化时,自动重载当前配置,即不用重启tomcat使部署的新应用程序生效  -->
            <Context path="/bbs" docBase="/web/bbs" reloadable="true" />
            <!--  定义另外一个独立的应用程序,访问路径为:www.test.com/bbs,该应用程序网页目录为/web/bbs   -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/www/logs"
                   prefix="www_access." suffix=".log"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            <!--   定义一个Valve组件,用来记录tomcat的访问日志,日志存放目录为:/web/www/logs如果定义为相对路径则是相当于$CATALINA_HOME,并非相对于appBase,这个要注意。定义日志文件前缀为www_access.并以.log结尾,pattern定义日志内容格式,具体字段表示可以查看tomcat官方文档   -->
          </Host>
          <Host name="manager.test.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
          <!--   定义一个主机名为man.test.com,应用程序目录是$CATALINA_HOME/webapps,自动解压,自动部署   -->
            <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="172.23.136.*" />
            <!--   定义远程地址访问策略,仅允许172.23.136.*网段访问该主机,其他的将被拒绝访问  -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/bbs/logs"
                   prefix="bbs_access." suffix=".log"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            <!--   定义该主机的访问日志      -->
          </Host>
        </Engine>
      </Service>
    </Server>


本文以Tomcat5.0.28为例,讨论一下Tomcat的启动过程及常见问题。大家都知道,Tomcat最普遍的启动方法就是在DOS 命令行窗口中执行Tomcat的bin目录下的startup.bat文件(双击该文件即可启动)。 
1. startup.bat脚本解析 
下面我们首先来看看startup.bat脚本是如何启动Tomcat的。Startup脚本非常明了,它的主要任务就是先设置CATALINA_HOME 的环境变量,让该环境变量指向Tomcat的安装目录;然后在安装目录的bin子目录下找catalina.bat文件,如果找不到,就打印出错误信息并 退出,如果在bin目录下找到catalina.bat文件,就准备执行该文件。不过,在执行该文件之前,startup脚本还做了一件工作,那就是寻找 参数。startup脚本可以带多个参数,在Java主类中,第一个参数为args[0],而在MS-DOS脚本中,第一个参数可以通过”%1”得到,如 果您想要得到DOS脚本中得到第二个参数,调用”%2”。但是,在脚本参数数目未知的情况下,我们就只能通过goto循环调用shift命令来获得脚本的 所有参数,下面这个简单的实验脚本有助于我们理解如何使用shift命令。 
Java代码  
  1. @echo off   
  2. echo Print parameters by %%1 and shift loop   
  3. :loopStart   
  4. if ""%1""=="""" goto loopEnd   
  5. echo Paramter is %1   
  6. shift   
  7. goto loopStart   
  8. :loopEnd   

如果把上面的脚本保存成test.bat并在DOS中执行该脚本,执行结果如下。 
下面就是Startup.bat脚本的详细注释,如果想要在DOS脚本中注释一行,前面加上rem即可,这相当于Java的双斜杠(//)注释,下面程序中,凡是以REM开头然后接着中文的行,都是笔者加上的注释,以帮助读者理解该脚本。 

Java代码  
  1. @echo off   
  2. if "%OS%" == "Windows_NT" setlocal   
  3. rem ---------------------------------------------------------------------------   
  4. rem Start script for the CATALINA Server   
  5. rem   
  6. rem $Id: startup.bat,v 1.6 2004/05/27 18:25:11 yoavs Exp $   
  7. rem ---------------------------------------------------------------------------   
  8.   
  9. rem 首先定义一个变量 CURRENT_DIR,然后把当前目录作为一个字符串赋给它   
  10. rem Guess CATALINA_HOME if not defined   
  11. set CURRENT_DIR=%cd%   
  12.   
  13. rem 如果CATALINA_HOME变量已经赋值,程序转到gotHome行继续   
  14. if not "%CATALINA_HOME%" == "" goto gotHome   
  15.   
  16. rem 把当前目录的值作为字符串赋给 CATALINA_HOME变量   
  17. set CATALINA_HOME=%CURRENT_DIR%   
  18.   
  19. rem 如果当前目录的bin子目录下发现catalina.bat文件,程序转到okHome行继续   
  20. rem 否则执行下一行“cd..”。   
  21. Rem 因为缺省情况下当前目录就是bin目录,所以缺省情况下程序不转入okHome行   
  22. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   
  23.   
  24. rem 回上层目录   
  25. cd ..   
  26.   
  27. rem 把当前目录的上层目录作为字符串赋给再次CATALINA_HOME变量,覆盖第一次的赋值   
  28. set CATALINA_HOME=%cd%   
  29.   
  30. rem 重新回到当前目录   
  31. cd %CURRENT_DIR%   
  32.   
  33. :gotHome   

rem 如果在当前目录的父目录的bin子文件夹下发现catalina.bat文件,程序转到okHome行继续 
rem 否则程序打印两行错误信息,然后退出 
Java代码  
  1. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   
  2. echo The CATALINA_HOME environment variable is not defined correctly   
  3. echo This environment variable is needed to run this program   
  4. goto end   
  5. :okHome   

rem 设置一个变量,存储catalina.bat的完整路径 
set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat 
rem 再次检查catalina.bat是否存在,如果不存在,打印两行错误信息,退出 
Java代码  
  1. rem Check that target executable exists   
  2. if exist "%EXECUTABLE%" goto okExec   
  3. echo Cannot find %EXECUTABLE%   
  4. echo This file is needed to run this program   
  5. goto end   
  6. :okExec   

rem 检查脚本是否带参数,如果发现参数,把第一个参数赋值给 CMD_LINE_ARGS变量 
rem 如果脚本带有多个参数,程序设置了一个循环setArgs, 
rem 不断把所带的参数加到CMD_LINE_ARGS变量中 
Java代码  
  1. rem Get remaining unshifted command line arguments and save them in the   
  2. set CMD_LINE_ARGS=   
  3. :setArgs   
  4. if ""%1""=="""" goto doneSetArgs   
  5. set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1   
  6. shift   
  7. goto setArgs   
  8. :doneSetArgs   

rem 执行catalina.bat脚本,该脚本的第一个参数为start,后面的参数是从本脚本中传入的call "%EXECUTABLE%" start %CMD_LINE_ARGS% 
:end 
那么读者也许要问,问什么要通过startup脚本来调用catalina脚本,直接一个脚本不更方便吗?细心的读者或许会发现,在缺省情况下,startup脚本只能放在两个位置,一是Tomcat的安装目录,一个就是Tomcat安装目录的bin子目录。这是什么意思呢?如果Tomcat安装目录是C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28,那么startup脚本只能放在C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\目录或者C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28\bin目录下才能运行,如果拷贝startup文件到其它目录,我们就会看到下面的错误(以Tomcat运行在C:\carl目录下为例): 
C:\carl>startup 
CATALINA_HOME C:\ 
The CATALINA_HOME environment variable is not defined correctly 
This environment variable is needed to run this program 
那么,如果我们想让Tomcat在桌面上能成功启动,那么该怎么办呢?当然,我们首先想到的是为startup创建一个快捷方式,然后拷贝该快捷方式到桌面,这是一种办法。另一种办法就是修改startup.bat文件,在startup.bat脚本的第八行处添上一句脚本,让 CATALINA_HOME变量指向用户Tomcat的安装路径,这样,startup.bat就可以拷贝到机器的任何目录执行。这个startup.bat脚本就是提供给使用者用来修改的,我们可以在其中设置JAVA_HOME,CATALINA_HOME等环境变量,但我们并不需要深入到较为复杂的catalina.bat脚本中,这正是startup.bat脚本的真正用意所在。我们知道,软件设计模式中有一个重要的原则就是开闭原则,即我们可以允许别人扩展我们的程序,但在程序发布后,我们拒绝任何修改,因为修改会产生新的Bug,使得我们已经Bug-free的程序又要重新测试。开闭原则是面向对象世界中的一个非常重要的原则,我们可以把这个原则从Java类扩展至源代码级别。startup脚本就是要求用户不要修改catalina.bat脚本,这是符合软件设计思想的。我们如果想要彻底贯彻这个重要的软件设计原则,可以写一个新脚本tomcat.bat,脚本内容大致如下: 
Java代码  
  1. set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09   
  2. set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28   
  3. call %CATALINA_HOME%\bin\startup.bat  

这个tomcat.bat文件可以存放在任何目录并能执行,并且不需要修改tomcat自带的任何脚本及其它环境变量,这就彻底贯彻了开闭原则。 
Java代码  
  1. 2. Catalina.bat脚本解析  

当startup脚本完成环境变量的设置后,就开始调用catalina.bat脚本来启动Tomcat。Catalina脚本的主要任务是根据环境变量和不同的命令行参数,拼凑出完整的java命令行,调用Tomcat的主类org.apache.catalina.startup.Bootstrap来启动Tomcat。我们先不解析该脚本,而是写一个简单的测试脚本来调用这个程序,看看测试结果,从而理解该脚本的调用方法。 
测试脚本如下: 
请将JAVA_HOME环境变量修改到您的JDK安装目录 
rem set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat 
我们把上面的脚本保存为start_tomcat_nothing.bat文件,然后在MS-DOS下执行,我们将看到如下的执行结果。 
这个脚本并没有成功启动Tomcat,但是它给我们提供调用catalina.bat脚本的方法,请阅读上面窗口中的加亮部分。Catalina.bat的调用方法为 catalina后面加上具体命令参数,这个命令参数有以下9种。 具体解释如下: 
debug 在调试器中启动Tomcat  
debug -security 带有安全管理器的调试器中,调用catalina脚本来启动Tomcat  
jpda start 调用catalina脚本,在JPDA调试器中启动Tomcat  
run  在当前窗口内调用catalina脚本来启动Tomcat(不切换窗口)  
run -security  带有安全管理的情况下,在当前窗口内调用catalina脚本来启动Tomcat(不切换窗口) 
start  开始一个新的DOS窗口,并在其中启动Tomcat(切换至新窗口) 
start -security 带有安全管理的情况下,在新的DOS窗口中启动Tomcat(切换至新窗口) 
stop catalina脚本执行停止命令来关闭Tomcat  
version  您使用的Tomcat版本 
看完上面的解释,我们对Tomcat的启动参数有所了解。好,咱们写一个最简单的脚本来测试一下,拷贝刚才start_tomcat_nothing.bat脚本,将它重新命名为start_tomcat_version.bat,该脚本的内容和start_tomcat_nothing.bat脚本几乎一致,只是最后一行多加了一个version命令,start_tomcat_version.bat脚本全部内容如下: 
rem 请将JAVA_HOME环境变量修改到您的JDK安装目录 
set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat version 

我们可以在DOS下观察该脚本的执行结果。 
该脚本顺利执行,执行的结果告诉我们当前Tomcat的版本号为5.0.28。有兴趣的读者朋友可以试试其它的8个命令参数,这些命令参数有时对我们非常有用。举例来说,有时候我们正常启动Tomcat时,Tomcat弹出一个DOS窗口,但是瞬间消失,我们看不出到底哪里出了问题,也无任何启动日志可看。在这种情况下,我们可以使用run命令在同一个窗口内启动Tomcat,不让Tomcat弹出新的DOS窗口,好让我们看看Tomcat到底为什么没有启动。测试这个问题的简单方法如下。 
首先,请到Tomcat安装目录下的bin子目录,把Tomcat的启动jar文件bootstrap.jar重命名为bootstrap_1.jar,然后点击startup.bat文件启动,我们会看到一个小黑窗口闪了一下,但是Tomcat并没有正常启动,这是因为startup.bat执行的是Tomcat的缺省命令start,该命令将在开始一个新的DOS窗口,并在其中启动Tomcat。在这种情况下,我们就要借重于run命令了,我们改以下我们上面的start_tomcat_version.bat脚本,将version命令改为run命令,然后另存为start_tomcat_run.bat,该脚本全部内容如下: 

rem 请将JAVA_HOME环境变量修改到您的JDK安装目录 
set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_09 
rem 请将CATALINA_HOME环境变量修改到您的Tomcat安装目录 
set CATALINA_HOME=C:\carl\it\tomcat_research\jakarta-tomcat-5.0.28 
rem 开始调用catalina.bat文件 
call %CATALINA_HOME%\bin\catalina.bat run 

脚本的执行结果如下: 
请观察上面窗口中的加亮部分,这部分向我们清楚地展示Tomcat的启动错误,没有找到Tomcat的启动主类Bootstrap。这是因为我们人为地把Tomcat的启动jar文件包从bootstrap.jar重命名为bootstrap_1.jar,这个bootstrap.jar文件既然不存在,那包含在这个文件的Bootstrap.class文件当然也就找不到了。 
现在,我们再回过头看看这个catalina.bat脚本。为简单起见,我们假定该脚本带缺省命令行参数start,看看catalina脚本的执行流程。如果您对catalina的security命令有兴趣,请参考Sun公司的文档http://java.sun.com/j2se/1.5.0/docs/guide/security/smPortGuide.html;如果您对jpda命令有兴趣,不妨浏览一下http://java.sun.com/javase/technologies/core/toolsapis/jpda/ 文档。让我们打开catalina脚本,首先请注意这个脚本第二行有一个setlocal的命令,这个命令表明catalina中的环境变量只在本脚本中起作用,对其它程序和命令不起作用,这就意味着这个脚本中的环境变量是局部变量,不是全局变量,不会影响其它脚本和操作系统环境。 
然后我们会看到长达34行的注释,这是优秀程序员必须学会的基本功之一。这些注释写得非常简洁明了,详细说明了各个环境变量的意义和用途。紧接着,如果发现CATALINA_HOME变量没有定义,该脚本试图设置该变量,这和startup.bat的第一节完全类似,在此不再赘述。然后该脚本调用setclasspath.bat到JAVA_HOME的bin目录下寻找java.exe、javaw.exe、jdb.exe和javac.exe所在的路径,并把这些exe文件的文件名和路径赋值到相应的环境变量_RUNJAVA、_RUNJAVAW、_RUNJDB和_RUNJAVAC中。再接下来,catalina脚本判断是否定义有环境变量CATALINA_BASE,CATALINA_TMPDIR,如果定义了它们,就执行相应的操作。因为我们在此并没有定义它们,所以执行不到这些操作。然后,catalina脚本将在本窗口内打印出四个环境变量的值,这四个环境变量我们非常熟悉,一旦启动Tomcat,我们必定能看到CATALINA_BASE,CATALINA_HOME,CATALINA_TMPDIR和JAVA_HOME。然后catalina脚本根据其后跟的不同命令,拼凑出完整的JAVA命令行并执行。下面是该脚本的详细注释: 
Rem 获得标准的环境变量,因为setenv.bat不存在,所以下面这两句不执行 
rem Get standard environment variables 
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat" 
Rem 调用setclasspath.bat脚本,获得标准的环境变量 
rem Get standard Java environment variables 
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath 
echo Cannot find %CATALINA_HOME%\bin\setclasspath.bat 
echo This file is needed to run this program 
goto end 
:okSetclasspath 
set BASEDIR=%CATALINA_HOME% 
call "%CATALINA_HOME%\bin\setclasspath.bat" 

rem根据不同情况在classpath中加上不同的jar包 
rem Add on extra jar files to CLASSPATH 
if "%JSSE_HOME%" == "" goto noJsse 
set CLASSPATH=%CLASSPATH%;%JSSE_HOME%\lib\jcert.jar;%JSSE_HOME%\lib\jnet.jar;%JSSE_HOME%\lib\jsse.jar

:noJsse 

Rem 注意下面的这个jar文件是tomcat的启动包 
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\bootstrap.jar 

rem 我们没有定义CATALINA_BASE,下面这节不执行 
if not "%CATALINA_BASE%" == "" goto gotBase 
set CATALINA_BASE=%CATALINA_HOME% 
:gotBase 
rem 我们没有定义CATALINA_ TMPDIR,下面这节将忽略 
if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir 
set CATALINA_TMPDIR=%CATALINA_BASE%\temp 

:gotTmpdir 

Rem 打印4个我们非常熟悉的环境变量 
rem ----- Execute The Requested Command --------------------------------------- 
echo Using CATALINA_BASE:   %CATALINA_BASE% 
echo Using CATALINA_HOME:   %CATALINA_HOME% 
echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR% 
echo Using JAVA_HOME:   %JAVA_HOME% 

rem 定义一些环境变量 
set _EXECJAVA=%_RUNJAVA% 
rem 这是Tomcat启动的主类 
set MAINCLASS=org.apache.catalina.startup.Bootstrap 
rem 这是catalina脚本的缺省命令start 
set ACTION=start 
set SECURITY_POLICY_FILE= 

set DEBUG_OPTS= 
set JPDA= 

rem 我们的第一个参数命令是start,下面这节将忽略不执行 
if not ""%1"" == ""jpda"" goto noJpda 
set JPDA=jpda 

if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport 

set JPDA_TRANSPORT=dt_shmem 

:gotJpdaTransport 

if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress 
set JPDA_ADDRESS=jdbconn 
:gotJpdaAddress 
shift 

:noJpda 

rem 我们的第一个参数命令是start,所以程序将走到doStart标签处执行 
if ""%1"" == ""debug"" goto doDebug 
if ""%1"" == ""run"" goto doRun 
if ""%1"" == ""start"" goto doStart 
if ""%1"" == ""stop"" goto doStop 
if ""%1"" == ""version"" goto doVersion 

rem 如果catalina后跟的命令不是debug, run, start, stop或version, 
rem 该脚本将打印出catalina的用法,然后结束。 
Rem 详情请见我们前面的测试脚本start_tomcat_nothing.bat及相应的结果窗口 
echo Usage: catalina ( commands ... ) 
echo commands: 
echo   debug   Start Catalina in a debugger 
echo   debug -security   Debug Catalina with a security manager 
echo   jpda start   Start Catalina under JPDA debugger 
echo   run   Start Catalina in the current window 
echo   run -security   Start in the current window with security manager 
echo   start   Start Catalina in a separate window 
echo   start -security   Start in a separate window with security manager 
echo   stop   Stop Catalina 
echo   version   What version of tomcat are you running? 
goto end 

rem 执行debug命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doDebug 
shift 
set _EXECJAVA=%_RUNJDB% 
set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\jakarta-tomcat-catalina\catalina\src\share" 

if not ""%1"" == ""-security"" goto execCmd 
shift 
echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

:doRun 
shift 
if not ""%1"" == ""-security"" goto execCmd 
shift 
echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

rem 执行start命令 
:doStart 
Rem 将参数列表指针指向下一个参数 
shift 
rem 设置Tomcat启动窗口的标题,缺省值为Tomcat 
if not "%OS%" == "Windows_NT" goto noTitle 
set _EXECJAVA=start "Tomcat" %_RUNJAVA% 
goto gotTitle 
:noTitle 
set _EXECJAVA=start %_RUNJAVA% 
:gotTitle 

Rem 检查第二个命令参数是否为-security,我们没有第二个命令参数,脚本将执行至execCmd标签处 
if not ""%1"" == ""-security"" goto execCmd 
shift 

echo Using Security Manager 
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy 
goto execCmd 

rem 执行stop命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doStop 
shift 
set ACTION=stop 
goto execCmd 

rem 执行version命令,我们的第一个参数命令是start,下面这节将忽略不执行 
:doVersion 
%_EXECJAVA% -classpath "%CATALINA_HOME%\server\lib\catalina.jar" org.apache.catalina.util.ServerInfo 
goto end 
rem 执行命令,首先看看命令行参数是否不只一个,我们本例只有一个start参数,所以下面这节将不执行 

:execCmd 
rem Get remaining unshifted command line arguments and save them in the 
set CMD_LINE_ARGS= 
:setArgs 
if ""%1""=="""" goto doneSetArgs 
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 
shift 

goto setArgs 
:doneSetArgs 

Rem 执行java命令行 
rem Execute Java with the applicable properties 
rem 检测JPDA和Security变量,我们本例没有定义他们,下面两句将忽略 
if not "%JPDA%" == "" goto doJpda 
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity 

rem 程序将执行下面的java命令,在新窗口内启动Tomcat 
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% 

Rem catalina至此结束,下面代码我们将忽略。 
goto end 
:end 




<Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <Listener className="org.apache.catalina.core.JasperListener" />
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
      <!-- 全局命名资源,来定义一些外部访问资源,其作用是为所有引擎应用程序所引用的外部资源的定义 --!>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <!-- 定义的一个名叫“UserDatabase”的认证资源,将conf/tomcat-users.xml加载至内存中,在需要认证的时候到内存中进行认证 -->
      <Service name="Catalina">
      <!-- # 定义Service组件,同来关联Connector和Engine,一个Engine可以对应多个Connector,每个Service中只能一个Engine --!>
        <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
        <!-- 修改HTTP/1.1的Connector监听端口为80.客户端通过浏览器访问的请求,只能通过HTTP传递给tomcat。  -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="test.com">
        <!-- 修改当前Engine,默认主机是,www.test.com  -->
        <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
        </Realm>
        # Realm组件,定义对当前容器内的应用程序访问的认证,通过外部资源UserDatabase进行认证
          <Host name="test.com"  appBase="/web" unpackWARs="true" autoDeploy="true">
          <!--  定义一个主机,域名为:test.com,应用程序的目录是/web,设置自动部署,自动解压    -->
            <Alias>www.test.com</Alias>
            <!--    定义一个别名www.test.com,类似apache的ServerAlias -->
            <Context path="" docBase="www/" reloadable="true" />
            <!--    定义该应用程序,访问路径"",即访问www.test.com即可访问,网页目录为:相对于appBase下的www/,即/web/www,并且当该应用程序下web.xml或者类等有相关变化时,自动重载当前配置,即不用重启tomcat使部署的新应用程序生效  -->
            <Context path="/bbs" docBase="/web/bbs" reloadable="true" />
            <!--  定义另外一个独立的应用程序,访问路径为:www.test.com/bbs,该应用程序网页目录为/web/bbs   -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/www/logs"
                   prefix="www_access." suffix=".log"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            <!--   定义一个Valve组件,用来记录tomcat的访问日志,日志存放目录为:/web/www/logs如果定义为相对路径则是相当于$CATALINA_HOME,并非相对于appBase,这个要注意。定义日志文件前缀为www_access.并以.log结尾,pattern定义日志内容格式,具体字段表示可以查看tomcat官方文档   -->
          </Host>
          <Host name="manager.test.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
          <!--   定义一个主机名为man.test.com,应用程序目录是$CATALINA_HOME/webapps,自动解压,自动部署   -->
            <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="172.23.136.*" />
            <!--   定义远程地址访问策略,仅允许172.23.136.*网段访问该主机,其他的将被拒绝访问  -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/bbs/logs"
                   prefix="bbs_access." suffix=".log"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            <!--   定义该主机的访问日志      -->
          </Host>
        </Engine>
      </Service>
    </Server>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值