Java Web应用程序在JVM中的执行过程
Java Web 应用开发完成,编译打包后得到一个 War 包,将这个 war 放入到 Tomcat 容器路径下,启动 Tomcat 就可以通过 HTTP 访问这个 Web 应用了。
Java Web 应用是被 Tomcat 加载运行的,所以也称 Tomcat 为 Web 容器。
通过执行 Tomcat 的 Shell 脚本启动 Tomcat ,在 Shell 脚本里,其实启动的是 Java 虚拟机,startup 脚本最后调的是 catalina 脚本,脚本中有这么一个 Shell 命令:
1 | org.apache.catalina.startup.Bootstrap "$@" start |
在 Tomcat 启动后,在操作系统可以看到一个 Java 进程。这个 JVM 虚拟机启动以后,加载 class 类文件执行,首先加载的是 org.apache.catalina.startup.Bootstrap
类,这个类里面有一个 main()
函数,这是整个 Tomcat 入口函数,JVM 虚拟机会启动一个主线程从这个入口函数开始执行。
主线程从 Bootstrap 的 main() 函数开始执行,初始化 Tomcat 的运行环境,这时需要创建一个线程,比如负责监听 80 端口的线程,处理客户端连接请求的线程,以及执行用户请求的线程,创建这些线程的代码是 Tomcat 代码的一部分。
初始化运行环境后,Tomcat 就会扫描 Web 程序路径,扫描到开发的 war 包后,会自动解压并加载类到 JVM 。
如果外部请求发送到 Tomcat ,也就是外部程序通过 80 端口与 Tomcat 进行 HTTP 通信的时候,Tomcat 会根据 war 包中的 web.xml 配置,决定这个请求 URL 应该由哪个 Servlet 处理,然后 Tomcat 会分配一个线程去处理这个请求。实际上,就是这个线程执行相应的 Servlet 代码。
Tomcat 启动时,启动的是 JVM 进程,这个进程首先执行 JVM 的代码,而 JVM 会加载 Tomcat 的 class 文件,并分配一个主线程,其次主线程会从 main() 函数开始执行。在主线程执行过程中,Tomcat 还会启动其他一些线程,包括处理 HTTP 请求的线程。
Java Web 应用也是一些 class 文件,被 Tomcat 代码加载到 JVM 里执行,所以,即使这里有多个应用被加载,也只是加载了一些 class 文件,应用被加载进来后,并没有增加 JVM 进程中的线程数,也就是 Web 应用本身与线程是没有关系的。
而 Tomcat 会根据 HTTP 请求 URL 执行应用中的代码,可以理解成每个请求分配一个线程,每个线程执行的都是开发的 Web 代码。如果 Web 代码中包含了创建线程的代码,Tomcat 的线程在执行代码时,就会创建出新的线程,这些线程也会被操作系统调度执行。
如果 Tomcat 的线程在执行代码时,代码抛出的未处理的异常,那当前线程就会结束执行,这时控制台看到的异常信息其实就是线程堆栈的信息,线程会把异常信息以及当前堆栈的方法都打印出来。
Java Web应用程序在JVM中的执行过程
http://blog.gxitsky.com/2022/12/18/JavaWeb-tomcat-in-jvm-process/