Tomcat 启动初始化和停止 (2)

如果 stop 命令执行失败,尝试使用系统信号终止,首先使用 kill -15 ,进程收到后进行处理;如果还是失败那么,等待 5s 后,使用 kill -9 强制终止。

小结

当我看到 Web应用加载的时候,耐心有点不足,感觉捋顺了整个过程,其实还有很多地方经不起推敲,为了看得更透彻,那么这个"简单"的启动过程,又有哪些值得思考的呢?

内部启动的线程和线程池中的线程为什么设置为守护线程(Daemon)?

Java 中有两类线程:守护线程与用户线程,区别是守护线程不会阻止 JVM 的退出。从 Tomcat 的停止流程来看,就算用非守护线程也不会出现什么问题,没有搜到官方对此的描述,这里按照理解强行解释一波 :)。

守护线程一般是服务提供者,运行系统代码,比如 GC 线程,就像操作系统中也区分用户线程和内核线程那样,Tomcat 将内部线程设为 daemon,也能很好的在语义上区分 Servlet 启动的线程,并且对于 Servlet 来说 Tomcat 就是它的操作系统。

生命周期的设计有什么好处?

保证组件启动和停止的一致性,为生命周期事件添加监听器,这些监听器处理其感兴趣的事件,来做一些额外的操作。这是观察者模式的应用。

多应用间如何实现隔离?

应用隔离的本质就是类隔离,主要防止类冲突。类是否相等是由其全限定名和类加载器共同决定的,容器就是通过自定义 ClassLoader 实现应用间隔离,Tomcat 类加载器结构:

classloader

当要求类加载器加载类时,它首先将请求委托给父加载器,然后在父加载器找不到所请求的类时,查找自己的存储库。而 Webapp 加载器略有不同,它首先会在自己的资源库中搜索,而不是向上委托,打破了标准的委托机制,其类加载时按以下顺序查找资源库:

Bootstrap 和 System 已加载的类

/WEB-INF/classes 和 /WEB-INF/lib/*.jar

Common 已加载的类

应用热加载和热部署?

当在启动 Engine 时,会新建一个名为 ContainerBackgroundProcessor[StandardEngine[Catalina]] 的线程,默认 10s 检查是否要重新加载或重新部署,对应方法在 Loader 接口定义分别是 backgroundProcess 和 modified。

默认 web.xml 配置了什么?

提供一个 DefaultServlet,用于处理静态资源和未找到匹配 Servlet 的请求;

用于编译和执行 JSP 的 JspServlet;

Session 默认超时 30 minutes;

默认 MIME Type 映射和 Welcome Files

其他能够想到的点

采用都是常用的数据结构,如 ArrayList、数组、HashMap等,Pipeline 采用链表实现,Digester 使用栈来解析。欢迎补充。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpspjj.html