做为工程师,有些时候,总会遇到部署的 Web 应用没有响应,或者状态不对等各类问题。 对于部署在 Tomcat 之上的 Java Web 应用,一般我们都会像程咬金一样,先使出「三板斧」来分析问题。
- 请求一下
- 查下进程在不在
- jstack 打下线程栈分析
我们在查看进程是否存在时,并没有直接查看对应 Web 应用的方式, 一般都是查看 Tomcat 的对应 Java 进程是否在。 如果应用没有响应另外再观察线程栈。
那这里有一个问题,Tomcat 进程在的时候,我们怎么来看 Tomcat的状态呢?
毕竟做为一个Java 应用,只要一启动的时候就会创建进程。这个并不能做为 Tomcat 在工作的真实依据。 此时有什么办法来判断当前 Tomcat 的工作状态呢?
一般在做集群内容器的心跳状态检测时也会遇到同样的问题。
这种情况如果 Tomcat 部署了ROOT应用,可以通过访问其指定的页面来判断请求是否可达,来确认 Tomcat 的状态。
另外一种方式是通过连接 Tomcat 的 MBeanServer 来确认其状态。一般情况Tomcat 宕掉了 MBeanServer也会连接失败。
前面的文章我们介绍过 JMX 连接到 Tomcat 提供的 MBeanServer 上(你了解JMX在Tomcat的应用吗?),可以执行一系列的容器相关组件的操作,甚至像启动停止 Connector 这些看似「危险」的操作。
当然要通过 JMX URL 连接到 Tomcat MBeanServer 上,是需要在启动脚本中配置参数启用。 除此之外,也可以用类似 JConsole 连接到各个 JVM 进程的方式,是通过 attach 到 VirtualMachine 后获取连接的。这个方式我们后面再写文章单独说。
在在官方的FQA里,还提到了一种实现检测状态的方式。
熟悉 Tomcat 配置的朋友都知道, 在一台机器上部署多个 Tomcat 时,经常会有端口冲突的问题, 这是因为在 server.xml 里会配置多个端口供实例使用。 除了 Connector 监听的端口外,还有一个 Server 组件使用的端口,默认是8005。 多个实例之间,除 Connector 端口外,这个SHUTDOWN 端口也是冲突的。
这里要实现检测 Tomcat 状态就是通过连接这个「端口」来实现。
说到端口,大家***印象一定是 Socket ,这里正是连接到这个端口对应的ServerSocket上,如果可以正常连接,表示 Tomcat 处于运行状态。 连接不上Socket 自然是 Tomcat 不可用了。
该端口除了获取状态外,还可以干啥呢? 还可以停止 Tomcat 进程,毕竟该端口可是号称SHUTDOWN端口啊。
实现起来也比较简单,在 Tomcat 的 SHUTDOWN端口旁边,还有一个属性,做为一个token,用于识别来关闭 Tomcat 的命令。当 Server 接收到带有这个token 的命令时,退出实例。
完整的实现,需要根据指定的 Tomcat 安装目录,解析配置文件,获取 SHUTDOWN 端口,以及对应的token,连接对应的 ServerSocket,获取状态,执行命令。
【本文为51CTO专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】