﻿---
title: Tomcat
date: 2024-07-24
tags: [Java, Web, Tomcat, Apache]
excerpt: Apache Tomcat，简称 Tomcat，是一个开源的、轻量级的 Web 应用服务器，它实现了 Java Servlet、JavaServer Pages（JSP）和少量Java EE技术规范。
thumbnail: https://assets.vluv.space/cover/Dev/Java/JavaWeb_Tomcat.webp
cover: https://assets.vluv.space/cover/Dev/Java/JavaWeb_Tomcat.webp
---

## Apache Tomcat Introduction

Tomcat 是一个开源的轻量级 Web 服务器和 **Servlet 容器**，由 Apache 软件基金会开发和维护。它实现了 Servlet 和 JSP 规范，同时也支持 WebSocket、HTTP/2 等协议，允许开发者使用 Java 编写服务器端应用程序来创建动态网页内容和处理客户端请求。Tomcat 通过其核心容器 Catalina，实现了高效的请求处理和响应机制。

容器 Container：指示一个应用程序的运行环境，Tomcat 是 Servlet 容器，意为 Tomcat 为 Servlet 运行提供了运行环境

> Apache 本义是一个北美原住民部落的名字。
> <br> <img src="https://assets.vluv.space/Java/Tomcat/tomcat-2024-06-08-20-42-49.webp" style="width:40%;"> <br>
> 此处 Apache 指的是 Apache Software Foundation (ASF) 是一家美国非营利性公司,成立于 1999 年

### 目录结构

```shell
├───bin 包含启动和停止 Tomcat 服务器所需的脚本文件
├───conf 这是Tomcat的主要配置文件目录
│   │─── server.xml：定义 Tomcat 服务器的全局设置，包括端口、连接器、引擎、虚拟主机等。
│   │─── web.xml：定义所有 Web 应用程序的默认配置，如错误页面、MIME 类型等。
│   │─── tomcat-users.xml：可配置用户的访问控制权限。
│   │─── context.xml：定义所有 Web 应用的共享默认上下文配置。
│   └───Catalina 该目录下可以设置默认加载的项目
│       └───localhost
├───lib 存放 Tomcat 服务器运行所需的共享库文件(JAR package)
├───logs 运行日志
├───temp JVM使用的临时文件
├───webapps 存放Web应用。可以以文件夹、war包、jar包的形式发布应用
└───work 包含Tomcat运行时创建的临时文件
```

## Servlet

Sevlet 是 Java EE 的一个标准，大部分的 Web 服务器都支持此标准。在 Web 应用中，Servlet 主要负责处理请求、协调调度功能。可以把 Servlet 称为 Web 应用中的**『控制器』**。

![alt text](https://assets.vluv.space/Java/Tomcat/Tomcat-1.webp)

### Create Servlet

```java
// 使用注解注册
@WebServlet(name = "HelloServlet", urlPatterns = "/hello")
public class HelloServlet implements Servlet {
    public TestServlet(){
        System.out.println("我是构造方法！");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("我是init");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("我是getServletConfig");
        return null;
    }

   @Override
   public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
      //首先将其转换为HttpServletRequest（继承自ServletRequest，一般是此接口实现）
         HttpServletRequest request = (HttpServletRequest) servletRequest;

         System.out.println(request.getProtocol());  //获取协议版本
         System.out.println(request.getRemoteAddr());  //获取访问者的IP地址
         System.out.println(request.getMethod());   //获取请求方法
         //获取头部信息
         Enumeration<String> enumeration = request.getHeaderNames();
         while (enumeration.hasMoreElements()){
               String name = enumeration.nextElement();
               System.out.println(name + ": " + request.getHeader(name));
         }

    @Override
    public String getServletInfo() {
        System.out.println("我是getServletInfo");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("我是destroy");
    }
   }
}
// 你可以在web.xml中进行注册
// <servlet>
//     <servlet-name>HelloServlet</servlet-name>
//     <servlet-class>com.example.HelloServlet</servlet-class>
// </servlet>
// <servlet-mapping>
//     <servlet-name>HelloServlet</servlet-name>
//     <url-pattern>/hello</url-pattern>
// </servlet-mapping>
```

### LifeCycle Of Servlet

- 执行构造方法完成 Servlet 初始化
- 调用 init () 方法。
- 调用 service() 方法处理客户端的请求。
- 销毁前调用 destroy() 方法。
- 最后，Servlet 由 JVM 的垃圾回收器进行垃圾回收的。

## Tomcat Component

### Connector

Connector 组件是 Tomcat 的前端，它负责接收来自客户端的网络请求并将其传递给后端的容器进行处理。Connector 支持不同的协议，如 HTTP/1.1、HTTP/2、AJP（Apache Jserv Protocol）、NIO（Non-blocking I/O）和 NIO2 等。在 Tomcat 中，Coyote 是默认的连接器实现。

#### Coyote

Coyote 是 Tomcat 中的连接器组件，它负责网络 I/O 操作。Coyote 可以使用不同的协议处理器来处理不同类型的请求，例如 HTTP/1.1 处理器、HTTP/2 处理器或 AJP 处理器。Coyote 还支持 NIO 和传统的阻塞 I/O。

### Servlet Container

Catalina 是 Tomcat 的核心组件，它实现了 Servlet 容器功能。Catalina 由以下容器层级组成：

- Engine: 每个 Engine 代表一个完整的服务器实例。一个 Tomcat 实例通常只有一个 Engine，但它可以配置多个，以支持多个独立的部署环境。
- Host: Host 是虚拟主机的概念，允许在同一个 Tomcat 实例中托管多个网站或应用。每个 Host 可以有自己的域和端口配置。
- Context: Context 是 Web 应用的容器，每个 Context 对应一个 Web 应用。它负责加载和管理 servlets、JSP 页面、filter 和 listener 等 Web 组件。
- Wrapper: Wrapper 是 servlet 的容器，每个 Wrapper 封装一个 servlet 实例，负责它的生命周期管理。

## Cluster

在 Tomcat 集群中，通过会话复制确保了即使某个节点失效，用户会话也能在其他节点上继续有效，从而提高了高可用性和负载均衡能力。

```shell
         Server
           |
         Service
           |
         Engine
           |  \
           |  --- Cluster --*
           |
         Host
           |
         ------
        /      \
     Cluster    Context(1-N)
        |             \
        |             -- Manager
        |                   \
        |                   -- DeltaManager
        |                   -- BackupManager
        |
     ---------------------------
        |                       \
      Channel                    \
    ----------------------------- \
        |                          \
     Interceptor_1 ..               \
        |                            \
     Interceptor_N                    \
    -----------------------------      \
     |          |         |             \
   Receiver    Sender   Membership       \
                                         -- Valve
                                         |      \
                                         |       -- ReplicationValve
                                         |       -- JvmRouteBinderValve
                                         |
                                         -- LifecycleListener
                                         |
                                         -- ClusterListener
                                         |      \
                                         |       -- ClusterSessionListener
                                         |
                                         -- Deployer
                                                \
                                                 -- FarmWarDeployer
```

**DeltaManager** 是 Tomcat 中用于会话复制的核心组件，它负责维护会话状态的同步。与 StandardManager 相比，DeltaManager 专注于只传输会话状态的变化，而不是整个会话状态，从而减少了网络带宽的消耗。

**Session Replication in Tomcat Clusters**
在 Tomcat 集群中，会话复制可以采用几种不同的策略，其中最常见的是基于 TCP/IP 的复制。以下是会话复制过程的主要步骤：

1. Session Creation and Modification:
   当一个用户会话在某一台 Tomcat 服务器上创建或修改时，该服务器的 DeltaManager 会检测到这个变化。
2. Replication Trigger:
   DeltaManager 会触发一个复制事件，将这个会话的更改通过 TCP/IP 网络发送给集群中的其他服务器。这个过程可以在每次会话修改后立即发生，也可以基于某种策略（例如脏标志）来优化复制频率。
3. Session State Transfer:
   其他服务器上的 DeltaManager 接收到来自源服务器的会话状态更新，然后更新本地的会话存储，使本地状态与源服务器一致。
4. Failure Recovery:
   如果集群中的某台服务器出现故障，其他服务器会自动检测到这一情况，并且由于会话状态已经被复制，所以它们能够继续处理属于故障服务器的会话，而无需任何数据丢失或中断。

## Ref

[wiki-The_Apache_Software_Foundation](https://en.wikipedia.org/wiki/The_Apache_Software_Foundation)
[Apache Tomcat 11](https://tomcat.apache.org/tomcat-11.0-doc/)
[柏码知识库](https://www.itbaima.cn/document/ycpagby2v7j4p728?segment=1)
