第四章:Web 应用部署 第四章:Web 应用部署 4.1 Web 应用部署概述 在深入细节之前,我们先对 Web 应用部署有一个整体的认识。一个 Web 应用程序,通常打包成 Web Archive (WAR) 文件,或者以 exploded directory(展开目录) 的形式存在。部署的本质就是将这些资源放置到 Tomcat 服务器能够识别和访问的位置,并告知 Tomcat 如何处理这些资源。 部署流程概览: Tomcat 中的部署单元 - Web 应用: Tomcat 将 Web 应用程序视为部署的基本单元。每个 Web 应用都有其独立的运行环境,包括: ServletContext: 每个 Web 应用都有一个唯一的 对象,用于提供应用程序级别的共享信息和资源。
在深入细节之前,我们先对 Web 应用部署有一个整体的认识。一个 Web 应用程序,通常打包成 Web Archive (WAR) 文件,或者以 exploded directory(展开目录) 的形式存在。部署的本质就是将这些资源放置到 Tomcat 服务器能够识别和访问的位置,并告知 Tomcat 如何处理这些资源。
部署流程概览:
Tomcat 中的部署单元 - Web 应用:
Tomcat 将 Web 应用程序视为部署的基本单元。每个 Web 应用都有其独立的运行环境,包括:
ServletContext: 每个 Web 应用都有一个唯一的 ServletContext 对象,用于提供应用程序级别的共享信息和资源。
类加载器: Tomcat 使用独立的类加载器来加载每个 Web 应用的类,实现应用之间的隔离。
会话管理: 每个 Web 应用拥有独立的会话管理机制。
部署的目标:
可用性: 确保 Web 应用能够稳定运行,并对外提供服务。
性能: 优化部署配置,提升 Web 应用的响应速度和吞吐量。
安全性: 配置安全策略,保护 Web 应用免受攻击。
可维护性: 简化部署流程,方便应用的更新和维护。
理解 Web 应用的结构是进行有效部署的基础。Tomcat 能够识别两种形式的 Web 应用:WAR 文件 和 展开目录。
WAR 文件是一种 JAR 文件,用于打包 Web 应用程序的所有必要组件,包括:
Web 应用程序代码: Servlet 类、JSP 文件、JavaBean 等。
静态资源: HTML 文件、CSS 文件、JavaScript 文件、图片等。
部署描述符: web.xml 文件,用于配置 Web 应用的行为。
库文件: JAR 文件形式的依赖库,通常放在 WEB-INF/lib 目录下。
WAR 文件的目录结构:
mywebapp.war ├── META-INF/ │ └── MANIFEST.MF ├── WEB-INF/ │ ├── classes/ // 存放编译后的 Servlet 类和 JavaBean │ │ └── com/example/ │ │ └── MyServlet.class │ ├── lib/ // 存放 Web 应用依赖的 JAR 包 │ │ └── my-library.jar │ └── web.xml // Web 应用部署描述符 ├── index.jsp // 首页文件 ├── css/ │ └── style.css └── js/ └── script.js
优点:
单一文件: 方便传输和部署,只需上传一个 WAR 文件即可。
压缩格式: 减小文件大小,节省存储空间和传输带宽。
标准化格式: WAR 文件是 Java EE 标准的 Web 应用打包格式,具有良好的兼容性。
缺点:
部署时需要解压: Tomcat 在部署 WAR 文件时需要先将其解压到磁盘,增加部署时间。
修改后需要重新打包: 如果需要修改 WAR 文件中的任何内容,都需要重新打包 WAR 文件并重新部署。
展开目录是指将 WAR 文件解压后的目录结构直接放置到 Tomcat 的指定位置。这种方式部署的 Web 应用以目录的形式存在。
展开目录的结构与 WAR 文件解压后的结构相同:
mywebapp/ ├── META-INF/ │ └── MANIFEST.MF ├── WEB-INF/ │ ├── classes/ │ │ └── com/example/ │ │ └── MyServlet.class │ ├── lib/ │ │ └── my-library.jar │ └── web.xml ├── index.jsp ├── css/ │ └── style.css └── js/ └── script.js
优点:
部署速度快: 无需解压,Tomcat 可以直接加载展开目录中的资源。
修改后部署方便: 修改展开目录中的文件后,Tomcat 可以自动检测并重新加载,无需重新打包。
便于开发调试: 在开发阶段,使用展开目录部署可以方便地修改代码和资源,并立即看到效果。
缺点:
目录结构复杂: 相对于 WAR 文件,展开目录结构较为复杂,容易出错。
文件数量多: 展开目录包含大量文件,占用磁盘空间较多。
不方便传输: 传输展开目录需要复制整个目录结构,不如 WAR 文件方便。
选择 WAR 文件还是展开目录:
生产环境: 通常推荐使用 WAR 文件 部署,因为其方便管理、传输和部署,并且在生产环境中,应用的更新频率相对较低。
开发环境: 展开目录 更适合开发环境,因为它部署速度快,修改后可以立即生效,方便开发和调试。
Tomcat 提供了多种部署 Web 应用的方式,主要可以分为以下几种:
webapps 目录这是最简单也是最常用的部署方式。Tomcat 默认会监控 webapps 目录,并将放入该目录下的 WAR 文件或展开目录自动部署。
部署步骤:
准备 WAR 文件或展开目录: 确保你的 Web 应用已经打包成 WAR 文件或准备好展开目录。
复制到 webapps 目录: 将 WAR 文件或展开目录复制到 Tomcat 安装目录下的 webapps 目录中。
Tomcat 自动部署: Tomcat 会自动检测到新的 WAR 文件或展开目录,并进行部署。
示例 (复制 WAR 文件):
假设 Tomcat 安装在 /usr/local/tomcat 目录下,你的 WAR 文件名为 mywebapp.war。
cp mywebapp.war /usr/local/tomcat/webapps/
Tomcat 会自动解压 mywebapp.war 文件,并将其部署为名为 mywebapp 的 Web 应用。访问路径为 http://localhost:8080/mywebapp。
示例 (复制展开目录):
假设你的展开目录名为 mywebapp。
cp -r mywebapp /usr/local/tomcat/webapps/
Tomcat 会直接部署 mywebapp 目录下的 Web 应用。访问路径同样为 http://localhost:8080/mywebapp。
优点:
简单易用: 操作简单,只需复制文件或目录即可完成部署。
自动化部署: Tomcat 自动监控 webapps 目录,无需手动干预。
缺点:
管理性较差: 如果需要部署多个 Web 应用,webapps 目录会变得臃肿,管理不便。
灵活性不足: 无法对部署过程进行更精细的控制。
Tomcat Manager 应用是一个 Tomcat 自带的 Web 应用,用于管理 Tomcat 服务器上的 Web 应用,包括部署、停止、启动、重新加载和卸载等操作。
访问 Tomcat Manager 应用:
默认情况下,Tomcat Manager 应用的访问路径为 http://localhost:8080/manager/html。你需要使用在 tomcat-users.xml 文件中配置的具有 manager-gui 或 manager-script 角色的用户进行身份验证。
使用 Manager 应用部署 WAR 文件:
登录 Manager 应用: 输入用户名和密码登录 Tomcat Manager 应用。
选择 "WAR file to deploy" 部分: 在 Manager 应用的界面中,找到 "WAR file to deploy" 部分。
选择 WAR 文件: 点击 "Choose File" 按钮,选择要部署的 WAR 文件。
指定 Context Path (可选): 在 "Context Path" 输入框中,可以指定 Web 应用的 Context Path。如果不指定,默认使用 WAR 文件名作为 Context Path。
点击 "Deploy" 按钮: 点击 "Deploy" 按钮开始部署。
使用 Manager 应用部署展开目录 (需要配置 Context):
Manager 应用主要用于部署 WAR 文件,部署展开目录通常需要结合 Context 配置。可以在 Manager 应用的 "Deploy directory or WAR file located on server" 部分,输入展开目录的路径,并配置相应的 Context Path。
优点:
集中管理: 通过 Manager 应用可以集中管理 Tomcat 服务器上的所有 Web 应用。
可视化操作: 提供友好的 Web 界面,操作直观方便。
远程部署: 可以通过网络远程部署 Web 应用。
缺点:
需要配置用户权限: 需要配置 tomcat-users.xml 文件,设置具有 Manager 应用访问权限的用户。
安全性考虑: 需要确保 Manager 应用的安全性,防止未授权访问。
Context 配置文件 (context.xml) 允许你更灵活地配置 Web 应用的部署信息,包括 Context Path、文档根目录、会话管理器、资源管理器等。
Context 配置文件的位置:
Context 配置文件可以放置在以下位置:
${CATALINA_BASE}/conf/Catalina/localhost/ 目录: 推荐方式,每个 Web 应用对应一个独立的 Context 配置文件,文件名通常为 应用名.xml (例如 mywebapp.xml),Context Path 默认为文件名 (例如 mywebapp)。
${CATALINA_BASE}/conf/server.xml 文件中的 <Host> 元素内: 不推荐,将所有 Web 应用的 Context 配置都放在 server.xml 文件中,不利于管理和维护。
WAR 文件或展开目录的 META-INF/ 目录: 嵌入式 Context 配置,优先级最低,不推荐在生产环境中使用。
Context 配置文件的内容示例 (mywebapp.xml):
<Context path="/mywebapp" docBase="/path/to/mywebapp" reloadable="true"> <!-- 其他 Context 配置项 --> </Context>
path 属性: 指定 Web 应用的 Context Path,即访问路径的前缀。
docBase 属性: 指定 Web 应用的文档根目录,可以是 WAR 文件的绝对路径或展开目录的绝对路径。
reloadable 属性: 设置为 true 时,Tomcat 会在 Web 应用的类或资源文件发生变化时自动重新加载 Web 应用 (热部署)。
部署步骤 (使用 Context 配置文件):
创建 Context 配置文件: 创建 mywebapp.xml 文件,并配置 path 和 docBase 属性,指向你的 Web 应用的 WAR 文件或展开目录。
放置 Context 配置文件: 将 mywebapp.xml 文件放置到 ${CATALINA_BASE}/conf/Catalina/localhost/ 目录下。
Tomcat 自动部署: Tomcat 会自动检测到新的 Context 配置文件,并根据配置进行部署。
优点:
灵活配置: 可以配置 Context Path、文档根目录、资源管理器等,提供更灵活的部署选项。
独立管理: 每个 Web 应用拥有独立的 Context 配置文件,方便管理和维护。
热部署: 可以通过 reloadable 属性启用热部署功能。
缺点:
配置稍复杂: 需要手动创建和编辑 Context 配置文件。
文件管理: 需要管理 Context 配置文件,确保其与 Web 应用对应。
Tomcat 默认启用自动部署功能。当 Tomcat 启动时,它会自动扫描 webapps 目录和 Context 配置文件目录,并部署找到的 Web 应用。
自动部署的配置:
自动部署的行为可以通过 <Host> 元素的属性进行配置,主要属性包括:
autoDeploy 属性: 控制是否启用自动部署,默认为 true。
deployOnStartup 属性: 控制 Tomcat 启动时是否部署 Web 应用,默认为 true。
deployXML 属性: 控制是否部署 Context 配置文件,默认为 true。
unpackWARs 属性: 控制是否解压 WAR 文件,默认为 true。
这些属性可以在 ${CATALINA_BASE}/conf/server.xml 文件中 <Host> 元素中进行配置。
示例 (禁用自动部署):
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"> <!-- ... --> </Host>
将 autoDeploy 属性设置为 false 可以禁用自动部署功能。此时,Tomcat 只会部署在 server.xml 或 Context 配置文件中显式配置的 Web 应用。
优点:
自动化: 无需手动干预,Tomcat 自动完成 Web 应用的部署。
简化部署流程: 降低部署的复杂性。
缺点:
灵活性降低: 自动部署的行为受配置控制,灵活性相对较低。
资源消耗: 自动扫描目录和部署 Web 应用会消耗一定的系统资源。
web.xml 文件是 Web 应用的部署描述符,位于 WEB-INF/ 目录下。它定义了 Web 应用的各种配置信息,包括 Servlet、Filter、Listener、Context 参数、会话配置、安全配置等。
web.xml 的作用:
配置 Servlet: 定义 Servlet 的映射路径、初始化参数、加载顺序等。
配置 Filter: 定义 Filter 的映射路径、初始化参数、拦截规则等。
配置 Listener: 定义 Listener 的监听事件和实现类。
配置 Context 参数: 定义 Web 应用级别的参数,可以在 ServletContext 中获取。
配置会话管理: 定义会话超时时间、会话 Cookie 配置等。
配置安全: 定义安全约束、认证方式、角色等。
配置错误页面: 定义错误代码对应的错误页面。
配置 MIME 类型: 定义文件扩展名与 MIME 类型的映射关系。
web.xml 的基本结构:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <display-name>MyWebApp</display-name> <!-- Servlet 配置 --> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> <init-param> <param-name>param1</param-name> <param-value>value1</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping> <!-- Filter 配置 --> <filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Listener 配置 --> <listener> <listener-class>com.example.MyListener</listener-class> </listener> <!-- Context 参数配置 --> <context-param> <param-name>contextParam1</param-name> <param-value>contextValue1</param-value> </context-param> <!-- 会话配置 --> <session-config> <session-timeout>30</session-timeout> <!-- 分钟 --> </session-config> <!-- 错误页面配置 --> <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> <!-- MIME 类型配置 --> <mime-mapping> <extension>html</extension> <mime-type>text/html</mime-type> </mime-mapping> <!-- 其他配置 --> </web-app>
代码实践 (Servlet 配置示例):
假设我们有一个名为 HelloServlet 的 Servlet 类,位于 com.example 包下。需要在 web.xml 中配置 Servlet 映射,使其能够响应 /hello 路径的请求。
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>
HelloServlet.java 代码示例:
package com.example; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html><body>"); out.println("<h1>Hello Servlet!</h1>"); out.println("</body></html>"); } }
部署 Web 应用后,访问 http://localhost:8080/mywebapp/hello 即可看到 "Hello Servlet!" 的输出。
web.xml 的版本:
web.xml 的版本由 version 属性指定,对应不同的 Servlet 规范版本。常用的版本包括:
2.4: Servlet 2.4 规范
2.5: Servlet 2.5 规范
3.0: Servlet 3.0 规范
3.1: Servlet 3.1 规范
4.0: Servlet 4.0 规范
不同版本的 web.xml 规范支持的功能有所不同,例如 Servlet 3.0 引入了注解配置和 Servlet 容器启动监听器等新特性。
web.xml 的简化:
Servlet 3.0 及以上版本允许使用注解配置 Servlet、Filter、Listener 等组件,可以部分替代 web.xml 的配置。例如,可以使用 @WebServlet 注解配置 Servlet 的映射路径,无需在 web.xml 中进行配置。
尽管注解配置可以简化配置,但在某些情况下,web.xml 仍然是必要的,例如配置安全约束、错误页面、Context 参数等。
热部署 (Hot Deployment):
热部署是指在 Tomcat 服务器运行时,无需重启服务器即可部署新的 Web 应用或更新已部署的 Web 应用。Tomcat 通过监控 webapps 目录和 Context 配置文件目录,自动检测新的 WAR 文件、展开目录或 Context 配置文件,并进行部署。
热部署的实现机制:
文件监控: Tomcat 定期扫描 webapps 目录和 Context 配置文件目录,检查文件是否有变化。
自动部署器: 当检测到新的 WAR 文件、展开目录或 Context 配置文件时,自动部署器会启动部署过程。
类加载器隔离: Tomcat 使用独立的类加载器加载每个 Web 应用,方便在热部署时卸载旧版本的 Web 应用,加载新版本的 Web 应用。
启用热部署:
Tomcat 默认启用热部署功能。可以通过 <Host> 元素的 autoDeploy 属性和 Context 配置文件的 reloadable 属性进行控制。
autoDeploy 属性 (server.xml): 控制是否启用自动部署,默认为 true。
reloadable 属性 (context.xml): 控制是否启用 Web 应用的自动重新加载,默认为 false。在开发环境下,可以将 reloadable 设置为 true,以便在修改代码后自动重新加载 Web 应用。
重新部署 (Redeployment):
重新部署是指在 Tomcat 服务器运行时,手动或自动地重新加载已部署的 Web 应用。重新部署通常发生在以下情况:
Web 应用更新: Web 应用的代码或资源文件发生变化。
Context 配置更新: Web 应用的 Context 配置文件发生变化。
手动触发重新部署: 通过 Tomcat Manager 应用或 JMX 等方式手动触发重新部署。
重新部署的方式:
自动重新加载 (reloadable): 当 Context 配置文件的 reloadable 属性设置为 true 时,Tomcat 会自动监控 Web 应用的类和资源文件,并在文件发生变化时自动重新加载 Web 应用。
Tomcat Manager 应用: 可以通过 Tomcat Manager 应用的 "Reload" 功能手动重新加载 Web 应用。
JMX (Java Management Extensions): 可以通过 JMX 客户端连接 Tomcat 服务器,调用 MBean 的 reload 操作重新加载 Web 应用。
Touch 文件 (Trigger File): Tomcat 允许配置一个 "touch 文件",当该文件被修改时,Tomcat 会自动重新加载 Web 应用。
重新部署的流程:
热部署与重新部署的区别:
热部署: 主要指 Tomcat 自动检测新的 Web 应用并进行部署的过程,强调 "新部署"。
重新部署: 主要指 Tomcat 重新加载已部署的 Web 应用的过程,强调 "重新加载"。
在实际应用中,这两个概念经常被混用,都指的是在 Tomcat 运行时更新 Web 应用的过程。
Web 应用卸载是指从 Tomcat 服务器中移除已部署的 Web 应用,使其不再对外提供服务。
卸载的方式:
删除 webapps 目录下的 WAR 文件或展开目录: 如果 Web 应用是通过复制到 webapps 目录部署的,可以直接删除对应的 WAR 文件或展开目录。Tomcat 会自动检测到删除操作,并卸载 Web 应用。
删除 Context 配置文件: 如果 Web 应用是通过 Context 配置文件部署的,可以删除 ${CATALINA_BASE}/conf/Catalina/localhost/ 目录下对应的 Context 配置文件。Tomcat 会自动检测到删除操作,并卸载 Web 应用。
Tomcat Manager 应用: 可以通过 Tomcat Manager 应用的 "Undeploy" 功能卸载 Web 应用。
JMX: 可以通过 JMX 客户端连接 Tomcat 服务器,调用 MBean 的 undeploy 操作卸载 Web 应用。
卸载的流程:
卸载的注意事项:
停止 Web 应用: 在卸载 Web 应用之前,Tomcat 会先停止 Web 应用,停止接受新的请求,并等待正在处理的请求完成。
资源释放: 卸载 Web 应用后,Tomcat 会释放 Web 应用占用的资源,包括类加载器、内存、文件句柄等。
数据清理: 卸载 Web 应用不会自动清理 Web 应用的数据,例如数据库中的数据或文件系统中的文件。如果需要清理数据,需要在卸载 Web 应用之前手动进行。
本章详细介绍了 Tomcat Web 应用部署的各个方面,包括 Web 应用的结构、部署方式、部署描述符、上下文配置、热部署、重新部署和卸载等关键概念。通过代码实践和图文结合的方式,希望读者能够全面掌握 Tomcat Web 应用部署技术,并能够根据实际需求选择合适的部署方式,配置部署描述符和上下文,实现高效、稳定、安全的 Web 应用部署。
本章核心知识点:
Web 应用结构: WAR 文件和展开目录的结构和特点。
部署方式: 复制到 webapps 目录、Tomcat Manager 应用、Context 配置文件、自动部署。
部署描述符 web.xml: web.xml 的作用和基本结构,Servlet、Filter、Listener、Context 参数等配置。
上下文配置 context.xml: context.xml 的位置和作用,path、docBase、reloadable 等属性。
热部署与重新部署: 热部署和重新部署的概念、实现机制和配置方式。
Web 应用卸载: Web 应用卸载的方式和流程。
掌握 Web 应用部署技术是 Web 开发人员必备的技能之一。希望本章内容能够帮助读者更好地理解和应用 Tomcat Web 应用部署技术,为构建高质量的 Web 应用打下坚实的基础。