Tomcat优雅关闭之路

  
  

本文首发于体内互联网技术微信公众号
链接:https://mp.weixin.qq.com/s/ZqkmoAR4JEYr0x0Suoq7QQ
马运杰

     

本文通过阅读Tomcat启动和关闭流程的源码,深入分析不同的Tomcat关闭方式背后的原理,让开发人员能够了解在使用不同的关闭方式时需要注意的点,避免因JVM进程异常退出导致的各种非预见性错误。

  

一、Tomcat的启动过程

  

要了解Tomcat关闭的原理,首先需要关注下Tomcat是如何启动的。这里我们简单介绍下。

  

Tomcat启动的入口是引导类中主要的方法,而后根据server.xml中的配置,对服务器、服务、Enigin,连接器,主机、上下文等组件进行初始化,之后便是启动这些组件。我们重点来看下启动之后,Tomcat做了哪些工作。

  

在Tomcat的各组件启动完毕之后,主要主线程会进入Catalina.out的等待()方法,而此方法又是主要调用了服务器组件的等待()方法,从名字便可以看的出,这个方法的目的是为了阻塞当前线程(主主线程)。

  

分析等待的源码(源码比较长,这里截取了部分,全部的可以自行拉取Tomcat源码进行阅读)。

  

 Tomcat优雅关闭之路

  

(StandardServer.await ())

  

我们发现等待()方法主要是根据server.xml中服务器节点港属性的设置做了以下几种工作:

  
      <李>   

    <>强港为2时,函数直接退出,此时主线程不会阻塞。

      李   <李>   

    <>强港为1时,将等待线程设置为当前线程,并且进入而循环,直到stopAwait标志位置为真正的

      李   <李> <>强港为其他时,强则会新建一个套接字服务端,该套接字绑定了当前服务器的ip以及港口端口,随后设置等待线程为当前线程,并且插座进入阻塞监听状态,直到套接字监听到server.xml中预置的关闭字符串(默认是“SHUTDOWN")   
  

在主线程退出等待后,就会进入Tomcat的关闭流程,进行各个组件的阻止和破坏操作。从上述分析可以看的出,要想停止Tomcat,就是要中断主要主线程的等待状态。

  

下图为Tomcat的整个生命周期。

  

 Tomcat优雅关闭之路

  

(Tomcat生命周期)

  

二,常见的关闭Tomcat的方式

  

1,我们下载的Tomcat压缩包的本目录下,有一个由官方提供的脚本(shutdown.sh),可以用来结束Tomcat进程。

  

2,服务器上,我们还可以利用杀- x命令来结束Tomcat进程。

  

3,此外,代码中的system . exit()以及伯父等异常情况的发生,也会导致Tomcat进程的关闭,但是这两者都不是正常的运维手段,在此我们不做分析。

  

三,关闭脚本

  

<强> 1,shutdown.sh的原理

  

查看分析官方的shutdown.sh脚本以及catalina.sh脚本,发现这两个脚本最终是在调用引导类主要的方法,和启动Tomcat时调用的是同一个方法,差异在于传入了“stop"作为主要的方法的参数,而传入了该参数的主方法,会调用卡特琳娜类的stopServer()方法。在此我们抹去不需要关注的代码,可以把整个stopServer()方法简化为如下4步:

  

 Tomcat优雅关闭之路

  

其主要做了两件事:

  
      <李>   

    初始化服务器组件,和Tomcat启动时类似,这一步主要是解析server.xml文件,然后根据server.xml中的属性初始化Tomcat组件的成员变量,这里主要关注服务器组件的几个成员变量:港口,地址,关闭,默认值分别为8005年,127.0.0.1,关机等,需要和启动时读取的server.xml保持一致。

      李   <李>往地址端口所监听的插座端口发生“关闭”字符串。   
  

至此,显而易见的,这对应了第一小节中的第三种阻塞情况,“SHUTDOWN"字符串让主要主线程结束了等待状态,并在接下来通过调用各组件的停止()和destroy()方法进行资源的释放。

  

<强> 2,关闭脚本的缺点

  

虽然关闭脚本是由Tomcat官方出品,但是其在实际应用中并不广泛,主要是由于下面两个缺点:

  
      <李>   

    从上述原理就可以分析出,关闭脚本是基于启动时监听了相应的端口,这就允许任意人员,只要能够发送“SHUTDOWN"字符串到相应的端口,就可以对Tomcat进程进行关闭,这对于生产环境是相当危险的,所以一般生产环境会将服务器的端口属性设置为1

    Tomcat优雅关闭之路