管理应用程序操作指南
目录
简介
在许多生产环境中,能够在不关闭和重启整个容器的情况下部署新的 Web 应用程序或卸载现有的 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
替换为您的网站主机名:https://127.0.0.1:8080/manager/html
。 - 一个仅使用 HTTP 请求的最小版本,适合系统管理员设置的脚本使用。命令作为请求 URI 的一部分给出,响应以简单的文本形式给出,可以轻松解析和处理。有关更多信息,请参见 支持的管理器命令。
- 一套方便的用于 Ant(版本 1.4 或更高版本)构建工具的任务定义。有关更多信息,请参见 使用 Ant 执行管理器命令。
配置管理应用程序访问
以下描述使用变量名 $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 界面的用户在使用 Web 浏览器访问 Manager 应用程序时必须谨慎。为了保持 CSRF 保护
- 如果您使用 Web 浏览器通过具有 **manager-script** 或 **manager-jmx** 角色的用户访问 Manager 应用程序(例如,测试纯文本或 JMX 接口),则必须在之后关闭浏览器的所有窗口以终止会话。如果您不关闭浏览器并访问其他网站,您可能会成为 CSRF 攻击的受害者。
- 建议不要向具有 **manager-gui** 角色的用户授予 **manager-script** 或 **manager-jmx** 角色。
注意 JMX 代理接口实际上是 Tomcat 的低级根级管理接口。如果您知道要调用的命令,就可以做很多事情。启用 **manager-jmx** 角色时应谨慎。
要启用对 Manager Web 应用程序的访问,您必须创建一个新的用户名/密码组合并将其中一个 **manager-xxx** 角色与之关联,或者将 **manager-xxx** 角色添加到某个现有的用户名/密码组合中。由于本文档的大部分内容描述了使用文本接口,因此本示例将使用角色名称 **manager-script**。用户名/密码的配置方式取决于您使用的 Realm 实现
- UserDatabaseRealm 加上 MemoryUserDatabase,或 MemoryRealm — UserDatabaseRealm 和 MemoryUserDatabase 在默认的
$CATALINA_BASE/conf/server.xml
中配置。MemoryUserDatabase 和 MemoryRealm 默认情况下读取位于$CATALINA_BASE/conf/tomcat-users.xml
的 XML 格式文件,可以使用任何文本编辑器对其进行编辑。此文件包含每个用户的 XML<user>
,可能类似于以下内容它定义了该用户登录使用的用户名和密码,以及与其关联的角色名称。您可以将 **manager-script** 角色添加到一个或多个现有用户的逗号分隔的<user username="craigmcc" password="secret" roles="standard,manager-script" />
roles
属性中,也可以创建具有该角色的新用户。 - DataSourceRealm — 您的用户和角色信息存储在通过 JDBC 访问的数据库中。按照您环境的标准程序,将 **manager-script** 角色添加到一个或多个现有用户,或创建一个或多个具有该角色的新用户。
- JNDIRealm — 您的用户和角色信息存储在通过 LDAP 访问的目录服务器中。按照您环境的标准程序,将 **manager-script** 角色添加到一个或多个现有用户,或创建一个或多个具有该角色的新用户。
您第一次尝试发出下一节中描述的 Manager 命令时,将要求您使用 BASIC 身份验证登录。您输入的用户名和密码无关紧要,只要它们在用户数据库中标识一个拥有 **manager-script** 角色的有效用户即可。
除了密码限制外,还可以通过添加 RemoteAddrValve
或 RemoteHostValve
来限制对 Manager Web 应用程序的访问,方法是通过 **远程 IP 地址** 或主机进行限制。有关详细信息,请参阅 阀门文档。以下是如何通过 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 应用程序知道如何处理的所有命令都指定在一个请求 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 参数,则路径和版本将使用标准的 上下文命名 规则从 config 参数中推导出来,或者如果 config 参数不存在,则从 war 参数中推导出来。 - version - 此 Web 应用程序的版本,如 并行部署 功能所用。如果您使用并行部署,无论何时需要路径,您都必须除了路径之外还指定一个版本,并且路径和版本的组合必须是唯一的,而不仅仅是路径。
注意:如果未显式指定路径,则版本参数将被忽略。 - war - Web 应用程序存档 (WAR) 文件的 URL,或包含 Web 应用程序的目录的路径名,或上下文配置“.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 - Host 的应用程序基本目录中 Web 应用程序上下文的目录名称。
- webapp.war - 位于 Host 的应用程序基本目录中的 Web 应用程序 war 文件的名称。
每个命令都将以 text/plain
格式返回响应(即,没有 HTML 标记的纯 ASCII),便于人和程序读取)。响应的第一行将以 OK
或 FAIL
开头,指示请求的命令是否成功。如果失败,第一行的其余部分将包含遇到的问题的描述。某些命令包含以下所述的附加信息行。
国际化说明 - Manager 应用程序在资源包中查找其消息字符串,因此这些字符串可能已针对您的平台进行了翻译。以下示例显示了消息的英文版本。
远程部署新的应用程序存档 (WAR)
https://127.0.0.1:8080/manager/text/deploy?path=/foo
上传作为此 HTTP PUT 请求中的请求数据指定的 Web 应用程序存档 (WAR) 文件,将其安装到我们相应的虚拟主机的 appBase
目录中,并启动,从指定的路径派生添加到 appBase
的 WAR 文件的名称。稍后可以使用 /undeploy
命令取消部署应用程序(并删除相应的 WAR 文件)。
此命令由 HTTP PUT 请求执行。
通过在 /META-INF/context.xml
中包含 Context 配置 XML 文件,.WAR 文件可以包含特定于 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 应用程序,或为新的应用程序选择不同的上下文路径。
update
参数可以作为 URL 上的参数指定,值为true
以避免此错误。 在这种情况下,将在执行部署之前对现有应用程序执行取消部署。 - 遇到异常
在尝试启动新的 Web 应用程序时遇到异常。 检查 Tomcat 日志以获取详细信息,但可能的解释包括解析
/WEB-INF/web.xml
文件时出现问题,或者在初始化应用程序事件侦听器和过滤器时遇到缺少的类。
从本地路径部署新的应用程序
部署并启动一个新的 Web 应用程序,附加到指定的上下文path
(该路径不能被任何其他 Web 应用程序使用)。 此命令是/undeploy
命令的逻辑反面。
此命令由 HTTP GET 请求执行。 部署命令可以使用多种不同的方式。
部署先前部署的 Web 应用程序
https://127.0.0.1:8080/manager/text/deploy?path=/footoo&tag=footag
这可用于部署先前已部署的 Web 应用程序,该应用程序已使用tag
属性部署。 请注意,Manager Web 应用程序的工作目录将包含先前部署的 WAR 文件; 删除它会导致部署失败。
通过 URL 部署目录或 WAR
部署位于 Tomcat 服务器上的 Web 应用程序目录或“.war”文件。 如果未指定path
,则路径和版本将从目录名称或 war 文件名派生。 war
参数指定目录或 Web 应用程序存档 (WAR) 文件的 URL(包括file:
方案)。 引用 WAR 文件的 URL 的支持语法在java.net.JarURLConnection
类的 Javadoc 页面上进行了描述。 只使用引用整个 WAR 文件的 URL。
在此示例中,位于 Tomcat 服务器上的目录/path/to/foo
中的 Web 应用程序被部署为名为/footoo
的 Web 应用程序上下文。
https://127.0.0.1:8080/manager/text/deploy?path=/footoo&war=file:/path/to/foo
在本例中,Tomcat 服务器上的 ".war" 文件 /path/to/bar.war
被部署为名为 /bar
的 Web 应用程序上下文。请注意,没有 path
参数,因此上下文路径默认为 Web 应用程序存档文件名称,不包括 ".war" 扩展名。
https://127.0.0.1:8080/manager/text/deploy?war=file:/path/to/bar.war
从主机 appBase 部署目录或 WAR
部署位于 Host appBase 目录中的 Web 应用程序目录或 ".war" 文件。路径和可选版本从目录或 war 文件名派生。
在本例中,位于 Tomcat 服务器 Host appBase 目录中名为 foo
的子目录中的 Web 应用程序被部署为名为 /foo
的 Web 应用程序上下文。请注意,使用的上下文路径是 Web 应用程序目录的名称。
https://127.0.0.1:8080/manager/text/deploy?war=foo
在本例中,位于 Tomcat 服务器 Host appBase 目录中的 ".war" 文件 bar.war
被部署为名为 /bar
的 Web 应用程序上下文。
https://127.0.0.1:8080/manager/text/deploy?war=bar.war
使用上下文配置“.xml”文件部署
如果 Host 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" 文件部署应用程序的示例。
https://127.0.0.1:8080/manager/text/deploy?config=file:/path/context.xml
以下是如何使用 Context 配置 ".xml" 文件和位于服务器上的 Web 应用程序 ".war" 文件部署应用程序的示例。
https://127.0.0.1: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 应用程序,或为新的应用程序选择不同的上下文路径。
update
参数可以作为 URL 上的参数指定,值为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,则上下文路径必须与目录名称或war文件名匹配,不包括“.war”扩展名。
- 只能安装Host Web应用程序目录中的Web应用程序
如果Host deployXML标志设置为false,则如果尝试在Host appBase目录之外部署Web应用程序目录或“.war”文件,则会发生此错误。
列出当前部署的应用程序
https://127.0.0.1:8080/manager/text/list
列出所有当前部署的Web应用程序的上下文路径、当前状态(running
或stopped
)以及活动会话数。在启动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
重新加载现有应用程序
https://127.0.0.1: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
参数是必需的。 - 不支持在路径/foo处部署的WAR上重新加载
目前,当Web应用程序直接从WAR文件部署时,不支持应用程序重新加载(以获取对类或
web.xml
文件的更改)。它仅在从解压缩的目录部署Web应用程序时才有效。如果您使用的是WAR文件,则应undeploy
,然后deploy
或使用update
参数再次deploy
应用程序以获取您的更改。
列出操作系统和 JVM 属性
https://127.0.0.1:8080/manager/text/serverinfo
列出有关 Tomcat 版本、操作系统和 JVM 属性的信息。
如果发生错误,响应将以 FAIL
开头,并包含错误消息。出现问题的原因可能包括
- 遇到异常
尝试枚举系统属性时遇到异常。检查 Tomcat 日志以获取详细信息。
列出可用的全局 JNDI 资源
https://127.0.0.1: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 资源。
会话统计
https://127.0.0.1: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
过期会话
https://127.0.0.1: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
参数的存在。
启动现有应用程序
https://127.0.0.1:8080/manager/text/start?path=/examples
向已停止的应用程序发出重启信号,使其再次可用。停止和启动很有用,例如,如果您的应用程序所需的数据库暂时不可用。通常,最好停止依赖此数据库的 Web 应用程序,而不是让用户不断遇到数据库异常。
如果此命令成功,您将看到类似于此的响应
OK - Started application at context path /examples
否则,响应将以FAIL
开头,并包含错误消息。 问题可能的原因包括
- 遇到异常
尝试启动 Web 应用程序时遇到异常。检查 Tomcat 日志以获取详细信息。
- 指定了无效的上下文路径
上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。
- 路径/foo不存在上下文
您指定的上下文路径上没有部署的应用程序。
- 未指定上下文路径
path
参数是必需的。
停止现有应用程序
https://127.0.0.1:8080/manager/text/stop?path=/examples
向现有应用程序发出信号,使其不可用,但将其部署。在应用程序停止时传入的任何请求都将看到 HTTP 错误 404,并且此应用程序将在列出应用程序的命令中显示为“已停止”。
如果此命令成功,您将看到类似于此的响应
OK - Stopped application at context path /examples
否则,响应将以FAIL
开头,并包含错误消息。 问题可能的原因包括
- 遇到异常
尝试停止 Web 应用程序时遇到异常。检查 Tomcat 日志以获取详细信息。
- 指定了无效的上下文路径
上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。
- 路径/foo不存在上下文
您指定的上下文路径上没有部署的应用程序。
- 未指定上下文路径
path
参数是必需的。
卸载现有应用程序
https://127.0.0.1:8080/manager/text/undeploy?path=/examples
警告 - 此命令将删除此虚拟主机 appBase
目录(通常为“webapps”)中存在的任何 Web 应用程序工件。这将删除应用程序 .WAR(如果存在)、从解压缩形式部署或从 .WAR 扩展生成的应用程序目录,以及来自 $CATALINA_BASE/conf/[enginename]/[hostname]/
目录的 XML 上下文定义。如果您只想使应用程序停止服务,则应使用 /stop
命令。
向现有应用程序发出信号,使其优雅地关闭自身,并将其从 Tomcat 中删除(这也使该上下文路径可供以后重用)。此外,如果文档根目录存在于此虚拟主机的 appBase
目录(通常为“webapps”)中,则该目录将被删除。此命令是 /deploy
命令的逻辑反面。
如果此命令成功,您将看到类似于此的响应
OK - Undeployed application at context path /examples
否则,响应将以FAIL
开头,并包含错误消息。 问题可能的原因包括
- 遇到异常
在尝试取消部署 Web 应用程序时遇到异常。检查 Tomcat 日志以获取详细信息。
- 指定了无效的上下文路径
上下文路径必须以斜杠字符开头。要引用ROOT Web应用程序,请使用“/”。
- 不存在名为 /foo 的上下文。
没有部署与您指定的名称相同的应用程序。
- 未指定上下文路径
path
参数是必需的。
查找内存泄漏
https://127.0.0.1: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 密码信息
https://127.0.0.1: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 证书链信息
https://127.0.0.1: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 可信证书信息
https://127.0.0.1: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 配置
https://127.0.0.1:8080/manager/text/sslReload?tlsHostName=name
重新加载 TLS 配置文件(证书和密钥文件,这不会触发对 server.xml 的重新解析)。要重新加载所有主机的文件,请不要指定 tlsHostName
参数。
OK - Reloaded TLS configuration for [_default_]
线程转储
https://127.0.0.1:8080/manager/text/threaddump
写入 JVM 线程转储。
响应将类似于以下内容
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 信息
https://127.0.0.1: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:
...
保存配置
https://127.0.0.1:8080/manager/text/save
如果未指定任何参数,则此命令会将服务器的当前配置保存到 server.xml。如果需要,现有文件将被重命名为备份。
如果指定了与已部署 Web 应用程序的路径匹配的 path
参数,则该 Web 应用程序的配置将保存到当前 Host 的 xmlBase
中的适当命名的 context.xml 文件中。
要使用该命令,必须存在 StoreConfig MBean。通常,这使用 StoreConfigLifecycleListener 进行配置。
如果命令未成功,则响应将以 FAIL
开头,并包含错误消息。
服务器状态
从以下链接,您可以查看有关服务器的状态信息。任何一个 manager-xxx 角色都可以访问此页面。
https://127.0.0.1:8080/manager/status
https://127.0.0.1:8080/manager/status/all
以 HTML 格式显示服务器状态信息。
https://127.0.0.1:8080/manager/status?XML=true
https://127.0.0.1:8080/manager/status/all?XML=true
以 XML 格式显示服务器状态信息。
https://127.0.0.1:8080/manager/status?JSON=true
https://127.0.0.1:8080/manager/status/all?JSON=true
以 JSON 格式显示服务器状态信息。
首先,您拥有服务器和 JVM 版本号、JVM 提供商、操作系统名称和编号,然后是体系结构类型。
其次,是有关 JVM 内存使用情况的信息。
然后,是有关 Tomcat AJP 和 HTTP 连接器的信息。两者都提供相同的信息。
线程信息:最大线程数、最小和最大备用线程数、当前线程数和当前繁忙线程数。
请求信息:最大处理时间和处理时间、请求和错误计数、接收和发送的字节数。
一个表格,显示阶段、时间、发送的字节数、接收的字节数、客户端、虚拟主机和请求。表格中列出了所有现有线程。以下是可能的线程阶段列表。
"解析并准备请求" : 正在解析请求头,或正在进行读取请求主体(如果已指定传输编码)的必要准备工作。
"服务" : 线程正在处理请求并生成响应。此阶段紧随“解析并准备请求”阶段,并在“完成”阶段之前。此阶段始终至少有一个线程(服务器状态页面)。
"完成" : 请求处理的结束。输出缓冲区中剩余的任何响应都将发送到客户端。此阶段之后是“保持活动”,如果保持连接活动是合适的,或者“就绪”,如果“保持活动”不合适。
"保持活动" : 线程保持与客户端的连接打开,以防客户端发送另一个请求。如果收到另一个请求,下一个阶段将是“解析并准备请求”。如果在保持活动超时之前没有收到请求,连接将关闭,下一个阶段将是“就绪”。
"就绪" : 线程处于静止状态,准备使用。
如果您使用的是/status/all
命令,则将提供有关每个已部署 Web 应用程序的附加信息。
使用 JMX 代理 Servlet
什么是 JMX 代理 Servlet
JMX 查询命令
它采用以下形式
http://webserver/manager/jmxproxy/?qry=STUFF
其中STUFF
是您希望执行的 JMX 查询。例如,以下是一些您可能希望运行的查询
-
qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessor
,它将找到所有可以处理请求的 worker 并报告其状态。 -
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 获取命令
JMXProxyServlet 还支持一个“get”命令,您可以使用它来获取特定 MBean 属性的值。get
命令的一般形式是
http://webserver/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY
您必须提供以下参数
get
:完整的 Bean 名称att
:您要获取的属性key
:(可选)CompositeData 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 设置命令
现在您可以查询 MBean 了,是时候修改 Tomcat 的内部结构了!set 命令的一般形式是
http://webserver/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE
因此您需要提供 3 个请求参数
set
:完整的 Bean 名称att
:您要更改的属性val
:新值
如果一切顺利,它将显示 OK,否则将显示错误消息。例如,假设我们要动态地为 ErrorReportValve
启用调试。以下操作将调试设置为 10。
https://127.0.0.1:8080/manager/jmxproxy/
?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
&att=debug&val=10
我的结果是(结果可能会有所不同)
Result: ok
以下是我传入错误值时看到的内容。这是我使用的 URL,我尝试将调试设置为“cow”
https://127.0.0.1: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
命令允许在 MBean 上调用方法。该命令的一般形式是
http://webserver/manager/jmxproxy/
?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS
例如,要调用 **Service** 的 findConnectors()
方法,请使用
https://127.0.0.1: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="https://127.0.0.1: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
文件源代码中存在安全风险。为了避免这种情况,请省略密码属性,并从命令行指定它。
ant -Dpassword=secret deploy
任务输出捕获
使用Ant版本1.6.2或更高版本,Catalina 任务提供将输出捕获到属性或外部文件中的选项。它们直接支持以下<redirector>
类型属性子集
属性 | 描述 | 必需 |
---|---|---|
output | 要写入输出的文件的名称。如果错误流也没有重定向到文件或属性,它将出现在此输出中。 | 否 |
error | 应将命令的标准错误重定向到的文件。 | 否 |
logError | 当您希望在 Ant 的日志中看到错误输出并且将输出重定向到文件/属性时,使用此属性。错误输出将不会包含在输出文件/属性中。如果您使用error或errorProperty属性重定向错误,这将不起作用。 | 否 |
append | 输出和错误文件是否应追加到或覆盖。默认为false 。 |
否 |
createemptyfiles | 即使为空,输出和错误文件是否也应创建。默认为true 。 |
否 |
outputproperty | 应将命令的输出存储在其中的属性的名称。除非错误流重定向到单独的文件或流,否则此属性将包含错误输出。 | 否 |
errorproperty | 应将命令的标准错误存储在其中的属性的名称。 | 否 |
还可以指定一些其他属性
属性 | 描述 | 必需 |
---|---|---|
alwaysLog | 当您希望看到您正在捕获的输出,也出现在 Ant 的日志中时,使用此属性。除非您正在捕获任务输出,否则不得使用它。默认为false 。此属性将在 Ant 1.6.3 中由<redirector> 直接支持 |
否 |
failonerror | 当您希望避免任何管理器命令处理错误终止 ant 执行时,使用此属性。默认为true 。如果您想捕获错误输出,则必须将其设置为false ,否则执行将在任何内容被捕获之前终止。
此属性仅对管理器命令执行起作用,任何错误或缺少的命令属性仍然会导致 Ant 执行终止。 |
否 |
它们还支持嵌入的 <redirector>
元素,您可以在其中指定其完整的属性集,但 input
、inputstring
和 inputencoding
即使被接受,也不会被使用,因为它们在这个上下文中没有意义。有关 <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"
属性,在这种情况下,您将看到每次任务调用的输出附加到文件中。