Tomcat运行脚本及启动过程分析--catalina.sh

一、概述

作为一个成熟的中间件产品,tomcat有很多值得我们学习的地方。下面我将从tomcat的运行脚本catalina.sh入手,分析tomcat的启动过程,以及tomcat脚本是如何实现停止tomcat服务的。

注意:此处分析的是linux环境下的脚本文件

二、tomcat目录结构

tomcat目录结构如下:

bin目录的内容如下:

  • 可执行文件,包括startup.sh、shutdown.sh、catalina.sh
  • tomcat启动所依赖的jar包,包括 bootstrap.jar、tomcat-juli.jar

三、脚本分析

我会介绍每个脚本的主要逻辑,并对涉及到的linux命令做简要介绍。脚本中做了大部分的注释,请结合注释理解。毕竟是代码,干说是很难描述的,注释效果更好。

startup.sh

#!/bin/sh

# 1)检测是否为os400操作系统
os400=false
case "`uname`" in
OS400*) os400=true;;
esac

# 2)PRG表示脚本路径,如果当前脚本文件为软链接,则会解析出PRG真正文件所在路径
# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do # -h 判断是否为软链接
  ls=`ls -ld "$PRG"` # 如果为软链接,输出中含有 link -> source 的字串
  link=`expr "$ls" : '.*-> \(.*\)$'` # 模式匹配出源文件的路径,对这里感觉模糊请搜索“expr模式匹配”
  if expr "$link" : '/.*' > /dev/null; then # 匹配 /.*,这里expr会输出匹配个数,如果不为0,说明$link包含目录
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link" # 当不包含目录,说明软链接和源文件在同一目录
  fi
done

#获取脚本目录路径
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh

# Check that target executable exists
if $os400; then
  # -x will Only work on the os400 if the files are:
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  eval
else
  if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
    echo "Cannot find $PRGDIR/$EXECUTABLE"
    echo "The file is absent or does not have execute permission"
    echo "This file is needed to run this program"
    exit 1
  fi
fi

# 3)执行catalina.sh start
exec "$PRGDIR"/"$EXECUTABLE" start "$@"

脚本主要逻辑如下:

1. 检测操作系统,以兼容特定操作系统的特性

  • uname 显示操作系统信息

2. 获取脚本路径

这段代码几乎在所有启动脚本、停止脚本的开头都会出现。为了防止获取到的路径是软链接的路径,需要对路径做解析。

  • expr命令解释

1)expr  string : regex

       这种形式下,会用:后面的正则表达式匹配前面的字符串,输出匹配的个数

2)expr string : xxx\(zzz\ )

      这种形式下,\(zzz\)中,zzz匹配的字符串会被输出

3.执行catalina.sh start

<think>嗯,用户遇到了Tomcat启动时的错误,日志里提到了几行关于JMX参数的报错,比如“command not found”。我需要先理解这些错误的原因。JMX是用于监控和管理Java应用的,用户可能在配置Tomcat时添加了这些参数,但可能放错了地方。 首先,错误提示显示在catalina.sh的某些行中找不到这些命令,这说明这些参数可能被当作Shell命令执行了,而实际上它们应该是Java启动参数。用户可能是在CATALINA_OPTS或者JAVA_OPTS环境变量中设置了这些参数,但错误地写在了脚本的其他位置,比如直接写在了catalina.sh脚本里,而没有放在正确的变量中。 接下来,我需要回忆Tomcat启动脚本结构。通常,用户应该在setenv.sh文件中设置JAVA_OPTS或者CATALINA_OPTS,这样在启动脚本会自动加载这些参数。如果用户直接修改了catalina.sh,把参数写在了执行命令的前面,那么Shell会尝试执行这些参数,导致报错,因为参数被当成了命令。 然后,解决方案应该是检查用户修改了哪些地方,将这些JMX参数从脚本的命令行中移动到正确的环境变量里。例如,在setenv.sh中定义JAVA_OPTS,包含所有的-D参数。另外,用户需要确认是否使用了正确的变量名,比如CATALINA_OPTS和JAVA_OPTS的区别,CATALINA_OPTS通常用于Tomcat特定的参数,而JAVA_OPTS用于所有Java应用的参数。 另外,可能用户没有正确设置环境变量的位置,或者在脚本中错误地添加了这些参数。需要指导用户检查catalina.sh中是否有直接写入的这些参数,如果有的话,应该删除,并转移到setenv.sh中。 最后,可能还需要提醒用户关于安全性的问题,因为JMX的配置如果暴露在网络上,尤其是关闭了SSL和认证,可能会带来安全风险。建议用户在生产环境中启用SSL和认证,或者确保JMX端口不被公开访问。</think>这个错误是由于在 `catalina.sh` 中错误地放置了JMX监控参数导致的。以下是逐步解决方案: --- ### **问题定位** 错误提示表明:`catalina.sh` 尝试将 `-D` 开头的Java虚拟机参数(JMX监控参数)当作Shell命令执行,说明参数未正确传递给Java进程,而是被Shell解析为命令。 --- ### **解决方案** #### **1. 检查参数放置位置** JMX参数应通过环境变量 **`JAVA_OPTS`** 或 **`CATALINA_OPTS`** 传递,而非直接写入 `catalina.sh` 脚本主体中。 #### **2. 修改配置文件** -Tomcat的 `bin` 目录下创建或编辑 `setenv.sh` 文件: ```bash vi /data/tomcat/apache-tomcat/bin/setenv.sh ``` - 添加以下内容(注意参数格式): ```bash export JAVA_OPTS="$JAVA_OPTS \ -Dcom.sun.management.jmxremote \ -Djava.rmi.server.hostname=127.0.0.1 \ -Dcom.sun.management.jmxremote.port=9999 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false" ``` **注意**:参数必须连续书写,每行以 `\` 换行符结尾(确保无空格干扰)。 #### **3. 修复脚本错误** 检查 `catalina.sh` 第511-515行,**删除直接写入的JMX参数**(类似 `-Dcom.sun.management.jmxremote` 的代码行)。 #### **4. 赋予执行权限** ```bash chmod +x /data/tomcat/apache-tomcat/bin/setenv.sh ``` #### **5. 重启Tomcat** ```bash /data/tomcat/apache-tomcat/bin/shutdown.sh /data/tomcat/apache-tomcat/bin/startup.sh ``` --- ### **验证JMX配置** 通过 `jconsole` 或 `jvisualvm` 连接JMX端口(默认 `127.0.0.1:9999`),确认监控功能正常。 --- ### **附加说明** - **安全性警告**:示例中关闭了SSL和认证(`ssl=false`, `authenticate=false`),**仅限内网测试环境使用**。生产环境需启用SSL和密码认证。 - **环境变量选择**:`CATALINA_OPTS` 和 `JAVA_OPTS` 的区别: - `CATALINA_OPTS`:仅Tomcat启动时生效 - `JAVA_OPTS`:所有Java进程共享(可能影响其他应用) --- ### **关联问题** 1. **如何排查其他Tomcat启动错误?** 检查 `logs/catalina.out` 日志,关注 `SEVERE` 或 `ERROR` 级别的报错。 2. **如何限制JMX端口仅本地访问?** 保持 `-Djava.rmi.server.hostname=127.0.0.1` 并配置防火墙规则。 3. **如何启用JMX认证?** 参考Oracle文档生成密码文件和访问控制文件,设置 `authenticate=true` 并指定路径。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值