Servlet 解决了什么问题?
Servlet 主要解决了以下几个核心问题:
-
性能问题 (Performance):
- CGI 的问题: 传统的 CGI 技术为每个Web 请求都启动一个新的进程。进程的创建和销毁涉及大量的系统资源开销(内存分配、CPU 时间、进程上下文切换等)。在高并发场景下,频繁创建进程会导致服务器负载过高,响应速度变慢,甚至崩溃。
- Servlet 的解决: Servlet 容器(如 Tomcat)通常只为每个 Servlet 类创建一个少数甚至只有一个 Servlet 实例(默认一个)。请求由容器的线程池中的线程来处理。线程的创建和管理开销远小于进程。多个请求可以共享同一个 Servlet 实例,并在不同的线程中并发执行其
service
方法。这种基于线程的处理方式,显著提高了处理大量并发请求的性能。
-
资源消耗问题 (Resource Consumption):
- CGI 的问题: 每个 CGI 进程都需要独立的内存空间,当并发请求多时,会占用大量系统内存。
- Servlet 的解决: 多个请求线程共享同一个 Servlet 实例的资源,以及 JVM 的内存空间,内存消耗相对更低。同时,Servlet 容器的连接池、线程池等机制也更有效的利用了系统资源。
-
开发效率问题 (Development Efficiency):
- CGI 的问题: CGI 程序可以使用各种语言编写,但与 Web 服务器的交互通常是通过标准输入/输出和环境变量进行的,处理 HTTP 请求头、请求体、Cookies、Session 等细节易出错。
- Servlet 的解决: Servlet 提供了统一的、面向对象的 Java API (
javax.servlet.*
) 方便访问 HTTP 请求(HttpServletRequest
)和构造 HTTP 响应(HttpServletResponse
)。API 抽象了底层网络通信和协议解析的细节,在开发中我们可以更专注于业务逻辑的实现。这大大简化了 Web 应用程序的开发过程。
-
平台依赖性问题 (Platform Dependency - Relative):
- CGI 的问题: CGI 程序依赖于特定的操作系统。
- Servlet 的解决: Servlet 是基于 Java 的,得益于 Java 的“一次编写,到处运行”特性,理论上同一个 Servlet 代码可以在任何支持 Java 的操作系统和符合 Servlet 规范的 Web 容器上运行,提高了跨平台性。
-
状态管理问题 (State Management):
- CGI 的问题: CGI 是无状态的,每个请求都是独立的。要实现用户会话(Session)等状态管理,需要开发者自己实现复杂的机制(如通过隐藏字段、URL 重写或 Cookies 手动管理)。
- Servlet 的解决: Servlet API 提供了内置的会话管理支持(
HttpSession
对象)。Servlet 容器负责创建、维护和管理用户的 Session,我们可以通过简单的 API 存储和获取用户会话相关的数据,极大的简化了有状态 Web 应用的开发。
-
部署和管理问题 (Deployment & Management):
- CGI 的问题: CGI 程序的部署和管理方式取决于Web 服务器,不够标准化。
- Servlet 的解决: Servlet 遵循标准的 Web 应用结构(WAR 包),可以统一部署到符合 Servlet 规范的容器中。容器提供了标准的管理和监控接口。
总结:
Servlet 的出现,通过引入基于线程的处理模型、统一的 API、内置的状态管理和标准化的部署方式,有效的解决了传统 CGI 技术在性能、资源消耗、开发效率、平台依赖性和状态管理等方面的问题,为 Java 成为企业级 Web 应用开发的主流语言奠定了基础。虽然现在我们更多地使用基于 Servlet 构建的上层框架(如 Spring MVC),但 Servlet API 仍然是这些框架处理 Web 请求的底层基础。