【9.Tomcat底层剖析与性能优化】2.3 启动入口脚本

好的,我们来深入解析一下 Tomcat 的启动入口脚本。这对于理解 Tomcat 的启动机制、自定义启动参数以及排查启动相关问题至关重要。

Tomcat 的启动脚本主要位于
$CATALINA_HOME/bin/
目录下。虽然脚本有 Windows(
.bat
)和 Unix/Linux(
.sh
)两个版本,但它们的核心逻辑和目标是完全一致的。

核心脚本文件


startup.sh
/
startup.bat

这是最直接的入口。用户通常执行这个脚本来启动 Tomcat。但它本质上只是一个快捷方式包装器,它的核心工作是设置基本环境,然后调用主脚本
catalina.sh
/
catalina.bat


catalina.sh
/
catalina.bat

这是真正意义上的核心脚本,包含了所有启动、停止、调试等逻辑。
startup.sh
调用
catalina.sh start

shutdown.sh
调用
catalina.sh stop


setenv.sh
/
setenv.bat

这是一个可选的、用户自定义的脚本。默认情况下它不存在。如果创建了这个文件,
catalina.sh
会执行它。这是设置自定义环境变量(如
JAVA_OPTS
,
CATALINA_OPTS
)的最佳位置
,因为它不会被 Tomcat 升级所覆盖。


setclasspath.sh
/
setclasspath.bat


catalina.sh
调用,用于设置 Java JDK/JRE 的路径和基本的 JAR 文件路径(
bootstra
p.jar)。


脚本执行流程详解 (以 Linux
catalina.sh
为例)

当我们执行
./startup.sh
时,会发生以下事情:

第一阶段:
startup.sh
的工作


startup.sh
的代码非常简洁,其核心逻辑是:

确定
CATALINA_HOME

通过
dirname $0
命令定位到脚本自身的目录(即
bin/
目录),然后将其父目录设置为
CATALINA_HOME

检查
catalina.sh
是否存在

传递参数并执行

最终,它调用:


exec "$CATALINA_HOME"/bin/catalina.sh start "$@"

这里的
start
是传递给
catalina.sh
的命令参数。

第二阶段:
catalina.sh
的核心工作

这才是重头戏。
catalina.sh
的执行可以分为以下几个步骤:

步骤 1: 设置环境变量和路径

设置
CATALINA_HOME

CATALINA_BASE
(如果未设置,两者默认相同)。设置
OS

ARCH
等系统信息变量。

步骤 2: 执行用户自定义设置 (
setenv.sh
)

这是脚本中非常关键的一步:


if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

它会优先检查
$CATALINA_BASE/bin/setenv.sh
,然后是
$CATALINA_HOME/bin/setenv.sh
,如果找到就执行。你可以在
setenv.sh
里设置:


# 示例 setenv.sh
export JAVA_OPTS="-Xms512M -Xmx1024M -Dspring.profiles.active=prod"
export CATALINA_OPTS="-XX:+UseG1GC"

步骤 3: 设置 Java 环境 (
setclasspath.sh
)

调用
setclasspath.sh
脚本。
setclasspath.sh
会检查
JAVA_HOME

JRE_HOME
环境变量是否已设置。如果没有设置,脚本会尝试自动查找,但强烈建议在系统或
setenv.sh
中显式设置
JAVA_HOME
。它还会设置启动 Tomcat 所必需的最初 JAR 文件路径:
$CATALINA_HOME/bin/bootstrap.jar

步骤 4: 构建最终的 Java 命令并执行

这是脚本的最终目标:组装一个长长的
java
命令行。类路径 (CLASSPATH):主要包含
bootstrap.jar

$CATALINA_HOME/bin/tomcat-juli.jar
主类 (Main Class)
org.apache.catalina.startup.Bootstrap
命令行参数:根据调用时传入的动作(如
start
,
stop
,
run
)来添加参数。

start
:以后台守护进程模式启动。
run
:在前台控制台启动(便于查看日志)。
stop
:传递
stop
参数给
Bootstrap
类以关闭 Tomcat。
Java 选项:组合
JAVA_OPTS

CATALINA_OPTS


JAVA_OPTS
:任何 Java 应用都可以使用的通用选项。
CATALINA_OPTS
专门为 Tomcat 设置的选项。通常推荐将 Tomcat 相关的内存、GC 等设置放在这里。

最终组装出来的命令大致如下:


java 
    $JAVA_OPTS $CATALINA_OPTS       # 合并所有JVM参数
    -Djava.endorsed.dirs="..."      #  endorsed目录
    -classpath "$CLASSPATH"         # 包含bootstrap.jar等
    -Dcatalina.base="$CATALINA_BASE" 
    -Dcatalina.home="$CATALINA_HOME" 
    -Djava.io.tmpdir="$CATALINA_TMPDIR" 
    org.apache.catalina.startup.Bootstrap  # 主类
    start "$@"                        # 传递给Bootstrap的参数
第三阶段:
Bootstrap
类接管

脚本的工作到此结束。之后,JVM 开始运行,加载
bootstrap.jar
中的
org.apache.catalina.startup.Bootstrap
类,并执行其
main()
方法。脚本传递的
start
参数和所有环境变量(如
catalina.home
,
catalina.base
)都会交给
Bootstrap
类,由它开始执行我们之前讨论过的 Java 部分的启动时序(初始化 Catalina 组件、加载 server.xml 等)。


关键环境变量总结

变量名 说明 示例

JAVA_HOME
必须。指向 JDK 的安装目录。
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

CATALINA_HOME
Tomcat 的安装目录,包含 lib, bin 等。通常由脚本自动设置。

CATALINA_BASE
实例目录。用于运行多个 Tomcat 实例。默认为
CATALINA_HOME

JAVA_OPTS
传递给 JVM 的通用参数。
export JAVA_OPTS="-Xms512m -Xmx1024m"

CATALINA_OPTS
推荐。专门用于 Tomcat 启动的 JVM 参数。
export CATALINA_OPTS="-XX:+UseG1GC -Dapp.env=prod"

CATALINA_OUT
指定
catalina.out
日志文件的完整路径。

export CATALINA_OUT=/var/log/tomcat/catalina.out

CATALINA_PID
指定存储 Tomcat 进程号 (PID) 的文件位置。用于可靠地停止服务。
export CATALINA_PID=$CATALINA_BASE/tomcat.pid

最佳实践与技巧

使用
setenv.sh
:永远不要直接修改
catalina.sh
。将你的自定义设置(尤其是
JAVA_OPTS
/
CATALINA_OPTS
)放在
$CATALINA_BASE/bin/setenv.sh
中。这样在 Tomcat 升级时,你的配置不会被覆盖。

前台启动用于调试:在遇到启动问题时,使用
./catalina.sh run
命令。这会在前台启动 Tomcat,并将所有日志输出直接打印到控制台,方便你实时查看错误信息。

使用
jpda
进行远程调试
:执行
./catalina.sh jpda start
可以以调试模式启动 Tomcat,并监听默认端口(8000)。你可以在 IDE 中配置远程调试来连接它。

配置
CATALINA_PID
:在生产环境中,设置
CATALINA_PID
可以让
shutdown.sh
脚本更可靠地停止 Tomcat,因为它会直接向该 PID 发送信号,而不是依靠端口连接。

总结

Tomcat 的启动脚本是一个精心设计的链条:

startup.sh
->
catalina.sh
-> (
setenv.sh
) ->
setclasspath.sh
-> 组装
java
命令 -> 执行
org.apache.catalina.startup.Bootstrap
类。

理解这个链条,特别是
catalina.sh

setenv.sh
的作用,是有效管理和定制 Tomcat 实例的关键。它完成了从操作系统 shell 环境到 Java 虚拟机世界的所有桥梁工作。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
妖魔鬼怪快走开的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容