Manager 应用程序操作指南

目录

简介

在许多生产环境中,无需关闭并重新启动整个容器即可部署新的 Web 应用程序或卸载现有应用程序的能力非常有用。此外,您还可以请求现有应用程序重新加载自身,即使您尚未在 Tomcat 服务器配置文件中将其声明为 reloadable

为支持这些功能,Tomcat 包含一个 Web 应用程序(默认安装在上下文路径 /manager 上),该应用程序支持以下功能:

  • 从上传的 WAR 文件内容部署新的 Web 应用程序。
  • 在指定的上下文路径上,从服务器文件系统部署新的 Web 应用程序。
  • 列出当前已部署的 Web 应用程序,以及这些 Web 应用程序当前活动的会话。
  • 重新加载现有 Web 应用程序,以反映 /WEB-INF/classes/WEB-INF/lib 内容的变化。
  • 列出操作系统和 JVM 属性值。
  • 列出可用的全局 JNDI 资源,供部署工具在使用 <Context> 部署描述中嵌套 <ResourceLink> 元素时使用。
  • 启动已停止的应用程序(使其再次可用)。
  • 停止现有应用程序(使其不可用),但不卸载它。
  • 卸载已部署的 Web 应用程序并删除其文档根目录(除非它是从文件系统部署的)。

默认的 Tomcat 安装包含一个为默认虚拟主机配置的 Manager 应用程序实例。如果您创建了额外的虚拟主机,您可能希望将 Manager 应用程序的实例添加到其中一个或多个主机。要将 Manager Web 应用程序 Context 的实例添加到新主机,请将 manager.xml 上下文配置文件安装到 $CATALINA_BASE/conf/[enginename]/[hostname] 文件夹中。示例如下:

<Context privileged="true" antiResourceLocking="false"
         docBase="${catalina.home}/webapps/manager">
  <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
                   sameSiteCookies="strict" />
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

使用 Manager Web 应用程序有三种方式。

  • 作为您在浏览器中使用的带用户界面的应用程序。这是一个示例 URL,您可以将 localhost 替换为您的网站主机名:http://localhost:8080/manager/html
  • 一个仅使用 HTTP 请求的最小版本,适用于系统管理员设置的脚本。命令作为请求 URI 的一部分给出,响应以简单的文本形式返回,易于解析和处理。更多信息请参阅支持的 Manager 命令
  • 一套方便的 Ant (版本 1.4 或更高) 构建工具任务定义。更多信息请参阅使用 Ant 执行 Manager 命令

配置 Manager 应用程序访问

以下描述中,变量名 $CATALINA_BASE 指的是大多数相对路径解析所依据的基础目录。如果您没有通过设置 CATALINA_BASE 目录来配置 Tomcat 的多个实例,那么 $CATALINA_BASE 将设置为 $CATALINA_HOME 的值,即您安装 Tomcat 的目录。

如果 Tomcat 允许互联网上的任何人执行服务器上的 Manager 应用程序,默认设置将是相当不安全的。因此,Manager 应用程序的发布要求任何尝试使用它的人都必须通过用户名和密码进行身份验证,这些用户名和密码必须与 manager-xxx 角色之一相关联(角色名称取决于所需的功能)。此外,默认用户文件($CATALINA_BASE/conf/tomcat-users.xml)中没有分配给这些角色的用户名。因此,默认情况下,Manager 应用程序的访问是完全禁用的。

您可以在 Manager Web 应用程序的 web.xml 文件中找到角色名称。可用的角色有:

  • manager-gui — 访问 HTML 界面。
  • manager-status — 仅访问“服务器状态”页面。
  • manager-script — 访问本文档中描述的对工具友好的纯文本界面,以及“服务器状态”页面。
  • manager-jmx — 访问 JMX 代理界面和“服务器状态”页面。

HTML 界面受 CSRF(跨站请求伪造)攻击保护,但文本和 JMX 界面无法保护。这意味着允许访问文本和 JMX 界面的用户在使用网页浏览器访问 Manager 应用程序时必须谨慎。为保持 CSRF 保护:

  • 如果您使用 Web 浏览器访问 Manager 应用程序,并且使用的用户具有 manager-scriptmanager-jmx 角色(例如,用于测试纯文本或 JMX 界面),则之后必须关闭浏览器的所有窗口以终止会话。如果您不关闭浏览器并访问其他网站,您可能会成为 CSRF 攻击的受害者。
  • 建议永远不要将 manager-scriptmanager-jmx 角色授予具有 manager-gui 角色的用户。

注意,JMX 代理接口实际上是 Tomcat 的低级类似根的管理接口。如果知道要调用什么命令,可以做很多事情。在启用 manager-jmx 角色时应谨慎。

要启用对 Manager Web 应用程序的访问,您必须创建新的用户名/密码组合并将其与 manager-xxx 角色之一关联,或者将 manager-xxx 角色添加到某个现有用户名/密码组合中。由于本文档大部分描述的是文本界面的使用,本示例将使用角色名 manager-script。用户名/密码的具体配置方式取决于您正在使用的Realm 实现

  • UserDatabaseRealmMemoryUserDatabase,或 MemoryRealmUserDatabaseRealmMemoryUserDatabase 在默认的 $CATALINA_BASE/conf/server.xml 中配置。MemoryUserDatabaseMemoryRealm 默认读取一个 XML 格式的文件,该文件通常存储在 $CATALINA_BASE/conf/tomcat-users.xml,可以用任何文本编辑器编辑。该文件包含一个 XML <user> 元素,用于每个用户,其内容可能如下所示:
    <user username="craigmcc" password="secret" roles="standard,manager-script" />
    这定义了该用户用于登录的用户名和密码,以及他们所关联的角色名称。您可以将 manager-script 角色添加到逗号分隔的 roles 属性中,用于一个或多个现有用户,和/或创建具有该角色的新用户。
  • DataSourceRealm — 您的用户和角色信息存储在通过 JDBC 访问的数据库中。按照您环境的标准程序,将 manager-script 角色添加到一个或多个现有用户,和/或创建具有此角色的一或多个新用户。
  • JNDIRealm — 您的用户和角色信息存储在通过 LDAP 访问的目录服务器中。按照您环境的标准程序,将 manager-script 角色添加到一个或多个现有用户,和/或创建具有此角色的一或多个新用户。

第一次尝试发出下一节中描述的 Manager 命令之一时,系统将要求您使用基本认证登录。您输入的用户名和密码无关紧要,只要它们标识了用户数据库中拥有 manager-script 角色的有效用户即可。

除了密码限制外,还可以通过添加 RemoteAddrValveRemoteHostValve 来通过远程 IP 地址或主机限制对 Manager web 应用程序的访问。有关详细信息,请参阅阀门文档。以下是按 IP 地址限制对 localhost 访问的示例:

<Context privileged="true">
         <Valve className="org.apache.catalina.valves.RemoteAddrValve"
                allow="127\.0\.0\.1"/>
</Context>

HTML 用户友好界面

Manager Web 应用程序的用户友好 HTML 界面位于:

http://{host}:{port}/manager/html

如上所述,您需要 manager-gui 角色才能访问它。有一份单独的文档提供了关于此界面的帮助。请参阅:

HTML 界面受 CSRF(跨站请求伪造)攻击保护。每次访问 HTML 页面都会生成一个随机令牌,该令牌存储在您的会话中,并包含在页面上的所有链接中。如果您的下一次操作没有正确的令牌值,则该操作将被拒绝。如果令牌已过期,您可以从 Manager 的主页或应用程序列表页面重新开始。

要自定义 Manager Web 应用程序 HTML 界面的副标题,您可以将任何有效的 XML 转义 HTML 代码添加到 HTMLManagerServlethtmlSubTitle 初始化参数中:

<servlet>
  <servlet-name>HTMLManager</servlet-name>
  <servlet-class>org.apache.catalina.manager.HTMLManagerServlet</servlet-class>
  <init-param>
    <param-name>htmlSubTitle</param-name>
    <param-value>Company Inc.&lt;br&gt;&lt;i style=&apos;color:red&apos;&gt;Staging&lt;/i&gt;</param-value>
  </init-param>
  ...
</servlet>

上述字符串值将被反转义并追加到标题中。

Company Inc.<br><i style='color:red'>Staging</i>

支持的 Manager 命令

Manager 应用程序知道如何处理的所有命令都指定在一个单独的请求 URI 中,如下所示:

http://{host}:{port}/manager/text/{command}?{parameters}

其中 {host}{port} 表示 Tomcat 运行的主机名和端口号,{command} 表示您希望执行的 Manager 命令,{parameters} 表示该命令特有的查询参数。在下面的示例中,请根据您的安装情况适当自定义主机和端口。

命令通常由 HTTP GET 请求执行。/deploy 命令有一种通过 HTTP PUT 请求执行的形式。

通用参数

大多数命令接受以下一个或多个查询参数:

  • path - 您正在处理的 Web 应用程序的上下文路径(包括前导斜杠)。要选择 ROOT Web 应用程序,请指定 "/"。
    注意:无法对 Manager 应用程序本身执行管理命令。
    注意:如果未明确指定 path 参数,则 path 和 version 将根据 config 参数的标准上下文命名规则派生;如果 config 参数不存在,则根据 war 参数派生。
  • version - 此 Web 应用程序的版本,由并行部署功能使用。如果您在需要路径的地方使用并行部署,则除了路径之外还必须指定版本,并且路径和版本的组合必须是唯一的,而不仅仅是路径。
    注意:如果未明确指定路径,则版本参数将被忽略。
  • war - Web 应用程序归档 (WAR) 文件的 URL,或包含 Web 应用程序的目录路径名,或 Context 配置 ".xml" 文件。您可以使用以下任何格式的 URL:
    • file:/absolute/path/to/a/directory - 包含 Web 应用程序解压版本的目录的绝对路径。此目录将不经任何更改地附加到您指定的上下文路径。
    • file:/absolute/path/to/a/webapp.war - Web 应用程序归档 (WAR) 文件的绝对路径。这适用于 /deploy 命令,并且是该命令唯一可接受的格式。
    • file:/absolute/path/to/a/context.xml - 包含 Context 配置元素的 Web 应用程序 Context 配置 ".xml" 文件的绝对路径。
    • directory - 主机应用程序基本目录中 Web 应用程序上下文的目录名称。
    • webapp.war - 位于主机应用程序基本目录中的 Web 应用程序 WAR 文件名。

每个命令都将以 text/plain 格式(即纯 ASCII,无 HTML 标记)返回响应,使人类和程序都易于阅读。响应的第一行将以 OKFAIL 开头,指示请求的命令是否成功。如果失败,第一行的其余部分将包含遇到的问题的描述。某些命令包含其他信息行,如下所述。

国际化注意事项 - Manager 应用程序在资源包中查找其消息字符串,因此字符串可能已针对您的平台进行了翻译。以下示例显示了消息的英文版本。

远程部署新的应用程序归档文件 (WAR)

http://localhost:8080/manager/text/deploy?path=/foo

上传在此 HTTP PUT 请求中指定为请求数据的 Web 应用程序归档 (WAR) 文件,将其安装到对应虚拟主机的 appBase 目录中,并启动,从指定路径派生添加到 appBase 的 WAR 文件的名称。该应用程序稍后可以通过使用 /undeploy 命令进行卸载(并移除相应的 WAR 文件)。

此命令通过 HTTP PUT 请求执行。

.WAR 文件可以通过在 /META-INF/context.xml 中包含一个 Context 配置 XML 文件来包含 Tomcat 特定的部署配置。

URL 参数包括:

  • update: 当设置为 true 时,任何现有更新将首先被卸载。默认值为 false。
  • tag: 指定一个标签名称,这允许将已部署的 Web 应用程序与一个标签或标记关联。如果 Web 应用程序被卸载,以后只需使用该标签即可重新部署。
  • config: Context 配置 ".xml" 文件的 URL,格式为 file:/absolute/path/to/a/context.xml。这必须是包含 Context 配置元素的 Web 应用程序 Context 配置 ".xml" 文件的绝对路径。

注意 - 此命令与 /undeploy 命令在逻辑上是相反的。

如果安装和启动成功,您将收到如下响应:

OK - Deployed application at context path /foo

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 应用程序已存在于路径 /foo

    所有当前运行的 Web 应用程序的上下文路径必须是唯一的。因此,您必须使用此上下文路径卸载现有 Web 应用程序,或为新的 Web 应用程序选择不同的上下文路径。可以在 URL 上指定 update 参数,其值为 true 以避免此错误。在这种情况下,将在执行部署之前对现有应用程序执行卸载。

  • 遇到异常

    尝试启动新的 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息,但可能的原因包括解析 /WEB-INF/web.xml 文件时出现问题,或在初始化应用程序事件监听器和过滤器时缺少类。

从本地路径部署新应用程序

部署并启动一个新的 Web 应用程序,将其附加到指定的上下文 path(该路径不得被任何其他 Web 应用程序使用)。此命令与 /undeploy 命令在逻辑上是相反的。

此命令通过 HTTP GET 请求执行。部署命令有多种不同的使用方式。

部署之前已部署的 web 应用程序

http://localhost:8080/manager/text/deploy?path=/footoo&tag=footag

这可用于部署以前已部署的 Web 应用程序,该应用程序已使用 tag 属性进行部署。请注意,Manager Web 应用程序的工作目录将包含以前部署的 WAR 文件;删除它将导致部署失败。

通过 URL 部署目录或 WAR

部署位于 Tomcat 服务器上的 Web 应用程序目录或“.war”文件。如果未指定 path,则路径和版本将从目录名或 war 文件名派生。war 参数指定一个 URL(包括 file: 方案),用于目录或 Web 应用程序归档 (WAR) 文件。引用 WAR 文件的 URL 支持的语法在 java.net.JarURLConnection 类的 Javadocs 页面上有所描述。仅使用引用整个 WAR 文件的 URL。

在此示例中,位于 Tomcat 服务器上 /path/to/foo 目录中的 Web 应用程序被部署为名为 /footoo 的 Web 应用程序上下文。

http://localhost:8080/manager/text/deploy?path=/footoo&war=file:/path/to/foo

在此示例中,Tomcat 服务器上 /path/to/bar.war 的“.war”文件作为名为 /bar 的 Web 应用程序上下文进行部署。请注意,没有 path 参数,因此上下文路径默认为 Web 应用程序归档文件的名称,不带“.war”扩展名。

http://localhost:8080/manager/text/deploy?war=file:/path/to/bar.war

从主机 appBase 部署目录或 WAR

部署位于您主机 appBase 目录中的 Web 应用程序目录或“.war”文件。路径和可选版本从目录或 war 文件名派生。

在此示例中,位于 Tomcat 服务器主机 appBase 目录中名为 foo 的子目录中的 Web 应用程序被部署为名为 /foo 的 Web 应用程序上下文。请注意,使用的上下文路径是 Web 应用程序目录的名称。

http://localhost:8080/manager/text/deploy?war=foo

在此示例中,位于 Tomcat 服务器主机 appBase 目录中的“.war”文件 bar.war 作为名为 /bar 的 Web 应用程序上下文进行部署。

http://localhost:8080/manager/text/deploy?war=bar.war

使用 Context 配置 ".xml" 文件进行部署

如果主机 deployXML 标志设置为 true,则可以使用 Context 配置 ".xml" 文件和可选的 ".war" 文件或 Web 应用程序目录来部署 Web 应用程序。使用 Context ".xml" 配置文件部署 Web 应用程序时,不使用上下文 path

Context 配置 ".xml" 文件可以包含 Web 应用程序 Context 的有效 XML,就像它在您的 Tomcat server.xml 配置文件中配置一样。示例如下:

<Context path="/foobar" docBase="/path/to/application/foobar">
</Context>

当可选的 war 参数设置为 Web 应用程序“.war”文件或目录的 URL 时,它会覆盖 context 配置“.xml”文件中配置的任何 docBase。

以下是使用 Context 配置“.xml”文件部署应用程序的示例。

http://localhost:8080/manager/text/deploy?config=file:/path/context.xml

以下是使用 Context 配置“.xml”文件和位于服务器上的 Web 应用程序“.war”文件部署应用程序的示例。

http://localhost:8080/manager/text/deploy
 ?config=file:/path/context.xml&war=file:/path/bar.war

部署注意事项

如果 Host 配置了 unpackWARs=true,并且您部署了一个 war 文件,那么该 war 文件将被解压到您 Host appBase 目录中的一个目录中。

如果应用程序 war 或目录安装在您的 Host appBase 目录中,并且 Host 配置了 autoDeploy=true,则 Context 路径必须与目录名或不带“.war”扩展名的 war 文件名匹配。

为安全起见,当不受信任的用户可以管理 Web 应用程序时,可以将 Host deployXML 标志设置为 false。这可以防止不受信任的用户使用配置 XML 文件部署 Web 应用程序,并防止他们部署位于其 Host appBase 之外的应用程序目录或“.war”文件。

部署响应

如果安装和启动成功,您将收到如下响应:

OK - Deployed application at context path /foo

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 应用程序已存在于路径 /foo

    所有当前运行的 Web 应用程序的上下文路径必须是唯一的。因此,您必须使用此上下文路径卸载现有 Web 应用程序,或为新的 Web 应用程序选择不同的上下文路径。可以在 URL 上指定 update 参数,其值为 true 以避免此错误。在这种情况下,将在执行部署之前对现有应用程序执行卸载。

  • 文档基目录不存在或不可读

    war 参数指定的 URL 必须标识此服务器上包含 Web 应用程序“未打包”版本的目录,或包含此应用程序的 Web 应用程序归档 (WAR) 文件的绝对 URL。更正 war 参数指定的值。

  • 遇到异常

    尝试启动新的 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息,但可能的原因包括解析 /WEB-INF/web.xml 文件时出现问题,或在初始化应用程序事件监听器和过滤器时缺少类。

  • 指定的应用程序 URL 无效

    您指定的目录或 Web 应用程序的 URL 无效。此类 URL 必须以 file: 开头,WAR 文件的 URL 必须以“.war”结尾。

  • 指定的上下文路径无效

    上下文路径必须以斜杠字符开头。要引用 ROOT Web 应用程序,请使用 "/"。

  • 上下文路径必须与目录或 WAR 文件名匹配

    如果应用程序 war 或目录安装在您的 Host appBase 目录中,并且 Host 配置了 autoDeploy=true,则 Context 路径必须与目录名或不带“.war”扩展名的 war 文件名匹配。

  • 只能安装主机 Web 应用程序目录中的 Web 应用程序

    如果 Host deployXML 标志设置为 false,并且尝试在 Host appBase 目录之外部署 Web 应用程序目录或“.war”文件,则会发生此错误。

列出当前已部署的应用程序

http://localhost:8080/manager/text/list

列出所有当前已部署的 Web 应用程序的上下文路径、当前状态(runningstopped)以及活动会话数。刚启动 Tomcat 后,典型的响应可能如下所示:

OK - Listed applications for virtual host localhost
/webdav:running:0:webdav
/examples:running:0:examples
/manager:running:0:manager
/:running:0:ROOT
/test:running:0:test##2
/test:running:0:test##1

重新加载现有应用程序

http://localhost:8080/manager/text/reload?path=/examples

发出信号通知现有应用程序自行关闭并重新加载。当 Web 应用程序上下文不可重新加载且您已更新 /WEB-INF/classes 目录中的类或属性文件,或者当您在 /WEB-INF/lib 目录中添加或更新了 jar 文件时,这可能很有用。

如果此命令成功,您将看到如下响应:

OK - Reloaded application at context path /examples

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试重新启动 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息。

  • 指定的上下文路径无效

    上下文路径必须以斜杠字符开头。要引用 ROOT Web 应用程序,请使用 "/"。

  • 路径 /foo 不存在上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径

    path 参数是必需的。

  • WAR 部署在路径 /foo 上不支持重新加载

    目前,当 Web 应用程序直接从 WAR 文件部署时,不支持应用程序重新加载(以获取类或 web.xml 文件的更改)。它仅在 Web 应用程序从解压目录部署时才有效。如果您使用的是 WAR 文件,则应 undeploy 然后 deploy 或使用 update 参数再次 deploy 应用程序以获取更改。

列出操作系统和 JVM 属性

http://localhost:8080/manager/text/serverinfo

列出关于 Tomcat 版本、操作系统和 JVM 属性的信息。

如果发生错误,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试枚举系统属性时遇到异常。请检查 Tomcat 日志以获取详细信息。

列出可用的全局 JNDI 资源

http://localhost:8080/manager/text/resources[?type=xxxxx]

列出可用于上下文配置文件中资源链接的全局 JNDI 资源。如果指定 type 请求参数,则该值必须是您感兴趣的资源类型的完全限定 Java 类名(例如,您可以指定 javax.sql.DataSource 以获取所有可用 JDBC 数据源的名称)。如果您不指定 type 请求参数,则将返回所有类型的资源。

根据是否指定了 type 请求参数,正常响应的第一行将是:

OK - Listed global resources of all types

OK - Listed global resources of type xxxxx

其后是每个资源一行。每行由冒号字符 (":") 分隔的字段组成,如下所示:

  • 全局资源名称 - 此全局 JNDI 资源的名称,将用于 <ResourceLink> 元素的 global 属性中。
  • 全局资源类型 - 此全局 JNDI 资源的完全限定 Java 类名。

如果发生错误,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试枚举全局 JNDI 资源时遇到异常。请检查 Tomcat 日志以获取详细信息。

  • 没有可用的全局 JNDI 资源

    您正在运行的 Tomcat 服务器已配置为不包含全局 JNDI 资源。

会话统计

http://localhost:8080/manager/text/sessions?path=/examples

显示 Web 应用程序的默认会话超时时间,以及当前活跃会话中实际超时时间在“一分钟”范围内的数量。例如,在重启 Tomcat 并执行 /examples Web 应用程序中的一个 JSP 示例后,您可能会得到如下结果:

OK - Session information for application at context path /examples
Default maximum session inactive interval 30 minutes
<1 minutes: 1 sessions
1 - <2 minutes: 1 sessions

过期会话

http://localhost:8080/manager/text/expire?path=/examples&idle=num

显示会话统计信息(如上述 /sessions 命令),并使空闲时间超过 num 分钟的会话过期。要使所有会话过期,请使用 &idle=0

OK - Session information for application at context path /examples
Default maximum session inactive interval 30 minutes
1 - <2 minutes: 1 sessions
3 - <4 minutes: 1 sessions
>0 minutes: 2 sessions were expired

实际上 /sessions/expire 是同一个命令的同义词。区别在于是否存在 idle 参数。

启动现有应用程序

http://localhost:8080/manager/text/start?path=/examples

发出信号使已停止的应用程序重新启动,并使其再次可用。停止和启动非常有用,例如,当您的应用程序所需的数据库暂时不可用时。通常最好停止依赖此数据库的 Web 应用程序,而不是让用户不断遇到数据库异常。

如果此命令成功,您将看到如下响应:

OK - Started application at context path /examples

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试启动 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息。

  • 指定的上下文路径无效

    上下文路径必须以斜杠字符开头。要引用 ROOT Web 应用程序,请使用 "/"。

  • 路径 /foo 不存在上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径

    path 参数是必需的。

停止现有应用程序

http://localhost:8080/manager/text/stop?path=/examples

发出信号通知现有应用程序使其不可用,但保持其部署状态。当应用程序停止时,任何传入的请求都将看到 HTTP 404 错误,并且此应用程序将在应用程序列表命令中显示为“stopped”。

如果此命令成功,您将看到如下响应:

OK - Stopped application at context path /examples

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试停止 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息。

  • 指定的上下文路径无效

    上下文路径必须以斜杠字符开头。要引用 ROOT Web 应用程序,请使用 "/"。

  • 路径 /foo 不存在上下文

    您指定的上下文路径上没有已部署的应用程序。

  • 未指定上下文路径 path 参数是必需的。

卸载现有应用程序

http://localhost:8080/manager/text/undeploy?path=/examples

警告 - 此命令将删除此虚拟主机 appBase 目录(通常为 "webapps")中存在的任何 Web 应用程序工件。这将删除应用程序 .WAR 文件(如果存在)、解压形式或 .WAR 扩展产生的应用程序目录,以及 $CATALINA_BASE/conf/[enginename]/[hostname]/ 目录中的 XML Context 定义。如果您只想将应用程序暂时停用,则应使用 /stop 命令。

发出信号通知现有应用程序优雅地关闭自身,并将其从 Tomcat 中移除(这也使得此上下文路径稍后可重用)。此外,如果文档根目录存在于此虚拟主机的 appBase 目录(通常为“webapps”)中,则该目录将被移除。此命令与 /deploy 命令在逻辑上是相反的。

如果此命令成功,您将看到如下响应:

OK - Undeployed application at context path /examples

否则,响应将以 FAIL 开头并包含错误消息。可能的问题原因包括:

  • 遇到异常

    尝试卸载 Web 应用程序时遇到异常。请检查 Tomcat 日志以获取详细信息。

  • 指定的上下文路径无效

    上下文路径必须以斜杠字符开头。要引用 ROOT Web 应用程序,请使用 "/"。

  • 不存在名为 /foo 的上下文

    没有您指定的名称的已部署应用程序。

  • 未指定上下文路径 path 参数是必需的。

查找内存泄漏

http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]

查找泄漏诊断会触发完整的垃圾回收。在生产系统上应极其谨慎使用。

查找泄漏诊断尝试识别在停止、重新加载或卸载时导致内存泄漏的 Web 应用程序。结果应始终使用分析器进行确认。该诊断使用 StandardHost 实现提供的额外功能。如果使用的是不扩展 StandardHost 的自定义主机,则它将不起作用。

从 Java 代码中显式触发完整的垃圾回收被认为是不可靠的。此外,根据所使用的 JVM,存在禁用显式 GC 触发的选项,例如 -XX:+DisableExplicitGC。如果您想确保诊断程序成功运行了完整的 GC,您需要使用 GC 日志、JConsole 或类似工具进行检查。

如果此命令成功,您将看到如下响应:

/leaking-webapp

如果您希望响应中包含状态行,请在请求中包含查询参数 statusLine,并将其值设置为 true

每个已停止、重新加载或卸载,但其先前运行的类仍加载在内存中,从而导致内存泄漏的 Web 应用程序的上下文路径都将列在新行上。如果一个应用程序已重新加载多次,它可能会被列出多次。

如果命令不成功,响应将以 FAIL 开头并包含错误消息。

连接器 SSL/TLS 密码信息

http://localhost:8080/manager/text/sslConnectorCiphers

SSL 连接器/密码诊断列出了当前为每个连接器配置的 SSL/TLS 密码。

响应将如下所示:

OK - Connector / SSL Cipher information
Connector[HTTP/1.1-8080]
  SSL is not enabled for this connector
Connector[HTTP/1.1-8443]
  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
  TLS_DHE_RSA_WITH_AES_128_CBC_SHA
  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
  ...

连接器 SSL/TLS 证书链信息

http://localhost:8080/manager/text/sslConnectorCerts

SSL 连接器/证书诊断列出了当前为每个虚拟主机配置的证书链。

响应将如下所示:

OK - Connector / Certificate Chain information
Connector[HTTP/1.1-8080]
SSL is not enabled for this connector
Connector[HTTP/1.1-8443]-_default_-RSA
[
[
  Version: V3
  Subject: CN=localhost, OU=Apache Tomcat PMC, O=The Apache Software Foundation, L=Wakefield, ST=MA, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
  ...

连接器 SSL/TLS 受信任证书信息

http://localhost:8080/manager/text/sslConnectorTrustedCerts

SSL 连接器/受信任证书诊断列出了当前为每个虚拟主机配置的受信任证书。

响应将如下所示:

OK - Connector / Trusted Certificate information
Connector[HTTP/1.1-8080]
SSL is not enabled for this connector
Connector[HTTP/1.1-8443]-_default_
[
[
  Version: V3
  Subject: CN=Apache Tomcat Test CA, OU=Apache Tomcat PMC, O=The Apache Software Foundation, L=Wakefield, ST=MA, C=US
  ...

重新加载 TLS 配置

http://localhost:8080/manager/text/sslReload?tlsHostName=name

重新加载 TLS 配置文件(证书和密钥文件,这不会触发 server.xml 的重新解析)。要重新加载所有主机的 TLS 文件,请不要指定 tlsHostName 参数。

OK - Reloaded TLS configuration for [_default_]

线程 Dump

http://localhost:8080/manager/text/threaddump

写入 JVM 线程 dump。

响应将如下所示:

OK - JVM thread dump
2014-12-08 07:24:40.080
Full thread dump Java HotSpot(TM) Client VM (25.25-b02 mixed mode):

"http-nio-8080-exec-2" Id=26 cpu=46800300 ns usr=46800300 ns blocked 0 for -1 ms waited 0 for -1 ms
   java.lang.Thread.State: RUNNABLE
        locks java.util.concurrent.ThreadPoolExecutor$Worker@1738ad4
        at sun.management.ThreadImpl.dumpThreads0(Native Method)
        at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:440)
        at org.apache.tomcat.util.Diagnostics.getThreadDump(Diagnostics.java:409)
        at org.apache.catalina.manager.ManagerServlet.threadDump(ManagerServlet.java:557)
        at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:371)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:618)
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:725)
...

VM 信息

http://localhost:8080/manager/text/vminfo

写入关于 Java 虚拟机的一些诊断信息。

响应将如下所示:

OK - VM info
2014-12-08 07:27:32.578
Runtime information:
  vmName: Java HotSpot(TM) Client VM
  vmVersion: 25.25-b02
  vmVendor: Oracle Corporation
  specName: Java Virtual Machine Specification
  specVersion: 1.8
  specVendor: Oracle Corporation
  managementSpecVersion: 1.2
  name: ...
  startTime: 1418012458849
  uptime: 393855
  isBootClassPathSupported: true

OS information:
...

保存配置

http://localhost:8080/manager/text/save

如果未指定任何参数,此命令会将服务器的当前配置保存到 server.xml。如果需要,现有文件将被重命名为备份。

如果指定了与已部署 Web 应用程序路径匹配的 path 参数,则该 Web 应用程序的配置将保存到当前主机的 xmlBase 中适当命名的 context.xml 文件中。

要使用此命令,必须存在 StoreConfig MBean。通常,这通过 StoreConfigLifecycleListener 进行配置。

如果命令不成功,响应将以 FAIL 开头并包含错误消息。

服务器状态

通过以下链接,您可以查看服务器的状态信息。manager-status 角色或任何其他 manager-xxx 角色都允许访问此页面。

http://localhost:8080/manager/status
http://localhost:8080/manager/status/all

以 HTML 格式显示服务器状态信息。

http://localhost:8080/manager/status?XML=true

以 XML 格式显示服务器状态信息。XML 格式不包含每个 Web 应用程序的详细统计信息。

http://localhost:8080/manager/status?JSON=true
http://localhost:8080/manager/status/all?JSON=true

以 JSON 格式显示服务器状态信息。JSON 格式不包含每个线程的状态信息。如果使用客户端可视化工具进行主动监控和服务器状态警报(例如 Grafana),Manager 提供的 JSON 输出可能会提供最简单和最安全的解决方案。

首先,您会看到服务器和 JVM 版本号、JVM 提供商、操作系统名称和编号,后跟体系结构类型。

其次,是关于 JVM 内存使用情况的信息。

然后,是关于 Tomcat AJP 和 HTTP 连接器的信息。它们都有相同的信息:

  • 线程信息:最大线程数、最小和最大空闲线程数、当前线程数和当前繁忙线程数。

  • 请求信息:最大处理时间和处理时间、请求和错误计数、接收和发送的字节数。

  • 如果不使用 JSON 格式,线程的状态会显示 Stage、Time、Bytes Sent、Bytes Receive、Client、VHost 和 Request。所有现有线程都列在表中。以下是可能的线程阶段列表:

    • “解析和准备请求”:正在解析请求头或正在进行读取请求体(如果已指定传输编码)所需的准备工作。

    • “服务”:线程正在处理请求并生成响应。此阶段在“解析和准备请求”阶段之后,在“完成”阶段之前。此阶段总是至少有一个线程(server-status 页面)。

    • “完成”:请求处理的结束。响应中仍在输出缓冲区中的任何剩余部分都发送到客户端。如果适合保持连接活动,则此阶段之后是“保持连接”,如果“保持连接”不适合,则之后是“准备就绪”。

    • “保持连接”:线程保持与客户端的连接打开,以防客户端发送另一个请求。如果收到另一个请求,下一个阶段将是“解析和准备请求”。如果在保持连接超时之前未收到请求,则连接将关闭,下一个阶段将是“就绪”。

    • “准备就绪”:线程处于空闲状态,随时可用。

如果您使用 /status/all 命令,除了 XML 格式外,还将提供每个已部署 Web 应用程序的附加信息。

使用 JMX 代理 Servlet

什么是 JMX 代理 Servlet

JMX 代理 Servlet 是一个轻量级代理,用于获取和设置 Tomcat 内部。(或任何通过 MBean 公开的类)它的用法不是很用户友好,但其 UI 对于集成命令行脚本以监控和更改 Tomcat 内部结构非常有用。您可以使用代理执行两件事:获取信息和设置信息。要真正理解 JMX 代理 Servlet,您应该对 JMX 有一个大致的了解。如果您不知道 JMX 是什么,那么请准备好感到困惑。

JMX 查询命令

形式如下:

http://webserver/manager/jmxproxy/?qry=STUFF

其中 STUFF 是您希望执行的 JMX 查询。例如,以下是一些您可能希望运行的查询:

  • qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessor 这将定位所有可以处理请求的工作器并报告其状态。
  • qry=*%3Aj2eeType=Servlet%2c* --> j2eeType=Servlet 这将返回所有已加载的 Servlet。
  • qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue --> Catalina:type=Environment,resourcetype=Global,name=simpleValue 这将按给定名称查找特定的 MBean。

您需要进行实验才能真正理解其功能。如果您不提供 qry 参数,则将显示所有 MBean。我们强烈建议您查看 Tomcat 源代码并理解 JMX 规范,以更好地了解您可以运行的所有查询。

JMX Get 命令

JMXProxyServlet 还支持一个“get”命令,您可以使用它来获取特定 MBean 属性的值。get 命令的一般形式是:

http://webserver/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY

您必须提供以下参数:

  1. get:完整的 bean 名称
  2. att:您希望获取的属性
  3. key:(可选)复合数据 MBean 属性的键

如果一切顺利,它将显示 OK,否则将显示错误消息。例如,假设我们希望获取当前的堆内存数据:

http://webserver/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage

或者,如果您只想要“used”键:

http://webserver/manager/jmxproxy/
 ?get=java.lang:type=Memory&att=HeapMemoryUsage&key=used

JMX Set 命令

现在您可以查询 MBean 了,是时候修改 Tomcat 的内部了!set 命令的一般形式是:

http://webserver/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE

因此,您需要提供 3 个请求参数:

  1. set:完整的 bean 名称
  2. att:您希望更改的属性
  3. val:新值

如果一切顺利,它将显示 OK,否则将显示错误消息。例如,假设我们希望动态打开 ErrorReportValve 的调试功能。以下操作将把调试级别设置为 10。

http://localhost:8080/manager/jmxproxy/
 ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
 &att=debug&val=10

我的结果是(可能有所不同):

Result: ok

如果我传入错误的值,我看到的是这样。这是我使用的 URL,我尝试将调试设置为“cow”:

http://localhost:8080/manager/jmxproxy/
 ?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
 &att=debug&val=cow

当我尝试这样做时,我的结果是:

Error: java.lang.NumberFormatException: For input string: "cow"

JMX Invoke 命令

invoke 命令允许在 MBean 上调用方法。该命令的一般形式是:

http://webserver/manager/jmxproxy/
 ?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS

例如,要调用 ServicefindConnectors() 方法,请使用:

http://localhost:8080/manager/jmxproxy/
 ?invoke=Catalina%3Atype%3DService&op=findConnectors&ps=

使用 Ant 执行 Manager 命令

除了通过 HTTP 请求执行 Manager 命令的能力(如上所述)外,Tomcat 还包含一组方便的 Ant(版本 1.4 或更高)构建工具任务定义。为了使用这些命令,您必须执行以下设置操作:

  • https://ant.apache.ac.cn 下载 Ant 的二进制发行版。您必须使用版本 1.4 或更高。
  • 将 Ant 发行版安装到一个方便的目录中(在以下说明中称为 ANT_HOME)。
  • $ANT_HOME/bin 目录添加到您的 PATH 环境变量中。
  • 在您的 Tomcat 用户数据库中配置至少一个包含 manager-script 角色的用户名/密码组合。

要在 Ant 中使用自定义任务,您必须首先使用 <import> 元素声明它们。因此,您的 build.xml 文件可能看起来像这样:

<project name="My Application" default="compile" basedir=".">

  <!-- Configure the directory into which the web application is built -->
  <property name="build"    value="${basedir}/build"/>

  <!-- Configure the context path for this application -->
  <property name="path"     value="/myapp"/>

  <!-- Configure properties to access the Manager application -->
  <property name="url"      value="http://localhost:8080/manager/text"/>
  <property name="username" value="myusername"/>
  <property name="password" value="mypassword"/>

  <!-- Configure the path to the Tomcat installation -->
  <property name="catalina.home" value="/usr/local/apache-tomcat"/>

  <!-- Configure the custom Ant tasks for the Manager application -->
  <import file="${catalina.home}/bin/catalina-tasks.xml"/>

  <!-- Executable Targets -->
  <target name="compile" description="Compile web application">
    <!-- ... construct web application in ${build} subdirectory, and
            generated a ${path}.war ... -->
  </target>

  <target name="deploy" description="Install web application"
          depends="compile">
    <deploy url="${url}" username="${username}" password="${password}"
            path="${path}" war="file:${build}${path}.war"/>
  </target>

  <target name="reload" description="Reload web application"
          depends="compile">
    <reload  url="${url}" username="${username}" password="${password}"
            path="${path}"/>
  </target>

  <target name="undeploy" description="Remove web application">
    <undeploy url="${url}" username="${username}" password="${password}"
            path="${path}"/>
  </target>

</project>

注意:通过上述导入定义 resources 任务将覆盖 Ant 1.7 中添加的 resources 数据类型。如果您希望使用 resources 数据类型,则需要使用 Ant 的命名空间支持来修改 catalina-tasks.xml,将 Tomcat 任务分配到其自己的命名空间。

现在,您可以执行 ant deploy 等命令将应用程序部署到正在运行的 Tomcat 实例,或执行 ant reload 告诉 Tomcat 重新加载它。另请注意,此 build.xml 文件中的大多数重要值都定义为可替换属性,因此您可以从命令行覆盖它们的值。例如,您可能认为将真实的管理器密码包含在 build.xml 文件的源代码中存在安全风险。为避免这种情况,请省略 password 属性,并从命令行指定它:

ant -Dpassword=secret deploy

任务输出捕获

使用 Ant 版本 1.6.2 或更高,Catalina 任务提供将输出捕获到属性或外部文件的选项。它们直接支持 <redirector> 类型属性的以下子集:

属性 描述 必填
output 写入输出的文件名。如果错误流未同时重定向到文件或属性,它将出现在此输出中。
error 命令标准错误应重定向到的文件。
logError 当您希望在 Ant 的日志中看到错误输出,并且正在将输出重定向到文件/属性时,使用此属性。错误输出将不包含在输出文件/属性中。如果您使用 errorerrorProperty 属性重定向错误,这将无效。
append 输出和错误文件是追加还是覆盖。默认为 false
createemptyfiles 即使文件为空,是否也应创建输出和错误文件。默认为 true
outputproperty 存储命令输出的属性名称。除非错误流被重定向到单独的文件或流,否则此属性将包含错误输出。
errorproperty 存储命令标准错误的属性名称。

还可以指定另外几个属性:

属性 描述 必填
alwaysLog 当您希望在 Ant 的日志中看到正在捕获的输出时,使用此属性。除非您正在捕获任务输出,否则不得使用此属性。默认为 false此属性将在 Ant 1.6.3 中直接受 <redirector> 支持
failonerror 当您希望避免任何管理器命令处理错误终止 Ant 执行时,使用此属性。默认为 true。如果要捕获错误输出,则必须将其设置为 false,否则执行将在捕获任何内容之前终止。
此属性仅对管理器命令执行有效,任何错误或缺失的命令属性仍将导致 Ant 执行终止。

它们还支持嵌入式 <redirector> 元素,您可以在其中指定其全部属性集,但 inputinputstringinputencoding 除外,这些属性即使被接受,也不会被使用,因为它们在此上下文中没有意义。有关 <redirector> 元素属性的详细信息,请参阅 Ant 手册

以下是显示如何使用此输出重定向支持的示例构建文件摘录:

    <target name="manager.deploy"
        depends="context.status"
        if="context.notInstalled">
        <deploy url="${mgr.url}"
            username="${mgr.username}"
            password="${mgr.password}"
            path="${mgr.context.path}"
            config="${mgr.context.descriptor}"/>
    </target>

    <target name="manager.deploy.war"
        depends="context.status"
        if="context.deployable">
        <deploy url="${mgr.url}"
            username="${mgr.username}"
            password="${mgr.password}"
            update="${mgr.update}"
            path="${mgr.context.path}"
            war="${mgr.war.file}"/>
    </target>

    <target name="context.status">
        <property name="running" value="${mgr.context.path}:running"/>
        <property name="stopped" value="${mgr.context.path}:stopped"/>

        <list url="${mgr.url}"
            outputproperty="ctx.status"
            username="${mgr.username}"
            password="${mgr.password}">
        </list>

        <condition property="context.running">
            <contains string="${ctx.status}" substring="${running}"/>
        </condition>
        <condition property="context.stopped">
            <contains string="${ctx.status}" substring="${stopped}"/>
        </condition>
        <condition property="context.notInstalled">
            <and>
                <isfalse value="${context.running}"/>
                <isfalse value="${context.stopped}"/>
            </and>
        </condition>
        <condition property="context.deployable">
            <or>
                <istrue value="${context.notInstalled}"/>
                <and>
                    <istrue value="${context.running}"/>
                    <istrue value="${mgr.update}"/>
                </and>
                <and>
                    <istrue value="${context.stopped}"/>
                    <istrue value="${mgr.update}"/>
                </and>
            </or>
        </condition>
        <condition property="context.undeployable">
            <or>
                <istrue value="${context.running}"/>
                <istrue value="${context.stopped}"/>
            </or>
        </condition>
    </target>

警告: 即使它没有多大意义,而且总是一个坏主意,多次调用 Catalina 任务,错误设置的 Ant 任务依赖链可能导致任务在同一个 Ant 运行中被多次调用,即使不是故意的。当您从该任务捕获输出时,应谨慎一些,因为这可能导致意外情况:

  • 当捕获到属性中时,您将只在其中找到第一次调用的输出,因为 Ant 属性是不可变的,一旦设置就不能更改,
  • 当捕获到文件中时,每次运行都会覆盖它,并且您只会在其中找到最后一次调用的输出,除非您使用 append="true" 属性,在这种情况下,您将看到每次任务调用的输出都附加到文件中。