1.2 Tomcat 的历史与发展


文档摘要

1.2 Tomcat 的历史与发展 1.2 Tomcat 的历史与发展 1.2.1 Tomcat 的起源:Apache-Jakarta 项目 Tomcat 的故事始于上世纪 90 年代末,那个 Java Servlet 和 JSP 技术刚刚兴起的年代。为了推动这两项技术的普及和应用,Sun Microsystems(后被 Oracle 收购)需要一个高质量的、开源的参考实现。与此同时,Apache 软件基金会(Apache Software Foundation, ASF)也积极投身于开源 Java Web 技术的发展。

1.2 Tomcat 的历史与发展

1.2 Tomcat 的历史与发展

1.2.1 Tomcat 的起源:Apache-Jakarta 项目

Tomcat 的故事始于上世纪 90 年代末,那个 Java Servlet 和 JSP 技术刚刚兴起的年代。为了推动这两项技术的普及和应用,Sun Microsystems(后被 Oracle 收购)需要一个高质量的、开源的参考实现。与此同时,Apache 软件基金会(Apache Software Foundation, ASF)也积极投身于开源 Java Web 技术的发展。

1999 年,Sun 与 Apache 协同合作,将 Sun 内部的一个 Servlet 容器项目捐献给了 Apache 软件基金会,并命名为 Jakarta Tomcat。 Jakarta 项目是 Apache 基金会下专门负责 Java 相关开源项目的子项目。Tomcat 的诞生,正是为了在 Jakarta 项目下提供一个开源的 Servlet 和 JSP 容器。

最初的 Tomcat 代码基于 Sun 公司的 Servlet API 规范实现,目标是创建一个符合 Servlet 规范,并且能够稳定、高效运行的 Web 服务器。早期的 Tomcat 版本,例如 Tomcat 3.x,主要关注于实现 Servlet 2.2 和 JSP 1.1 规范。

内容详解:

  • Sun Microsystems 的角色: 作为 Java 技术的创造者,Sun 需要一个官方的 Servlet/JSP 参考实现来推动技术标准的落地和应用生态的建立。

  • Apache 软件基金会的角色: Apache 基金会以其开放、协作的开源模式,为 Tomcat 的发展提供了理想的平台。Jakarta 项目的框架,确保了 Tomcat 项目的规范化管理和社区驱动发展。

  • Jakarta Tomcat 的命名: "Jakarta" 代表了 Apache 基金会下的 Java 项目,"Tomcat" 则是一个富有活力和亲和力的名字,象征着这个项目像 Tomcat 猫一样灵活、敏捷。

  • 参考实现的意义: Tomcat 作为 Servlet/JSP 的参考实现,其重要性在于:

    • 规范验证: 确保 Servlet 和 JSP 规范的正确性和完整性。

    • 互操作性: 促进不同 Web 服务器之间的互操作性,因为大家都遵循同一套规范和参考实现。

    • 学习资源: 为开发者提供学习 Servlet 和 JSP 技术的最佳实践和示例。

代码实践(早期 Tomcat 配置示例 - server.xml):

早期的 Tomcat 配置相对简洁,server.xml 是核心配置文件。以下是一个简化的 Tomcat 3.x 时代的 server.xml 片段,展示了如何配置一个简单的 Connector 和 Engine:

<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"/> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context path="/myapp" docBase="myapp" debug="0" reloadable="true"/> </Host> </Engine> </Service> </Server>

代码详解:

  • <Server> 元素: Tomcat 的顶层元素,定义了整个 Tomcat 服务器。port="8005" 指定了关闭服务器的端口,shutdown="SHUTDOWN" 是关闭指令。

  • <Service> 元素: 代表一个 Tomcat 服务,可以包含多个 Connector 和一个 Engine。

  • <Connector> 元素: 配置连接器,负责接收客户端请求。port="8080" 定义了 HTTP 监听端口。maxThreads, minSpareThreads, maxSpareThreads 等属性控制了线程池大小,用于处理并发请求。

  • <Engine> 元素: Servlet 引擎,负责处理请求并返回响应。defaultHost="localhost" 设置了默认主机。

  • <Host> 元素: 代表一个虚拟主机,name="localhost" 定义了主机名,appBase="webapps" 指定了 Web 应用的根目录。

  • <Context> 元素: 定义了一个 Web 应用上下文,path="/myapp" 是访问应用的上下文路径,docBase="myapp" 指向 Web 应用的物理路径。

1.2.2 Tomcat 4.x:Catalina Servlet 引擎的诞生

Tomcat 发展历程中的一个重要里程碑是 Tomcat 4.x 的发布。Tomcat 4.x 引入了全新的 Catalina Servlet 引擎,这是一个完全重写的 Servlet 容器,标志着 Tomcat 在架构和性能上迈上了一个新的台阶。

Catalina 的设计目标是更加模块化、可扩展和高性能。它采用了基于 组件化 的架构,将 Servlet 容器分解为多个独立的组件,例如 Connector, Engine, Host, Context 等,这些组件可以灵活配置和组合。

Tomcat 4.x 实现了 Servlet 2.3 和 JSP 1.2 规范,并引入了许多重要的改进,例如:

  • 更强大的 Servlet 容器: Catalina 引擎提供了更完善的 Servlet 生命周期管理、会话管理、安全管理等功能。

  • JSP 预编译: Tomcat 4.x 引入了 JSP 预编译功能,可以将 JSP 页面在部署时预先编译成 Servlet,提高了 JSP 页面的首次访问速度。

  • 更灵活的部署: 支持 WAR 文件部署,简化了 Web 应用的打包和部署流程。

  • JNDI 支持: 开始支持 JNDI (Java Naming and Directory Interface),方便 Web 应用访问企业级资源。

内容详解:

  • Catalina 引擎的重要性: Catalina 的出现是 Tomcat 架构演进的关键一步,它奠定了现代 Tomcat 的基础架构。模块化设计使得 Tomcat 更易于维护、扩展和定制。

  • Servlet 2.3 和 JSP 1.2 的提升: 这两个规范的升级带来了更多的 Web 开发功能,例如过滤器 (Filter)、监听器 (Listener) 等,增强了 Web 应用的灵活性和可扩展性。

  • JSP 预编译的意义: JSP 页面在首次访问时需要编译成 Servlet,这个过程会消耗一定的时间。预编译功能将编译过程提前到部署阶段,显著提升了应用的启动速度和用户体验。

  • WAR 部署的便利性: WAR (Web Application Archive) 文件是一种标准的 Web 应用打包格式,包含了 Web 应用的所有资源 (Servlet, JSP, 静态文件, 配置文件等)。Tomcat 4.x 开始支持 WAR 文件部署,使得 Web 应用的部署变得更加简单快捷。

  • JNDI 支持的价值: JNDI 允许 Web 应用通过名称查找和访问各种资源,例如数据源、消息队列等。Tomcat 4.x 的 JNDI 支持为构建企业级 Web 应用提供了便利。

代码实践(Tomcat 4.x server.xml - Connector 配置变化):

Tomcat 4.x 的 server.xml 在 Connector 配置方面引入了更多的选项,例如可以配置不同的 Connector 实现,以适应不同的协议和性能需求。

<Connector className="org.apache.catalina.connector.http.HttpConnector" port="8080" minProcessors="5" maxProcessors="75" enableLookups="true" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" useURIValidationHack="false" disableUploadTimeout="true"/>

代码详解:

  • className="org.apache.catalina.connector.http.HttpConnector": 显式指定了 Connector 的类名。在 Tomcat 4.x 中,可以根据需要选择不同的 Connector 实现,例如 HttpConnector (基于阻塞 I/O) 或 JavaIoConnector (基于 Java NIO)。

  • minProcessorsmaxProcessors: 这两个属性控制了 Connector 使用的处理器数量,也与早期的线程池配置类似,用于管理并发连接。

1.2.3 Tomcat 5.x 和 6.x:性能优化与标准兼容

Tomcat 5.x 和 6.x 是 Tomcat 发展过程中的稳定性和性能提升的关键时期。这两个版本继续在 Catalina 引擎的基础上进行优化,并紧跟 Servlet 和 JSP 规范的更新。

Tomcat 5.x 实现了 Servlet 2.4 和 JSP 2.0 规范,主要关注于:

  • 性能提升: 通过改进 Catalina 引擎的架构和算法,Tomcat 5.x 在性能方面有了显著提升,尤其是在处理大量并发请求时。

  • AJP Connector 的完善: AJP (Apache JServ Protocol) Connector 是一种用于 Tomcat 与 Apache HTTP Server 集成的协议。Tomcat 5.x 对 AJP Connector 进行了完善,使得 Tomcat 可以更好地与 Apache HTTP Server 协同工作,构建高性能的 Web 应用架构。

  • 管理和监控增强: Tomcat 5.x 提供了更多的管理和监控功能,例如可以通过 JMX (Java Management Extensions) 对 Tomcat 进行监控和管理。

Tomcat 6.x 实现了 Servlet 2.5 和 JSP 2.1 规范,进一步关注于:

  • 易用性提升: Tomcat 6.x 在配置和管理方面做了很多改进,使得 Tomcat 更加易于使用和维护。例如,简化了 server.xml 的配置,提供了更友好的管理界面。

  • 性能进一步优化: Tomcat 6.x 继续在性能方面进行优化,尤其是在内存管理和资源利用方面。

  • 安全性增强: Tomcat 6.x 加强了安全性,修复了一些安全漏洞,并提供了更多的安全配置选项。

内容详解:

  • 性能提升的重要性: 随着 Web 应用的复杂度和用户规模不断增长,性能成为 Web 服务器的关键指标。Tomcat 5.x 和 6.x 的性能优化 efforts 确保了 Tomcat 能够应对日益增长的 Web 应用负载。

  • AJP Connector 的作用: 在典型的 Web 应用架构中,通常会使用 Apache HTTP Server 作为前端 Web 服务器,负责处理静态资源请求和负载均衡,而 Tomcat 则作为后端应用服务器,负责处理动态内容请求。AJP Connector 使得 Apache HTTP Server 可以高效地将动态内容请求转发给 Tomcat 处理。

  • 管理和监控的价值: 对于运行中的 Web 应用,管理和监控至关重要。Tomcat 5.x 和 6.x 提供的管理和监控功能,方便管理员及时了解 Tomcat 的运行状态,并进行必要的调整和维护。

  • Servlet 2.4/2.5 和 JSP 2.0/2.1 的改进: 这些规范的升级带来了更多的 Web 开发新特性,例如注解 (Annotation)、EL 表达式语言 (Expression Language) 等,简化了 Web 应用的开发,并提升了开发效率。

代码实践(Tomcat 6.x server.xml - 更简洁的 Connector 配置):

Tomcat 6.x 的 server.xml 配置更加简洁,许多属性都有了默认值,可以减少不必要的配置。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

代码详解:

  • protocol="HTTP/1.1": 显式指定了 HTTP 协议版本。默认情况下,Tomcat 6.x 使用 HTTP/1.1 协议。

  • 其他属性: port, connectionTimeout, redirectPort 等属性与之前的版本类似,但配置更加精简。

1.2.4 Tomcat 7.x:拥抱现代 Web 技术

Tomcat 7.x 是一个重要的版本,它实现了 Servlet 3.0、JSP 2.2、EL 2.2 和 WebSocket 1.0 规范,标志着 Tomcat 开始全面拥抱现代 Web 技术。

Tomcat 7.x 的主要特点包括:

  • Servlet 3.0 支持: Servlet 3.0 规范引入了许多重要的特性,例如:

    • 注解配置: 可以使用注解来配置 Servlet、Filter、Listener 等组件,无需再依赖 web.xml 部署描述符,简化了 Web 应用的配置。

    • 异步 Servlet: 支持异步 Servlet,可以处理长连接和推送等场景,提高了 Web 应用的并发处理能力。

    • 可插拔性: Servlet 3.0 规范增强了 Web 应用的可插拔性,可以更容易地集成第三方库和框架。

  • WebSocket 1.0 支持: WebSocket 是一种在客户端和服务器之间建立持久连接的双向通信协议。Tomcat 7.x 开始支持 WebSocket 1.0 规范,使得开发者可以使用 Tomcat 构建实时的 Web 应用。

  • 性能进一步提升: Tomcat 7.x 继续在性能方面进行优化,尤其是在异步 I/O 和 WebSocket 方面。

内容详解:

  • Servlet 3.0 注解配置的意义: 注解配置极大地简化了 Web 应用的配置,减少了 web.xml 的冗余代码,使得开发更加便捷高效。

  • 异步 Servlet 的价值: 异步 Servlet 解决了传统同步 Servlet 在处理长连接和推送场景下的性能瓶颈,使得 Web 应用可以更好地支持实时通信和高并发场景。

  • WebSocket 支持的意义: WebSocket 的出现为 Web 应用带来了真正的双向通信能力,使得构建实时聊天、在线游戏、实时监控等应用成为可能。

  • Servlet 3.0 规范的整体影响: Servlet 3.0 规范代表了 Java Web 开发技术的一个重要转折点,它引入了许多现代 Web 开发理念和技术,使得 Java Web 应用更加灵活、高效和易于扩展。

代码实践(Servlet 3.0 注解配置示例):

Servlet 3.0 允许使用注解来声明 Servlet,无需在 web.xml 中配置。

import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "HelloServlet", urlPatterns = {"/hello"}) public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>Hello Servlet 3.0 with Annotations!</h1>"); out.println("</body></html>"); } }

代码详解:

  • @WebServlet(name = "HelloServlet", urlPatterns = {"/hello"}): @WebServlet 注解用于声明一个 Servlet。name 属性指定 Servlet 的名称,urlPatterns 属性指定 Servlet 映射的 URL 模式。

  • 无需 web.xml 配置: 通过 @WebServlet 注解,Servlet 的配置信息直接嵌入到 Java 代码中,无需再在 web.xml 中进行配置。

1.2.5 Tomcat 8.x 和 9.x:HTTP/2 与 Jakarta EE 过渡

Tomcat 8.x 实现了 Servlet 3.1、JSP 2.3、EL 3.0、WebSocket 1.1 和 HTTP/2 协议,进一步提升了性能和对新 Web 标准的支持。

Tomcat 8.x 的主要亮点包括:

  • HTTP/2 支持: HTTP/2 是一种新的 HTTP 协议版本,旨在提高 Web 性能。Tomcat 8.x 开始支持 HTTP/2 协议,可以利用 HTTP/2 的多路复用、头部压缩等特性,提升 Web 应用的加载速度和性能。

  • NIO 和 NIO2 Connector: Tomcat 8.x 默认使用 NIO (Non-blocking I/O) Connector,并引入了 NIO2 Connector (基于 Java NIO.2)。NIO Connector 可以更好地处理大量并发连接,提升 Tomcat 的并发性能。

  • Servlet 3.1 的改进: Servlet 3.1 规范对 Servlet 3.0 进行了改进和完善,例如引入了非阻塞 I/O API,进一步提升了异步 Servlet 的性能。

Tomcat 9.x 实现了 Servlet 4.0、JSP 2.4、EL 3.0、WebSocket 1.1 和 HTTP/2 协议,并开始为 Jakarta EE 过渡做准备。

Tomcat 9.x 的主要特点包括:

  • Servlet 4.0 支持: Servlet 4.0 规范是 Java EE 8 的一部分,引入了 HTTP/2 服务端推送 (Server Push) 等新特性,进一步增强了 Web 应用的功能。

  • Jakarta EE 过渡准备: 随着 Java EE 向 Jakarta EE 的演进,Tomcat 9.x 开始为 Jakarta EE 过渡做准备,例如支持将 javax 命名空间迁移到 jakarta 命名空间。

  • 性能和安全性的持续提升: Tomcat 9.x 继续在性能和安全性方面进行优化和改进。

内容详解:

  • HTTP/2 支持的革命性意义: HTTP/2 的引入是 Web 协议发展的一个重要里程碑,它从根本上改变了 HTTP 协议的工作方式,显著提升了 Web 性能,尤其是在移动网络和高延迟网络环境下。

  • NIO 和 NIO2 Connector 的优势: NIO 和 NIO2 Connector 使用非阻塞 I/O 模型,可以更高效地处理大量并发连接,减少线程切换开销,提升 Tomcat 的并发处理能力和资源利用率。

  • Servlet 4.0 和 HTTP/2 服务端推送: Servlet 4.0 引入的 HTTP/2 服务端推送特性,允许服务器主动向客户端推送资源,无需客户端显式请求,进一步提升了 Web 应用的加载速度和用户体验。

  • Jakarta EE 过渡的背景: 由于 Oracle 将 Java EE 捐献给 Eclipse 基金会,Java EE 项目更名为 Jakarta EE。Jakarta EE 的一个重要变化是将所有 Java EE API 的包名从 javax.* 更改为 jakarta.*。Tomcat 9.x 开始为这一过渡做准备,为未来支持 Jakarta EE 版本的 Tomcat 奠定基础。

代码实践(Tomcat 8.x server.xml - HTTP/2 Connector 配置):

Tomcat 8.x 可以配置使用 HTTP/2 Connector。

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" maxThreads="150" connectionTimeout="20000" redirectPort="8443" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.3" keystoreFile="conf/localhost-cert.p12" keystorePass="changeit" keystoreType="PKCS12" />

代码详解:

  • protocol="org.apache.coyote.http11.Http11Nio2Protocol": 指定使用 NIO2 Connector。

  • SSLEnabled="true": 启用 SSL/TLS 加密,HTTP/2 通常需要基于 HTTPS。

  • SSL/TLS 配置: keystoreFile, keystorePass, keystoreType, sslProtocol, sslEnabledProtocols 等属性用于配置 SSL/TLS 证书和协议。

1.2.6 Tomcat 10.x 及未来:Jakarta EE 时代

Tomcat 10.x 是 Tomcat 的一个重要里程碑版本,它正式过渡到 Jakarta EE 平台,实现了 Jakarta Servlet 5.0 规范。

Tomcat 10.x 的核心变化是:

  • Jakarta EE 兼容: Tomcat 10.x 是第一个完全兼容 Jakarta EE 平台的 Tomcat 版本。它使用了 jakarta.* 命名空间,取代了之前的 javax.* 命名空间。这意味着基于旧 javax.* API 的 Web 应用需要进行迁移才能在 Tomcat 10.x 上运行。

  • Jakarta Servlet 5.0 支持: Tomcat 10.x 实现了 Jakarta Servlet 5.0 规范,这是 Jakarta EE 9 的一部分。Jakarta Servlet 5.0 规范在 Servlet 4.0 的基础上进行了一些小的改进和调整,主要是为了适应 Jakarta EE 平台的变化。

  • 持续演进和优化: Tomcat 10.x 仍然在持续演进和优化,包括性能提升、安全性增强、Bug 修复等。

Tomcat 的未来发展方向:

  • Jakarta EE 平台的持续支持: 未来的 Tomcat 版本将继续紧跟 Jakarta EE 平台的演进,支持最新的 Jakarta EE 规范,例如 Jakarta EE 10、Jakarta EE 11 等。

  • 云原生和容器化: 随着云原生和容器化技术的普及,未来的 Tomcat 版本将更加注重云原生特性和容器化支持,例如更好地与 Kubernetes 等容器编排平台集成,提供更轻量级、更易于部署和管理的 Tomcat 镜像。

  • 性能和安全性的持续提升: 性能和安全性始终是 Web 服务器的核心关注点。未来的 Tomcat 版本将继续在性能和安全性方面进行持续的改进和优化,以满足不断变化的 Web 应用需求。

  • 社区驱动的创新: Tomcat 是一个开源项目,其发展离不开社区的贡献。未来的 Tomcat 版本将继续鼓励社区参与,共同推动 Tomcat 的创新和发展。

内容详解:

  • Jakarta EE 兼容的重大意义: Tomcat 10.x 的 Jakarta EE 兼容标志着 Java Web 技术正式进入 Jakarta EE 时代。这是一个重要的技术转型,预示着 Java EE 技术将以更加开放、社区驱动的方式继续发展。

  • jakarta.* 命名空间的迁移: javax.*jakarta.* 命名空间的迁移是 Jakarta EE 兼容的关键一步,但也意味着现有的基于 javax.* API 的 Web 应用需要进行代码迁移才能在 Tomcat 10.x 及更高版本上运行。

  • 云原生和容器化的趋势: 云原生和容器化是当前 IT 领域的热门趋势。未来的 Tomcat 版本将更加注重与云原生和容器化技术的融合,以适应云时代的 Web 应用部署和管理需求.

  • 社区驱动的重要性: Tomcat 的成功离不开 Apache 软件基金会的开源模式和活跃的社区。社区的参与和贡献是 Tomcat 持续创新和发展的源动力。

代码实践(Tomcat 10.x Servlet 示例 - Jakarta Servlet):

Tomcat 10.x 使用 Jakarta Servlet API,包名从 javax.servlet.* 变更为 jakarta.servlet.*

import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "JakartaHelloServlet", urlPatterns = {"/jakarta-hello"}) public class JakartaHelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>Hello Jakarta Servlet 5.0!</h1>"); out.println("</body></html>"); } }

代码详解:

  • import jakarta.servlet.annotation.WebServlet;import jakarta.servlet.http.HttpServlet;: 注意包名已经从 javax.servlet.* 变更为 jakarta.servlet.*

  • Servlet 代码逻辑不变: Servlet 的核心代码逻辑与之前的版本基本相同,只是 API 的包名发生了变化。


发布者: 作者: 转发
评论区 (0)
U