很多生產環(huán)境都非常需要以下特性:在無需關閉或重啟整個容器的情況下,部署新的 Web 應用或者取消對現有應用的部署?;蛘撸幢阍?Tomcat 服務器配置文件中沒有指定 reloadable
的情況下,也可以請求重新加載現有應用。
Tomcat 中的 Web 應用 Manager 就是來解決這些問題的,它默認安裝在上下文路徑:/manager
中,支持以下功能:
/WEB-INF/classes
或 /WEB-INF/lib
中內容的更改。<ResourceLink>
元素的部署工具中。<ResourceLink>
元素內嵌于 <Context>
部署描述中。Tomcat 默認安裝已經包含了 Manager。 將一個 Manager 應用實例的 Context
添加到一個新的主機中,manager.xml
上下文配置文件應放在 $CATALINA_BASE/conf/[enginename]/[hostname]
文件夾中。如下所示:
<Context privileged="true" antiResourceLocking="false"
docBase="${catalina.home}/webapps/manager">
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.0\.0\.1" />
</Context>
如果將 Tomcat 配置成能夠支持多個虛擬主機(網站),則需要對每個虛擬主機配置一個 Manager。
Manager 應用的使用方式有以下三種:
localhost
替換為你的網站主機名稱:http://localhost:8080/manager/html
。下文的描述將使用變量名
$CATALINA_BASE
來指代工作目錄。如果你還沒有為多個 Tomcat 實例設置 CATALINA_BASE 目錄,那么$CATALINA_BASE
就將被設置為$CATALINA_HOME
(Tomcat 的安裝目錄)的值。
Tomcat 以默認值運行是非常危險的,因為這能讓互聯網上的任何人都可以在你的服務器上執(zhí)行 Manager 應用。因此,Manager 應用要求任何用戶在使用前必須驗證自己的身份,提供自己的用戶名和密碼,以及相應配置的 manager-** 角色(角色名稱根據所需的功能而定)。另外,默認用戶文件($CATALINA_BASE/conf/tomcat-users.xml
)中的用戶名稱都沒有指定角色名稱,所以默認是不能訪問
Manager 應用的。
這些角色名稱位于 Manager 應用的 web.xml
文件中??捎玫慕巧ǎ?/p>
HTML 界面不會遭受 CSRF(Cross-Site Request Forgery,跨站請求偽造)攻擊,但純文本界面及 JMX 界面卻有可能無法幸免。這意味著,如果用戶能夠訪問純文本界面及 JMX 界面,那么在利用 Web 瀏覽器去訪問 Manager 應用時,必須要萬分謹慎。要想保持對 CSRF 免疫,則必須:
注意 JMX 代理界面是 Tomcat 中非常高效的底層、類似于根級別的管理界面。如果用戶知道了該調用的命令,就能實現大量行為,所以一定不要輕易授予用戶 manager-jmx 角色。
為了能夠訪問 Manager 應用,必須創(chuàng)建一個新的用戶名/密碼組合,并為之授予一種 manager-** 角色,或者把一種 manager-** 角色授予現有的用戶名/密碼組合。因為本文檔的大部分內容都在描述純文本界面的命令,所以為了將來討論實例方便起見,把角色名稱定為 manager-script。而涉及到具體如何配置用戶名及密碼,則是跟你所使用的Realm 實現有關:
UserDatabaseRealm 加上 MemoryUserDatabase 或 MemoryRealm——UserDatabaseRealm 和 MemoryUserDatabase 配置在默認的 $CATALINA_BASE/conf/server.xml
文件中。MemoryUserDatabase 和 MemoryRealm 都會讀取儲存在 CATALINA_BASE/conf/tomcat-users.xml
里的
XML 格式文件,它可以用任何文本編輯器進行編輯。該文件會為每個用戶定義一個 XML 格式的 <user>
,如下所示:
<user username="craigmcc" password="secret" roles="standard,manager-script" />
它定義了用戶登錄時所用的用戶名和密碼,以及他或她采用的角色名稱。你可以把 manager-script 角色添加到由逗號分隔的 roles
屬性中,從而將該角色賦予一個或多個用戶,也可以利用指定角色來創(chuàng)建新的用戶。
DataSourceRealm 或 JDBCRealm——用戶和角色信息都存儲在一個經由 JDBC 訪問的數據庫中。按照當前環(huán)境的標準流程,將 manager-script 角色賦予一個或多個用戶,或者利用該角色創(chuàng)建一個或多個新用戶。
在下一節(jié),當你第一次嘗試使用 Manager 的一個命令時,將會使用基本驗證進行登錄。用戶名和密碼的具體內容并不重要,只要它們能夠證明,用戶數據庫中擁有 manager-script 角色的用戶是有效用戶,我們的目的就達到了。
除了密碼限制訪問之外,Manager 還可以配置 RemoteAddrValve
和 RemoteHostValve
這兩個參數,分別通過 遠程 IP 地址 或遠程主機名來進行限制訪問。詳情可查看 Valve 文檔。下列范例是通過
IP 地址來限制訪問本地主機:
<Context privileged="true">
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.0\.0\.1"/>
</Context>
Manager 應用易用的 HTML 界面位于:
http://{host}:{port}/manager/html
正像前面講過的那樣,需要被授予 manager-gui 角色才能訪問它。關于這個界面,還有一個獨立的文檔,請訪問以下頁面:
HTML 界面可免受 CSRF(跨站請求偽造)攻擊。對 HTML 頁面的每次訪問都會生成一個隨機令牌,存儲在會話中,包含在頁面的所有鏈接中。如果你的下一個操作沒有正確的令牌值,操作就會被拒絕。如果令牌過期,可以從主頁或者 Manager 的 List Applications(列出的應用)頁面重新開始。
Manager 應用能夠處理的命令都是通過下面這樣的請求 URL 來指定的:
http://{host}:{port}/manager/text/{command}?{parameters}
{host}
和 {port}
分別代表運行 Tomcat 服務器所在的主機名和端口號。{command}
代表所要執(zhí)行的 Manager 命令。{parameters}
代表該命令所專有的查詢參數。在后面的實例中,可以為你的安裝自定義適當的主機和端口。
這些命令通常是被 HTTP GET
請求執(zhí)行的。/deploy
命令有一種能夠被 HTTP PUT
請求所執(zhí)行的形式。
多數 Manager 命令都能夠接受一個或多個查詢參數,這些查詢參數如下所示:
/
即可。注意:無法對 Manager 應用自身執(zhí)行管理命令。/deploy
命令有效,也是該命令所唯一能接受的格式。JarURLConnection
類的任何有效語法。每個命令都會以 text/plain
的形式(比如,沒有 HTML 標記的純 ASCII 碼文本 )返回響應,從而便于開發(fā)者與程序閱讀。響應的第一行以 OK
或 FAIL
開頭,表明請求的命令是否成功。如果失敗,響應第一行隨后部分就會帶有遇到問題的描述。一些包含其他信息行的命令會在下文予以介紹。
國際化說明 Manager 應用會在資源包中查找消息字符串,所以這些字符串可能已經轉化為你所用平臺的語言版本了。下文的范例展示的全都是消息的英文版本。
http://localhost:8080/manager/text/deploy?path=/foo
將作為請求數據指定在 HTTP PUT
請求中的 Web 應用歸檔文件(WAR)上傳,將它安裝到相應虛擬主機的 appBase
目錄中,啟動,使用目錄名或不帶 .war 后綴的 WAR 文件名作為路徑。稍后,可以通過 /undeploy
取消對應用的部署,相應的應用目錄也會被刪除。
該命令通過 HTTP PUT
請求來執(zhí)行。
通過在 /META-INF/context.xml
中包含上下文配置 XML 文件,.WAR 文件能夠包含 Tomcat 特有的部署配置信息。
URL 參數包括:
update
設置為 true 時,任何已有的更新將會首先取消部署。默認值為 false。tag
指定一個標簽名稱。這個參數能將已部署的 Web 應用與標簽連接起來。如果 Web 應用被取消部署,則以后在需要重新部署時,只需使用標簽就能實現。注意:該命令是 /undeploy
命令在邏輯上是對立的。
如果安裝或啟動成功,會接受到這樣一個響應:
OK - Deployed application at context path /foo
否則,響應會以 FAIL
開始,并包含一個錯誤消息。出現問題的可能原因為:
Application already exists at path /foo
當前運行的 Web 應用的上下文路徑必須是唯一的。否則,必須使用這一上下文路徑取消對現有 Web 應用的部署,或者為新應用選擇另外一個上下文路徑。update
參數可以指定為 URL 中的參數。true 值可避免這種錯誤。這種情況下,會在部署前,取消對現有應用的部署。
/WEB-INF/web.xml
文件時遇到了問題,或者在初始化應用的事件偵聽器與過濾器時出現遺失類的情況。部署并啟動一個新的 Web 應用,附加到指定的上下文 path
上(不能被其他 Web 應用同時使用)。該命令與 /undeploy
在邏輯上是對立的。
該命令由一個 HTTP GET
請求執(zhí)行。部署命令的應用方式有很多種。
http://localhost:8080/manager/text/deploy?path=/footoo&tag=footag
用來部署之前曾通過 tag
屬性部署過的 Web 應用。注意,Manager 應用的工作目錄包含之前部署過的 WAR 文件;如果清除它則將使部署失敗。
部署位于 Tomcat 服務器上的 Web 應用目錄或 .war 文件。如果沒有指定上下文路徑參數 path
,就會把目錄名或未帶 .war 后綴的 war 文件名當做路徑來使用。war
參數指定了目錄或 WAR 文件的 URL(也包含 file:
格式)。引用 WAR 文件的 URL 所采用的語法詳見 java.net.JarURLConnection
類的 Java 文檔頁面。只使用引用了整個 WAR
文件的 URL。
下面這個實例中,Web 應用位于 Tomcat 服務器上的 /path/to/foo
目錄中,被部署為上下文路徑為 /footoo
的 Web 應用。
http://localhost:8080/manager/text/deploy?path=/footoo&war=file:/path/to/foo
在下例中,Tomcat 服務器上的 .war 文件 /path/to/bar.war
被部署為上下文路徑為 /bar
的 Web 應用。注意,這里沒有 path
參數,因此上下文路徑默認為沒有 .war 后綴的 WAR 文件名。
http://localhost:8080/manager/text/deploy?war=jar:file:/path/to/bar.war!/
appBase
目錄中部署一個目錄或 WAR對位于主機 appBase
目錄中的 Web 應用目錄或 .war 文件進行部署。目錄名或沒有 .war 后綴名的 WAR 文件名被用作上下文路徑名。
在下面的范例中,Web 應用位于 Tomcat 服務器中主機 appBase
目錄下名為 foo
的子目錄中,被部署為上下文路徑名為 /foo
的 Web 應用。注意,用到的上下文路徑名就是 Web 應用的目錄名。
http://localhost:8080/manager/text/deploy?war=foo
在下面的范例中,位于主機 appBase
目錄中的 bar.war
文件被部署為上下文名為 /bar
的 Web 應用。
http://localhost:8080/manager/text/deploy?war=bar.war
如果主機的 deployXML
標志設定為 true,就可以使用上下文配置 .xml 文件以及一個可選的 .war 文件(或 Web 應用目錄)來進行 Web 應用部署。在使用上下文 .xml 文件配置文件進行部署時,不會用到上下文路徑參數 /path
。
上下文配置 .xml 文件包含用于 Web 應用上下文的有效 XML,就好像是在 Tomcat 的 server.xml
配置文件中進行配置一樣。范例如下:
<Context path="/foobar" docBase="/path/to/application/foobar">
</Context>
可選的 war
參數被設定為指向 Web 應用的 .war 文件或目錄的 URL,它會覆蓋掉上下文配置 .xml 文件中的任意 docBase
。
在下面這個實例中,使用上下文配置 .xml 文件部署 Web 應用:
http://localhost:8080/manager/text/deploy?config=file:/path/context.xml
在下面這個應用部署范例中,使用了上下文配置 .xml 文件和位于服務器中的 Web 應用的 .war 文件。
http://localhost:8080/manager/text/deploy
?config=file:/path/context.xml&war=jar:file:/path/bar.war!/
如果主機配置中將 unpackWARs
設為 true,而且你部署了一個 war 文件,那么這個 war 文件將解壓縮至主機的 appBase
目錄下的一個目錄中。
如果應用的 war 文件或目錄安裝在主機的 appBase
目錄中,那么或者主機應該被部署為 autoDeploy
為 true,或者上下文路徑必須匹配目錄名或不帶 .war 后綴的 war 文件名。
為了避免不可信用戶作出對 Web 應用的侵害,主機的 deployXML
標志可以設為 false。這能保證不可信用戶通過使用 XML 配置文件來部署 Web 應用,也能阻止他們部署位于其主機 appBase
之外的應用目錄或 .war 文件。
如果安裝及啟動都正常,會得到以下這樣的響應:
OK - Deployed application at context path /foo
否則,響應會以 FAIL
開頭并包含一些錯誤消息,引起問題的原因可能有以下幾種:
Application already exists at path /foo
當前運行的 Web 應用的上下文路徑必須是唯一的。否則,必須使用這一上下文路徑取消對現有 Web 應用的部署,或者為新應用選擇另外一個上下文路徑。update
參數可以指定為 URL 中的參數。true 值可避免這種錯誤。這種情況下,會在部署前,取消對現有應用的部署。
Document base does not exist or is not a readable directory
通過 war
指定的 URL 必須要確認服務器中的某個目錄含有解壓縮后的 Web 應用,包含該應用的 WAR 文件的絕對 URL 。更正 war
參數所提供的值。
Encountered exception
遇到試圖開啟新 Web 應用??刹榭?Tomcat 日志了解詳情。但有可能是在解析 /WEB-INF/web.xml
文件時遇到了問題,或者在初始化應用的事件偵聽器與過濾器時出現遺失類的情況。
Invalid application URL was specified
所指定的指向目錄或 Web 應用的 URL 無效。有效的 URL 必須以 file:
開始,用于 WAR 文件的 URL 必須以 .war 結尾。
Invalid context path was specified
上下文路徑必須以斜杠字符開始,引用 ROOT 應用必須使用 /
。
Context path must match the directory or WAR file name
如果應用的 .war 文件或目錄安裝在主機的 appBase
目錄,那么或者主機應該被部署為 autoDeploy
為 true,或者上下文路徑必須匹配目錄名或不帶 .war 后綴的 war 文件名。
deployXML
標志為設為 false,那么當要部署的 Web 應用目錄或 .war 文件位于主機 appBase
目錄之外時,就會產生這樣的錯誤。http://localhost:8080/manager/text/list
列出當前所有部署的 Web 應用的上下文路徑、當前狀態(tài)(running
或 stopped
),以及活躍會話。開啟 Tomcat 后,一般立刻會產生如下這樣的響應:
OK - Listed applications for virtual host localhost
/webdav:running:0
/examples:running:0
/manager:running:0
/:running:0
Listed applications for virtual host localhost:列出虛擬主機本地主機的所有應用。
http://localhost:8080/manager/text/reload?path=/examples
標記一個現有應用,關閉它并重新加載。這一功能的適用情況為:當 Web 應用上下文不能重新加載;你已經更新了 /WEB-INF/classes
目錄中的類和屬性文件時;或者當你在 /WEB-INF/lib
目錄添加或更新了 jar 文件。
注意:在重新加載時,Web 應用配置文件
/WEB-INF/web.xml
無法重新讀取。如果對 web.xml 文件作出改動,則必須停止并啟動 Web 應用。
如果命令成功執(zhí)行,應得如下所示的響應:
OK - Reloaded application at context path /examples
否則,返回的響應以 FAIL
開頭,并包含相關的錯誤消息。引起問題的可能原因有以下幾種:
Encountered exception
遇到試圖重啟 Web 應用的異常??刹榭?Tomcat 日志了解詳情。
Invalid context path was specified
上下文路徑必須以斜杠開始,引用 ROOT Web 應用必須使用 /
。
No context exists for path /foo
在所指定的上下文路徑中沒有發(fā)現部署好的應用。
No context path was specified
需要 path
參數。
http://localhost:8080/manager/text/serverinfo
列出 Tomcat 版本、操作系統(tǒng)以及 JVM 屬性等相關信息。
如果出現錯誤,響應會以 FAIL
開始并包含一系列錯誤消息,導致錯誤的可能原因包括有:
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
后面將每個資源都單列一行,每一行內的字段都由冒號(:
)分隔,如下所示:
<ResourceLink>
元素的 global
屬性中。如果出現錯誤,響應將會以 FAIL
開始,并包含一個錯誤消息。出錯的原因可能包括以下幾方面:
Encountered exception
碰到異常試圖列舉 JNDI 資源,可查看 Tomcat 日志了解詳情。
http://localhost:8080/manager/text/sessions?path=/examples
顯示 Web 應用默認的會話超時,當前活躍會話在一分鐘范圍內實際的超時次數。比如,重啟 Tomcat 并隨后執(zhí)行 /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
顯示會話統(tǒng)計信息(比如上面的 /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 應用運行。
如果該命令成功執(zhí)行,將得到類似如下的響應:
OK - Started application at context path /examples
否則,將返回出錯響應,該響應以 FAIL
開頭,并包含一些錯誤。出錯原因可能是由于:
Encountered exception
碰到異常情況,試圖開啟 Web 應用??蓹z查 Tomcat 日志了解詳情。
Invalid context path was specified
上下文路徑必須以斜杠字符開始,引用 ROOT Web 應用必須使用反斜杠(/
)。
No context exists for path /foo
在指定的上下文路徑處沒有部署的應用。
path
參數。http://localhost:8080/manager/text/stop?path=/examples
標記現有應用,使其不可用,但仍使其處于已部署狀態(tài)。當應用停止時,任何請求都將得到著名的 HTTP 404錯誤。在應用列表中,該應用將顯示為“stopped”。
如果該命令成功執(zhí)行,將得到類似如下的響應:
OK - Stopped application at context path /examples
否則,將返回出錯響應,它以 FAIL
開頭,并包含一個出錯消息,可能導致出誤的原因包括:
Encountered exception
碰到異常情況,試圖開啟 Web 應用。可檢查 Tomcat 日志了解詳情。
Invalid context path was specified
上下文路徑必須以斜杠字符開始,引用 ROOT Web 應用必須使用反斜杠(/
)。
No context exists for path /foo 在指定的上下文路徑處沒有部署的應用。
path
參數。http://localhost:8080/manager/text/undeploy?path=/examples
警告:該命令將刪除虛擬主機 appBase
目錄(通常是 webapps )中的所有 Web 應用。該命令將從未解壓縮(或已解壓縮)的 .WAR 式部署中,以及 $CATALINA_BASE/conf/[enginename]/[hostname]/
中以 XML 格式保存的上下文描述符中,刪除應用的 .WAR 文件及目錄。如果你只是想讓某個應用暫停服務,則應該使用 /stop
命令。
標記一個已有的應用,將其恰當地關閉,從 Tomcat 中移除(從而使得以后可以重新使用該上下文路徑)。另外,如果文檔根目錄位于虛擬主機的 appBase
目錄(通常是 webapps)中,則它也將被移除。該命令是 /deploy
的逆向命令。
如果該命令成功執(zhí)行,將得到類似如下的響應:
OK - Undeployed application at context path /examples
否則,將返回出錯響應,它以 FAIL
開頭,并包含一個出錯消息,可能導致出誤的原因包括:
Encountered exception
碰到異常情況,試圖取消對某個 Web 應用的部署??蓹z查 Tomcat 日志了解詳情。
Invalid context path was specified
上下文路徑必須以斜杠字符開始,引用 ROOT Web 應用必須使用反斜杠(/
)。
No context exists for path /foo 在指定的上下文路徑處沒有部署的應用。
path
參數。http://localhost:8080/manager/text/findleaks[?statusLine=[true|false]]
尋找內存泄露的診斷將觸發(fā)一個徹底的垃圾回收(GC)方案,所以如果在生產環(huán)境中使用它,需要非常謹慎才行。
尋找內存泄露的診斷會試圖確認已導致內存泄露的 Web 應用(當其處于停止、重新加載,以及被取消部署狀態(tài)時)。通常由一種分析器來確認結論。診斷使用了由 StandardHost(標準主機)實現所提供的附加功能。如果使用的是沒有擴展自 StandHost 的自定義主機,則該診斷無法生效。
已有一些文檔介紹,從 Java 代碼中顯式地觸發(fā)徹底的垃圾回收方案是不可靠的。此外,在不同的 JVM 中,也有很多選項禁止顯式觸發(fā)垃圾回收,比如像 -XX:+DisableExplicitGC
。 如果你需要確認診斷是否成功地實現了徹底的垃圾回收,可以使用 GC 日志、JConsole 分析器,或其他類似工具。
如果該命令成功執(zhí)行,將得到類似如下的響應:
/leaking-webapp
如果你希望在響應中看到狀態(tài)行,那么可以在請求中加入 statusLine
查詢參數,并將其設定為 true
。
對于已停止運行、被重新加載或被取消部署的Web 應用,由于之前運行所用到的類可能仍然加載在內存中,從而會造成內存泄露。響應將把這種應用的每個上下文路徑都單列一行。如果應用被重新加載了數次,就可能會列出幾次。
如果命令并沒有成功執(zhí)行,響應將以 FAIL
開頭,并包含一個錯誤消息。
http://localhost:8080/manager/text/sslConnectorCiphers
SSL 連接器/加密診斷會列出當前每一連接器所配置的 SSL/TLS 加密算法。對于 BIO 和 NIO,將列出每個加密算法套件的名稱;對于 APR,則返回 SSLCipherSuite 的值。
響應類似如下所示:
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
...
http://localhost: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 javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
...
http://localhost:8080/manager/text/vminfo
寫入一些關于 Java 虛擬機(JVM)的診斷信息。
響應類似如下所示:
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 中。已有的配置信息 .xml 文件將被重命名,作為必要時的備份文件。
如果指定了 path
參數,而且該參數與已部署應用的路徑相匹配,那么該 Web 應用的配置將保存為一個命名恰當的上下文 .xml 文件中,位于當前主機的 xmlBase
中。
要想使用該命令,則 StoreConfig MBean 必須存在。通常需要用 StoreConfigLifecycleListener來配置。
如果命令不能成功執(zhí)行,響應將以 FAIL
開頭,并包含一個錯誤消息。
可從下面這些鏈接中觀察有關服務器的狀態(tài)信息。任何一個 manager-** 角色都能訪問這一頁面。
http://localhost:8080/manager/status
http://localhost:8080/manager/status/all
上面是用 HTML 格式顯示服務器狀態(tài)信息的命令。
http://localhost:8080/manager/status?XML=true
http://localhost:8080/manager/status/all?XML=true
上面是用 XML 格式顯示服務器狀態(tài)信息的命令。
首先,顯示的是服務器和 JVM 的版本號、JVM 提供者、操作系統(tǒng)的名稱及其版本號,然后還顯示了系統(tǒng)體系架構類型。
其次,顯示的是關于 JVM 的內存使用信息。
最后,顯示的是關于 Tomcat AJP 和 HTTP 連接器的信息。對兩者來說,這些信息都很有用:
一張完整顯示線程階段、時間、發(fā)送字節(jié)數、接受字節(jié)數、客戶端、虛擬主機及請求的表。它將列出所有現有線程。下面列出了所有可能的線程階段:
使用 /status/all
命令可查看每一個已配置 Web 應用的額外信息。
JMX 代理 Servlet 是一款輕量級的代理。它的用途對用戶來說并不是特別友好,但是其 UI 卻非常有助于整合命令行腳本,從便于監(jiān)控和改變 Tomcat 的內部運行。通過這個代理,我們可以獲取和設置信息。要想真正了解 JMX 代理 Servlet,首先應該大概了解 JMX。如果不知道 JMX 的基本原理,那有些內容就很難理解了。
JMX 的查詢命令格式如下所示:
http://webserver/manager/jmxproxy/?qry=STUFF
STUFF
是所要執(zhí)行的 JMX 查詢。比如,可以執(zhí)行以下這些查詢:
qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessor
定位所有能夠處理請求并匯報各自狀態(tài)的 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 規(guī)范,更好地掌握所有能夠執(zhí)行的查詢。
get
命令JMXProxyServlet 還支持一種 get
命令來獲取特定 MBean的屬性值。該命令的一般格式如下所示:
http://webserver/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY
必須提供如下參數:
get
:MBean 的完整名稱。att
:希望獲取的屬性。key
:(可選參數)CompositeData MBean 的屬性中的鍵。如果命令成功執(zhí)行,則一切正常,否則就會返回一個出錯消息。舉兩個例子,比如當希望獲取當前的堆內存數據時,可以采用如下命令:
http://webserver/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage
再或者,如果只希望獲取“用過的”鍵,可以采用如下命令:
http://webserver/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage&key=used
set
命令上面介紹了如何查詢一個 MBean。下面來看看 Tomcat 的內部運行吧!set
命令的一般格式為:
http://webserver/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE
需要提供三個請求參數:
set
:完整的 bean 名稱。att
:想要改變的屬性。val
:新的屬性值。如果命令成功執(zhí)行,則一切正常,否則就會返回一個出錯消息。比如,假如想為 ErrorReportValve
進行立即調試,可以將屬性 debug
設為 10:
http://localhost:8080/manager/jmxproxy/
?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost
&att=debug&val=10
所得結果如下(你的有可能不同):
Result: ok
下面來看看如果傳入一個不恰當數值時的情況,比如使用一個URL,并試圖將屬性 debug 設置為 '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"
invoke
命令使用 invoke
命令,我們就可以在 MBean 中調用方法。該命令的一般格式為:
http://webserver/manager/jmxproxy/
?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS
比如,使用如下方式來調用 Service 的 findConnectors()
方法:
http://localhost:8080/manager/jmxproxy/
?invoke=Catalina%3Atype%3DService&op=findConnectors&ps=
上面的文檔介紹了如何利用 HTTP 請求來執(zhí)行 Manager 的命令。除此之外,Tomcat 還專為 Ant(1.4 版或更新版本)構建工具準備了一套方便的任務定義。為了使用這些命令,必須執(zhí)行下面這些操作:
server/lib/catalina-ant.jar
從 Tomcat 安裝目錄中復制到 Ant 的庫目錄($ANT_HOME/lib
)。$ANT_HOME/bin
目錄添加到環(huán)境變量 PATH
中。manager-script
角色的用戶名/密碼組合數據。為了在 Ant 中使用自定義任務,必須首先用 <taskdef>
元素來聲明它們,因而 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 custom Ant tasks for the Manager application -->
<taskdef name="list" classname="org.apache.catalina.ant.ListTask"/>
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/>
<taskdef name="start" classname="org.apache.catalina.ant.StartTask"/>
<taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"/>
<taskdef name="stop" classname="org.apache.catalina.ant.StopTask"/>
<taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/>
<taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask"/>
<typedef name="sessions" classname="org.apache.catalina.ant.SessionsTask"/>
<taskdef name="findleaks" classname="org.apache.catalina.ant.FindLeaksTask"/>
<typedef name="vminfo" classname="org.apache.catalina.ant.VminfoTask"/>
<typedef name="threaddump" classname="org.apache.catalina.ant.ThreaddumpTask"/>
<typedef name="sslConnectorCiphers" classname="org.apache.catalina.ant.SslConnectorCiphersTask"/>
<!-- 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>
注意:上面的資源任務定義將覆蓋 Ant 1.7 中所添加的資源數據類型。如果你希望使用這些資源數據類型,需要使用 Ant 命名空間支持,將 Tomcat 的任務分配到它們自己的命名空間中。
現在,可以執(zhí)行類似 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
|
是否應該創(chuàng)建輸出和錯誤文件,哪怕是空的文件。默認為 true 。 |
否 |
outputproperty
|
用于保存命令輸出的屬性名。除非錯誤流被重定向至單獨的文件或流,否則這一屬性將包含錯誤輸出。 | 否 |
errorproperty
|
用于保存命令標準錯誤的屬性名。 | 否 |
還可以指定其他一些額外屬性:
屬性 | 屬性說明 | 是否必需 |
---|---|---|
alwaysLog
|
該屬性用于查看捕獲的輸出,這個輸出也出現在 Ant 日志中。除非捕獲任務輸出,否則千萬不要使用它。默認為 false 。Ant 1.6.3 通過 <redirector> 直接支持該屬性。
|
否 |
failonerror
|
用于避免因為 manager 命令處理中錯誤而導致 Ant 執(zhí)行終止情況的發(fā)生。默認為 true 。如果希望捕獲錯誤輸出,則必須設為false ,否則 Ant 執(zhí)行將有可能在未捕獲任何輸出前就被終止。該屬性只用于 manager 命令的執(zhí)行上,任何錯誤的或丟失的命令屬性仍然會導致 Ant 執(zhí)行終止。 |
否 |
它們還支持內嵌的 <redirector>
元素,你可以在這些元素中指定全套的屬性。但對于input
、inputstring
、inputencoding
,即使接收,也無法使用,因為在這種上下文中它們沒有任何意義。詳情可參考 Ant 手冊以了解 <redirector>
元素的各個屬性。
下面這個范例摘錄了一段構建文件,展示了這種對輸出重定向的支持是如何運作的。
<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 運行中多次運行任務。必須提前對你稍加警告,因為有可能當你從任務中捕獲輸出時,會出現一些意想不到的情況:
append = "true"
屬性——在這種情況下,你將看到附加在文件內容末尾的每一個任務調用的相關輸出。
更多建議: