Mr Dk.'s BlogMr Dk.'s Blog
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • ☕ Understanding the JVM
    • Part 2 - 自动内存管理

      • Chapter 2 - Java 内存区域与内存溢出异常
      • Chapter 3.1-3.2 - 概述 && 对象已死
      • Chapter 3.3-3.4 - 垃圾收集算法 && HotSpot 的算法实现细节
      • Chapter 3.5 - 经典垃圾收集器
      • Chapter 3.6 - 低延迟垃圾收集器
    • Part 3 - 虚拟机执行子系统

      • Chapter 6 - 类文件结构
      • Chapter 7 - 虚拟机类加载机制
      • Chapter 8.1-8.2 - 运行时栈帧结构
      • Chapter 8.3 - 函数调用
      • Chapter 8.5 - 基于栈的字节码解释执行引擎
      • Chapter 9.2 - Tomcat: 正统的类加载器架构
    • Part 4 - 程序编译与代码优化

      • Chapter 10 - 前端编译与优化
      • Chapter 11.2 - 即时编译器
      • Chapter 11.3-11.4 - 提前编译器 && 编译器优化技术
    • Part 5 - 高效并发

      • Chapter 12.3 - Java 内存模型
      • Chapter 12.4-12.5 - Java 线程与协程
      • Chapter 13 - 线程安全与锁优化

Chapter 9.2 - Tomcat: 正统的类加载器架构

Created by : Mr Dk.

2020 / 01 / 31 16:32 🧨🧧

Ningbo, Zhejiang, China


9.2 案例分析

9.2.1 Tomcat: 正统的类加载器架构

主流的 Java Web 服务器都实现了自己定义的类加载器,且一般不止一个。要解决的问题:

  • 部署在同一服务器上的两个 Web 应用使用的 Java 类库可以互相隔离,因为两个不同的应用程序可能会依赖同一个第三方类库的不同版本
  • 部署在同一服务器上的两个 Web 应用使用的 Java 类库可以互相共享,否则 JVM 的方法区容易出现过度膨胀的风险
  • 服务器需要保证自身安全不受部署的 Web 应用程序影响,服务器使用的类库应该与应用程序类库互相独立
  • HotSwap

Tomcat 的类库目录结构:

  • /common - 类库可被 Tomcat 和所有的 Web 应用程序共同使用
  • /server - 类库可被 Tomcat 使用,对所有的 Web 应用程序都不可见
  • /shared - 类库可被所有的 Web 应用程序共同使用,但对 Tomcat 不可见
  • /WebApp/WEB-INF - 类库仅仅可以被该 Web 应用程序使用

为了支持这套目录结构,并对目录中的类库进行加载和隔离。Tomcat 自定义了多个类加载器,并按照经典的双亲委派模型实现:

  • CommonClassLoader 继承 Java 自带的应用程序类加载器
    • 负责加载 Tomcat 和应用程序共用的类库
  • CatalinaClassLoader 和 SharedClassLoader 继承 CommonClassLoader
    • CatalinaClassLoader 加载仅被 Tomcat 使用的类库
    • SharedClassLoader 加载应用程序共用的类库
  • WebAppClassLoader 继承 SharedClassLoader
    • 每个 Web 应用程序对应一个 WebApp 类加载器,因此有多个实例
    • 每个 WebApp 类加载器之间隔离
  • JasperLoader 继承 WebAppClassLoader
    • 每个 JSP 文件对应一个 JasperLoader 类加载器
    • 仅用于加载某个 JSP 文件编译出的 Class 文件
    • 当服务器检测到 JSP 文件被修改时,会替换当前的 JasperLoader 实例,再建立一个新的 JSP 类加载器实现 JSP 的 HotSwap

在 Tomcat 6 中,为了易用性,默认将所有目录整合为一个 /lib 目录,默认只启用 CommonClassLoader。

  • 简化大多数部署场景
  • 可以通过配置文件指定 server.loader 和 share.loader 重新启用原来完整的加载器架构
Edit this page on GitHub
Prev
Chapter 8.5 - 基于栈的字节码解释执行引擎