如何检测Tomcat 10中所有WAR包已完全部署并正常运行?
验证Tomcat 10中所有应用完全部署运行的方法
问题1:是否存在返回“所有应用已启动运行”布尔值的REST服务?
Tomcat没有原生提供这类直接返回单一布尔值的REST API,但可以通过现有API的结果自行判断。
问题2:可查询应用列表及部署状态的API
Tomcat自带的Manager应用提供了几个实用端点,能获取已部署应用的状态:
/manager/text/list(文本格式):返回每行一个应用的信息,格式为应用路径:状态:会话数:应用名称,状态为running即表示已正常启动。
示例调用:curl -u 用户名:密码 http://localhost:8080/manager/text/list/manager/jmxproxy(JMX代理):可以查询指定应用的状态属性,比如查询根应用的状态:curl -u 用户名:密码 http://localhost:8080/manager/jmxproxy/?get=Catalina:type=Manager,context=/,host=localhost&att=stateName
返回结果中的stateName为STARTED表示应用正常运行。- 直接JMX连接:用jconsole等JMX客户端,或者代码连接Tomcat的JMX服务,查询
org.apache.catalina.core.StandardContext的stateName属性,值为STARTED即正常。
问题3:简易实现方法
方法1:脚本批量校验
写个简单的Shell或Python脚本,调用/manager/text/list接口,遍历结果检查所有应用状态:
- Shell脚本示例:
#!/bin/bash USER="tomcat" PASS="你的manager密码" TOMCAT_MANAGER_URL="http://localhost:8080/manager/text/list" # 获取应用状态列表(过滤掉开头的OK行) APP_STATES=$(curl -s -u $USER:$PASS $TOMCAT_MANAGER_URL | grep -v "^OK" | awk -F: '{print $2}') # 检查是否存在非running状态 if echo "$APP_STATES" | grep -qv "running"; then echo "有应用未正常运行" exit 1 else echo "所有应用已启动运行" exit 0 fi
方法2:轻量自定义Servlet
如果需要对外提供一个返回布尔值的接口,写个极简Servlet就行,不用照搬WebApplicationManager的复杂逻辑:
import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.Context; import org.apache.catalina.Host; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; @WebServlet("/check-all-apps") public class AppStatusChecker extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { resp.setContentType("application/json"); boolean allRunning = true; // 获取Tomcat服务器实例 Server server = Tomcat.getServer(); for (Service service : server.findServices()) { for (Host host : service.findHosts()) { for (Context ctx : host.findChildren()) { if (ctx instanceof StandardContext) { StandardContext stdCtx = (StandardContext) ctx; if (!"STARTED".equals(stdCtx.getStateName())) { allRunning = false; break; } } } if (!allRunning) break; } if (!allRunning) break; } try { resp.getWriter().write("{\"allAppsRunning\": " + allRunning + "}"); } catch (Exception e) { e.printStackTrace(); } } }
把这个Servlet打包成极简WAR包部署,访问/check-all-apps就能拿到JSON格式的布尔结果,比参考WebApplicationManager代码简单太多。
方法3:JMX批量查询(Java程序用)
如果是Java程序里需要做校验,直接通过JMX连接Tomcat批量查询所有应用状态:
import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.util.Set; public class TomcatAppChecker { public static void main(String[] args) throws Exception { // 连接Tomcat JMX服务(需提前在server.xml中启用JMX远程) JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); JMXConnector connector = JMXConnectorFactory.connect(jmxUrl); MBeanServerConnection conn = connector.getMBeanServerConnection(); // 查询所有Context实例 Set<ObjectName> ctxNames = conn.queryNames(new ObjectName("Catalina:type=Context,*"), null); boolean allRunning = true; for (ObjectName ctxName : ctxNames) { String state = (String) conn.getAttribute(ctxName, "stateName"); if (!"STARTED".equals(state)) { allRunning = false; System.out.println("应用 " + ctxName.getKeyProperty("context") + " 状态异常:" + state); } } System.out.println("所有应用是否正常运行:" + allRunning); connector.close(); } }
注意要在Tomcat的conf/server.xml里配置JMX远程连接的端口和权限,比如添加:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="1099" rmiServerPortPlatform="1098"/>
内容的提问来源于stack exchange,提问作者Bruno Genovese
相关产品推荐
相关产品推荐

