TT Lab
开始
学习 学习路径 课程

Tomcat 与 nginx 运维

用 WAR 部署与并行部署做不停机切换

在 TT Lab 中继续学习

目标

确认 WAR 部署的实际行为,通过并行部署(Parallel Deployment)在不中断会话的情况下 升级版本,并编写带有验证功能的部署脚本。

为什么重要

在单台 WAS 环境中实现不停机部署,人们很容易认为必须在 L4 前端把服务器摘下再挂上。 然而 Tomcat 本来就有并行部署功能。 只要在文件名后加上 ##버전(占位符为版本号),同一个上下文中就可以并存多个版本, 已有会话走旧版本,新请求走新版本。 许多 SI 现场不知道这个功能,一直在凌晨重复停机部署。 还有一点——如果部署脚本不等待展开完成,就会把失败的部署 汇报为成功。这比停机部署要糟糕得多。

步骤

  1. 启动 Tomcat,将 /opt/lab/samples/labhub-1.0.0.war 部署为 /opt/tomcat/webapps/labhub##001.war。 http://127.0.0.1:8080/labhub/version 必须返回 1.0.0, 并且 catalina.out 中必须留有 labhub##001 的部署记录。 (这条部署记录将在后续步骤中作为证据使用。)
  2. 查看已展开的目录,创建 /root/tc/explode.csv。 首行为 path,exists。针对下面四个路径写入 Y/N。 WEB-INF/web.xml, WEB-INF/classes, WEB-INF/lib, META-INF
  3. 将 /opt/lab/samples/labhub-2.0.0.war 部署为 /opt/tomcat/webapps/labhub##002.war。 此时不要先删除 ##001,让两个版本并存。 http://127.0.0.1:8080/labhub/version 现在必须返回 2.0.0, 并且 catalina.out 中必须同时有 labhub##001 和 labhub##002 的部署记录。
  4. 编写 /root/tc/parallel.md。正文中必须包含下面三点。
    • 持有已有会话的请求会走向哪个版本
    • 新请求会走向哪个版本
    • 因为版本字符串按字符串比较排序,所以 ##1/##10 这类写法为什么危险 001 和 002 这两个字符串都必须出现。
  5. 彻底移除 ##001 版本(WAR 和展开目录都要删除)。 移除之后,http://127.0.0.1:8080/labhub/version 也必须返回 2.0.0。
  6. 在 8082 端口上后台启动 /opt/lab/samples/labhub-boot.jar, 并把日志保存到 /root/tc/boot.log。 http://127.0.0.1:8082/version 必须返回 200。
  7. 创建 /root/tc/war-vs-jar.csv。首行为 항목,WAR,JAR(首列表头为韩文,意为“项目”)。 必须有 배포단위、톰캣버전관리、포트지정、롤백、무중단 这五个项目(韩文,依次意为“部署单位”“Tomcat 版本管理”“端口指定”“回滚”“不停机”), 每个单元格都不能为空。
  8. 创建 /root/tc/deploy-war.sh。接收两个参数(WAR파일 컨텍스트명,占位符依次为 WAR 文件与上下文名称):
    • WAR 文件不存在或大小为 0 时,立即以非 0 的退出码结束。
    • 文件存在时,将其放入 webapps,并最多轮询 30 秒等待展开。
    • 如果 http://127.0.0.1:8080/<컨텍스트명>/version 返回 200,则以退出码 0 结束(占位符为上下文名称), 如果 30 秒内没有成功,则以非 0 的退出码结束。

参考

部署第一个版本

启动 Tomcat,将 /opt/lab/samples/labhub-1.0.0.war 部署为 /opt/tomcat/webapps/labhub##001.war。 http://127.0.0.1:8080/labhub/version 必须返回 1.0.0, 并且 catalina.out 中必须留有 labhub##001 的部署记录。 (这条部署记录将在后续步骤中作为证据使用。)

在文件名后加上 ##版本,上下文路径就是 ## 之前的部分。展开是异步的,复制后立刻请求可能返回 404。

确认展开结果

查看已展开的目录,创建 /root/tc/explode.csv。 首行为 path,exists。针对下面四个路径写入 Y/N。 WEB-INF/web.xml, WEB-INF/classes, WEB-INF/lib, META-INF

WAR 是 zip。请在展开的目录中找出标准 Web 应用程序结构。哪些是必需的、哪些是可选的,是这一步的学习要点。

并行部署第二个版本

将 /opt/lab/samples/labhub-2.0.0.war 部署为 /opt/tomcat/webapps/labhub##002.war。 此时不要先删除 ##001,让两个版本并存。 http://127.0.0.1:8080/labhub/version 现在必须返回 2.0.0, 并且 catalina.out 中必须同时有 labhub##001 和 labhub##002 的部署记录。

用相同的上下文名称,加上更高的版本字符串来部署。两个 WAR 必须同时处于展开状态,新请求应走向更高的版本。

整理对会话排空的理解

编写 /root/tc/parallel.md。正文中必须包含下面三点。

用文字整理并行部署中已有会话和新会话各自走向哪里。也请同时写下版本字符串是按字符串比较来排序的这一点。

下线旧版本

彻底移除 ##001 版本(WAR 和展开目录都要删除)。 移除之后,http://127.0.0.1:8080/labhub/version 也必须返回 2.0.0。

必须同时移除旧版本的 WAR 和展开目录。移除之后服务不能中断,版本响应仍然必须是新版本。

启动可执行 JAR

在 8082 端口上后台启动 /opt/lab/samples/labhub-boot.jar, 并把日志保存到 /root/tc/boot.log。 http://127.0.0.1:8082/version 必须返回 200。

内嵌 Tomcat 的方式通过启动参数指定端口。请让它在后台运行,并把日志保存到文件。

WAR 与 JAR 对比表

创建 /root/tc/war-vs-jar.csv。首行为 항목,WAR,JAR(首列表头为韩文,意为“项目”)。 必须有 배포단위、톰캣버전관리、포트지정、롤백、무중단 这五个项目(韩文,依次意为“部署单位”“Tomcat 版本管理”“端口指定”“回滚”“不停机”), 每个单元格都不能为空。

请从这样的角度来整理:真正左右选择的不是技术上的优劣,而是“运维流程标准化到了哪一边”。

编写部署脚本

创建 /root/tc/deploy-war.sh。接收两个参数(WAR파일 컨텍스트명,占位符依次为 WAR 文件与上下文名称):

把失败的部署汇报为成功的脚本最危险。等待展开的轮询循环,以及验证失败时返回非 0 的退出码,是关键所在。