-
main方法
-
第一阶段
-
第二阶段
-
第三阶段
-
启动参数的区别
-
一个Bug
-
configtest启动参数
一般,我们直接运行startup.sh
来
启动Tomcat
。最终执行的命令是:
java [options] org.apache.catalina.startup.Bootstrap start
options是JVM启动参数,这里忽略。
main方法
可见,Tomcat
的启动类是org.apache.catalina.startup.Bootstrap
,
启动参数是start
。我们从该类的main
方法看起。
public static void main(String args[]) {
try {
// Attempt to load JMX class
new ObjectName("test:foo=bar");
} catch (Throwable t) {
System.out.println(JMX_ERROR_MESSAGE);
try {
// Give users some time to read the message before exiting
Thread.sleep(5000);
} catch (Exception ex) {
}
return;
}
if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[0] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[0] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}
}
上述代码主要分为三段:
- 第一段是检查JMX
支持
- 第二段创建Boostrap
实
例并初始化
- 第三段根据启动参数,执行进一步操作
第一阶段
乍一看,第一段似乎可有可无。它只是创
建了一个不被使用的ObjectName
对象,如果创建失败,就打印一条错误信息。而
且在Tomcat 6
中,已经移除了这段代码。
try {
// Attempt to load JMX class
new ObjectName("test:foo=bar");
} catch (Throwable t) {
System.out.println(JMX_ERROR_MESSAGE);
try {
// Give users some time to read the message before exiting
Thread.sleep(5000);
} catch (Exception ex) {
}
return;
}
这段代码的作用是什么呢?这其实和J2SE
1.4
的兼容性有关。Tomcat 5
使用JMX
作为管理和监控机制,但是J2SE
1.4
本身并不支持JMX
,像ObjectName
这些JMX
类
并不包括J2SE 1.4
的API
中。因此,Tomcat 5
不能直接运行
在J2SE 1.4
及之前版本上。
但是Tomcat 5
的设计目标是支持运行在J2SE 1.4
上的。因此,要达到这个目标,Tomcat 5
须
将JMX
类作为兼容包(compatibility
package
)额外添加到Tomcat
启动类路径中。
我
们有两种方法获得兼容包:
- 从Tomcat
的官方下载
页面下载兼容包,参见http://tomcat.apache.org/download-55.cgi
- 从Tomcat
的源代码构建兼容包,参见http://jarfield.iteye.com/blog/604198
不
管怎样,Tomcat 5
不能保证用户安装了兼容包,因此在启动时,它首先检
查能够加载ObjectName
类,以此判断兼容包是否安装。如果没有安装,则向标准
输出打印一条错误信息:
This release of Apache Tomcat
was packaged to run on J2SE 5.0 or later. It can be run on earlier JVMs
by downloading and installing a compatibility package from the Apache
Tomcat binary download page.
这
条信息也就是第一段代码中JMX_ERROR_MESSAGE
变量的值。下面是Bootstrap
类声明该变量的代码:
private static final String JMX_ERROR_MESSAGE =
"This release of Apache Tomcat was packaged to run on J2SE 5.0 \n"
+ "or later. It can be run on earlier JVMs by downloading and \n"
+ "installing a compatibility package from the Apache Tomcat \n"
+ "binary download page.";
那为什么Tomcat
6中移除了第一段代码,不检查兼容包是否安装了呢?原因很简单,Tomcat 6的设计目标并不包括J2SE 1.4及之前版本。
OK
,看完了第一段,我们进入正题,看看第二段代码。
第二阶段
if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}
可见,这段代码的主要逻辑在Bootstrap
的init
方法。该方法的工作包括:
- 设
置Catalina
(Tomcat Servlet
容器的代号)的路径:CATALINA_HOME
和CATALINA_BASE
- 初始化Tomcat
的类加载器体系
- 创建org.apache.catalina.startup.Catalina
对
象(启动阶段剩余的工作由Catalina类
完成)
为了
节省篇幅,init
方法的代码另文表述
。下面我们看看第三段代码。
第三阶段
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[0] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[0] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}
容
易看出,这段代码的主要逻辑就是根据不同的启动参数,执行不同的工作。可以接受的启动参数包括4
种:startd stopd start stop
。
启动参数决定了启动还是停止Tomcat
。如何启动,如何停止,另文表述
。本文问想讨论的问题是:除了start
和stop
,为什么
还有startd
和stopd
?
它们有什么区别呢?
启动参数的区别
我们先看看start
和startd
。处理start
的
代码比startd
仅多了一行:
daemon.setAwait(true);
这行代码执行后,主线程(即main
函数所在的线程)在Tomcat
启
动过程结束时并不会退出,而是监听SHUTDOWN
端口(默认端口是8005
)。该端口如果接收SHUTDOWN
命
令,就停止Tomcat
;如果收到的是其他命令,则忽略,继续监听。这样,我
们就可以在Tomcat
进程之外通过网络停止Tomcat
。
如果以startd
参
数启动Tomcat
,主线程会在启动结束时退出,只剩下主线程创建的其他线程
(HTTP
监听线程、HTTP
请求线程、Tomcat
后台线程等)。
这样,我们并不能通过网络停止Tomcat
。
如果启动参数是stop
,那么将调用Bootstrap类
的stopServer
方法。该方法通过SHUTDOWN
端口向Tomcat
发送SHUTDOWN
命
令,从而停止Tomcat
。shutdown.bat
就是通过这种方式关闭Tomcat
,
它最终执行的命令是:
java [options]
org.apache.catalina.startup.Bootstrap stop
如果启动参数是stopd,那么
Bootstrap将直接调用Catalina的stop方法,直接停止Tomcat。
综上所述,以start
启动,就以stop
停
止;以startd
启动,就以stopd
停
止。
如果将Tomcat
作为独立的进程运行,那么应该使用start
和stop
,这样
我们就可以通过网络停止Tomcat
。
如果将Tomcat
以嵌入到应用进程的方式运行(例如Eclipse
中运行Tomcat
),
那么应该使用startd
和stopd
。
这样,宿主程序通过普通的方法调用,来启动和停止Tomcat
。
一个Bug
关于这4
个启动参数的讨论,可以参见Bug
47881
。这个Bug
的本意是要指出第三段代码的一个问题
,不过恰好讨论了各种启动参数的区别。
至于这个Bug
,也比较明显:
-
args[0] = "start";
应该是 args[args.length - 1
] = "start";
-
args[0] = "stop";
应该是 args[args.length - 1
] = "stop";
这
个Bug
已经在Tomcat
6
中解决了。
Tomcat 7中引入的configtest启动参数
在Tomcat 7中,新增了configtest启动参数。
public static void main(String args[]) {
// 省略部分代码
if (command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
// 省略部分代码
} else if (command.equals("configtest")) {
daemon.load(args);
if (null==daemon.getServer()) {
System.exit(1);
}
System.exit(0);
} else {
// 省略部分代码
}
顾名思义,configtest是为了检测配置参数是否正确,配置参数的主要来源就是conf/server.xml。
从代码可以看出,configtest启动参数就是把load方法给执行了一遍,然后无条件退出。load方法的代码,另文表述
。这里只要知道,load的主要工作之一就是解析conf/server.xml,从而起到检测配置参数是否正确的作用。
configtest通过exit status来返回检测结果。1表示检测到错误,0表示检测结果正确。如果load方法执行成功,就会创建server实例,通过daemon.getServer方法返回;反之,如果配置参数不正确,load方法执行失败,那么就不创建server实例,deamon.getServer方法就返回null。
分享到:
相关推荐
Apache Tomcat 5.5.26 是一个广泛使用的开源软件,它是一个符合Java Servlet和JavaServer Pages(JSP)规范的应用服务器,主要用于部署和运行Java Web应用程序。Tomcat是Apache软件基金会Jakarta项目的一部分,它以...
在描述中提到,Tomcat服务器是免费且开放源代码的,这意味着任何人都可以访问其源代码,对其进行修改并自由分发。它的轻量级特性意味着它对系统资源的需求相对较低,特别适合中小规模的Web应用程序。此外,Tomcat ...
这个"apache-tomcat-5.5.26 免安装"版本是专为那些不想进行复杂安装过程的用户设计的,只需解压缩即可立即使用。 Tomcat 5.5.26 是该服务器的一个特定版本,发布于2008年,是Tomcat 5.x系列中的一个稳定版本。在这...
1. **Tomcat 5.5.26**: 这是Apache Tomcat的一个较早版本,发布于2008年。Tomcat遵循Java EE规范中的Servlet和JSP标准,它提供了一个轻量级、高效的Web服务器和应用服务器。5.5.x系列是Tomcat的稳定版本,对许多企业...
Apache Tomcat 5.5.26 是一个广泛使用的开源软件,它是一个符合Java Servlet和JavaServer Pages(JSP)规范的应用服务器,主要用于部署和运行Java Web应用程序。这个版本的Tomcat是在Java EE 5标准下开发的,因此它...
Tomcat 5.5.26是一款历史悠久且广受欢迎的开源Web应用程序服务器,由Apache软件基金会的Jakarta项目开发。它主要用于部署和运行Java Servlets和JavaServer Pages (JSP)。Tomcat是Java EE(企业版)的一部分,尽管它...
这个压缩包"Apache tomcat 5.5.26_src.zip"包含了Tomcat 5.5.26版本的源代码,对于开发者来说,它是深入理解Tomcat工作原理、定制或扩展其功能的重要资源。 Apache Tomcat 的主要功能包括: 1. **Servlet容器**:...
另一个文件“apache-tomcat-5.5.26”看起来是Tomcat服务器的解压后的核心目录,其中包含了运行Tomcat所需的所有文件,比如启动脚本、配置文件、Web应用程序的默认目录(webapps)、日志文件存放位置(logs)、临时...
### RHEL5 + Apache2.2.6 + Tomcat5.5.26 整合:构建高效Web服务器环境 #### 第一部分:安装与配置Apache2.2.6 Apache作为全球广泛使用的Web服务器软件之一,其稳定性与性能备受好评。在本教程中,我们将学习如何...
2. **解压Apache源代码**:对于开发者,"httpd-2.2.9-win32-src.zip"包含Apache的源代码,你可以从中了解其工作原理或自定义编译配置。 3. **JK插件(mod_jk)的获取**:"mod_jk-1.2.26-httpd-2.2.4.so"是适用于...
Apache Tomcat 5.5.26 是一个广泛使用的开源软件,它是一个符合Java Servlet和JavaServer Pages(JSP)规范的应用服务器,主要用于部署和运行Java Web应用程序。Tomcat是Apache软件基金会Jakarta项目的一部分,以其...
总之,Tomcat 5.5.26是一个功能强大且易用的Java Web服务器,它为开发者提供了一个轻量级、高效的平台,用于构建和运行基于Java技术的Web应用程序。在实际应用中,我们需要根据具体需求对其进行配置和优化,以达到...
"tomcat-5.5.26集成了richfaces-demo" 这个标题表明我们讨论的是一个特定版本的Tomcat服务器——Tomcat 5.5.26,它已经预装了一个名为"richfaces-demo"的示例应用。RichFaces是一个JavaServer Faces (JSF)组件库,...
用于解决使用 Tomcat 5.5.26 Administration Tool 的 Delete Existing Hosts 功能时发生 HTTP Status 500 错误,详见 http://blog.csdn.net/LaoBai_2006/archive/2008/08/28/2844042.aspx。 md5: f8ad905990a96f...
打开D:\apache-tomcat-5.5.26\conf下的tomcat-users.xml,添加下面一句: xml 代码 roles="admin,manager"/> 启动tomcat,然后打开IE:http://localhost:8080,点击Tomcat Administration即可进入Tomcat server ...