云原生(TOMCAT概述)

一、WEB 技术基础

1.1 HTTP 协议与 B/S 架构

(1)进程 / 线程与网络通信基础

操作系统通过多进程 + 多线程 充分利用硬件资源:进程是资源分配的基本单位,线程是 CPU 调度的基本单位,多线程实现程序并行执行,让单台主机可作为服务器为多个客户端提供计算服务。跨主机进程间通信依赖网络编程 ,最核心的编程接口是Socket(套接字),类比 "插座",通信分为两端:

  • 服务器端:被动接收请求,提供计算和数据服务;
  • 客户端:主动发起计算 / 数据请求。
(2)C/S 编程模式

基于 Socket 实现的Client/Server(C/S) 是底层编程模式,基于传输层 TCP/UDP 协议,开发的程序需单独安装客户端,典型案例 :QQ、迅雷、云音乐、云盘、Foxmail、Xshell。核心特点:底层通信、客户端与服务端强耦合、定制化程度高,但开发和维护成本高。

(3)B/S 编程模式的诞生与发展
  1. 基础诞生 :1990 年HTTP 协议 + 浏览器 诞生,在应用层 通过文本格式跨网络传输数据,浏览器将服务器返回的 HTML 渲染为可视化页面,正式诞生网页开发。
    • 核心逻辑:网页是存储在 WEB 服务器的文本文件,浏览器通过 URL 发起 HTTP 请求,WEB 服务器根据 URL 读取对应 HTML 文件,封装为 HTTP 响应报文返回给浏览器。
  2. 静态网页阶段 :早期网页仅由 HTML、CSS 制作,核心能力是静态展示 (文字、图片)和超链接跳转,无动态交互能力。
  3. 动态网页的探索
    • 浏览器端动态:网景公司 1995 年推出JavaScript (初期名 LiveScript,借 Java 名气更名),通过浏览器 JS 引擎执行,实现网页元素动态变化;微软 ActiveX、SUN Applet 也能实现浏览器端代码执行,但存在严重安全漏洞,未成为主流。
    • 服务器端动态:为规避浏览器端安全问题,诞生CGI(通用网关接口) ,实现 URL 直接映射服务器端脚本程序,脚本可查询数据库并动态生成页面内容,这是动态网页技术的核心开端。
  4. B/S 模式成型 :在 CGI 基础上,衍生出 ASP、PHP、JSP 等WEB 后端编程技术 (代码运行在服务器端),与运行在浏览器端的WEB 前端编程技术 (HTML、CSS、JS)结合,形成Browser/Server(B/S) 编程模式,无需安装客户端,通过浏览器即可访问。

1.2 前端三大核心技术

(1)HTML(超文本标记语言)
  • 核心定位 :非编程语言,是网页的结构骨架,用于定义网页的内容和布局。

  • 超文本含义:超出纯文本范畴,可描述文本格式(颜色、大小、字体),嵌入图片、音频、视频等非文本内容。

  • 组成结构 :由各类标签组成,标签各司其职(布局、文字、图片、链接等),一个 HTML 文件 = 格式标签 + 业务数据。

  • 核心依赖 :需浏览器解析渲染,才能将标签转化为可视化页面;HTTP 协议实现超文本的网络传输与共享。

  • 基础示例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body>

    老李老李出门见喜

    </body> </html>
(2)CSS(层叠样式表)
  • 诞生背景 :HTML 本身的样式能力有限,为实现复杂样式需嵌套大量标签,导致 HTML 文件臃肿冗余 ,CSS 应运而生,专门负责网页的样式美化
  • 标准发展 :1994 年 W3C 成立,CSS 设计小组加入并主导标准研发;1996 年 12 月发布CSS 1.0 (基础样式能力);1998 年 5 月发布CSS 2.0 (完善布局、浮动、定位等能力);CSS 3.0 :采用模块化设计,在 CSS 2 基础上逐个模块升级(如动画、弹性布局、网格布局),模块陆续发布,至今仍在更新。
  • 核心问题浏览器兼容性,不同浏览器的渲染引擎(如 Chrome 的 Blink、Firefox 的 Gecko、IE 的 Trident)对 CSS 标准的支持程度不同,导致同一套 CSS 代码在不同浏览器中显示效果不一致。
(3)JavaScript(JS)
  • 核心属性动态、弱类型、解释型脚本语言 ,是网页的行为引擎,实现网页的交互、动态效果、数据处理等功能,与 HTML、CSS 并称 WEB 前端三大核心技术,兼容所有主流浏览器。
  • 发展历程 :1994 年:网景公司发布 Netscape Navigator 浏览器,占据主流市场;1995 年 9 月:网景推出 LiveScript,12 月更名为JavaScript ,借 Java 的品牌效应推广;1997 年:网景、微软、SUN 等企业联合 ECMA(欧洲计算机制造商协会)制定ECMAScript 标准 ,JS 和微软的 JScript 均成为该标准的实现,解决语言碎片化问题;2008 年:Chrome 浏览器发布V8 引擎 (C++ 开发),颠覆 JS 执行方式 ------本地编译执行 (而非传统解释执行),大幅提升运行效率,堪比本地二进制程序;2009 年:基于 V8 引擎的Node.js 诞生,推出npm(Node 包管理器) ,构建了庞大的开源库生态,让 JS 突破浏览器限制,成为服务器端编程语言 ,实现前后端通用(目前唯一的前后端通用语言)。
(4)同步与异步交互(WEB 交互核心)
① 同步交互
  • 核心逻辑 :用户发起请求后,浏览器阻塞等待 服务器响应,响应完成后返回全新页面,即使仅需更新少量内容,也需重新渲染整个页面。
  • 典型问题:用户体验差(页面刷新等待)、资源浪费(带宽、浏览器渲染资源),例如注册页面仅密码不一致,提交后整个页面刷新,所有输入项需重新填写。
  • 本质:请求与响应一一对应,单线程阻塞执行。
② 异步交互
  • 核心逻辑 :用户发起请求后,浏览器不阻塞 ,可继续操作,服务器仅返回需要更新的少量数据 ,浏览器仅局部更新页面,无需整体刷新。
  • 技术演进 :1996 年:微软推出iframe 标签 ,实现页面局部异步加载,是早期异步雏形;1999 年:微软推出 ActiveX 插件,内置XMLHttpRequest 对象 ,实现异步数据传输,虽插件笨重,但该对象成为核心基础;核心技术:Ajax(Asynchronous JavaScript And XML) ,1998 年起源于微软 Outlook Web Access 团队,是技术组合(非发明),核心是通过 JS 调用 XMLHttpRequest 对象,实现后台与服务器的少量数据交换。
  • Ajax 核心特点 :无需刷新整个页面,仅局部更新;异步通信,不阻塞浏览器操作;早期基于 XML 数据格式,目前主流使用JSON (轻量、易解析);实现前后端彻底分离,改变传统开发模式(前端专注页面,后端专注接口)。

二、WEB 框架体系

2.1 WEB 资源与访问方式

WEB 资源分为静态资源 (HTML、CSS、JS、图片、视频)和动态资源 (数据库查询结果、业务逻辑计算结果),对应不同的服务器存储和访问方式,主要分为PC / 移动端浏览器访问手机 App 访问 两类,核心架构包含:静态 WEB 服务器、图片服务器、业务服务器、数据库服务器

(1)PC / 移动端浏览器访问
  1. 静态 WEB 服务器请求 HTML、CSS、JS 等文件,浏览器接收后解析渲染;
  2. 图片服务器请求图片、视频等媒体资源,嵌入页面展示;
  3. 业务服务器 发起动态请求,业务服务器访问数据库服务器获取数据,处理后返回动态内容至浏览器。
(2)手机 App 访问
  1. App内置 HTML、JS 文件,无需从静态 WEB 服务器下载,减少网络请求,解决现代前端 JS 文件过大 / 过多的问题;
  2. 按需从图片服务器 请求媒体资源,从业务服务器请求动态数据;
  3. 核心依赖业务服务器集群,满足多样化的客户需求,单台业务服务器无法支撑高并发和复杂业务。

2.2 后台应用架构(核心:单体架构 vs 微服务架构)

WEB 后台架构经历了单体架构→SOA 架构→微服务架构 的演进,其中微服务架构是 SOA(面向服务架构)的子集,是目前互联网企业的主流架构,核心差异在于功能拆分、部署方式和耦合度。

(1)单体架构(All in One)
① 核心定义

传统单机架构,将一个项目的所有功能模块(如商品、订单、支付、库存、登录、注册)整合在一个工程 中,编译打包为一个包 (jar/war),部署在一台服务器 上,运行为一个进程

② Java 技术实现

基于JSP+Servlet开发,编译后打包为 war 包,部署在 WEB 应用服务器(Tomcat、Jetty 等)上运行。

③ 扩展方式

水平扩展 :当单台服务器负载不足时,将 war 包复制多份,部署在多台服务器上,通过负载均衡(如 Nginx)实现请求分发。

④ 核心优势
  • 开发、测试、部署简单便捷,适合小型项目和初创团队;
  • 技术栈统一,无需处理分布式问题,开发成本低;
  • 调试方便,单进程运行,问题定位快速。
⑤ 核心劣势
  • 模块耦合度极高 ,单个模块故障可能导致全站不可用
  • 模块修改、Bug 修复、版本升级需停止整个服务 ,重新打包部署,不支持快速迭代,无法满足互联网业务的快速更新需求;
  • 大型项目中,代码量庞大,维护和分工难度大,多人协作开发易产生冲突;
  • 水平扩展成本高,需复制整个应用,资源利用率低。
⑥ 适配 WEB 应用服务器
  • 开源:Tomcat、Jetty、Glassfish(轻量级,适合中小型项目);
  • 商用:Weblogic、Websphere、Jboss(重量级,功能完善,适合大型企业项目,需付费)。
(2)微服务架构(Microservices)
① 核心定义

将传统一站式单体应用,按照业务边界 拆分为多个独立的微服务 ,每个微服务仅负责一个单一的业务功能 (如订单服务、支付服务、商品服务),各服务可独立开发、测试、部署、启动 / 销毁,属于分布式架构

② 核心特征
  • 服务松耦合,业务边界清晰,无代码依赖;
  • 每个服务可使用独立的技术栈(如 Java、Python、Go、PHP),独立的数据库(也可共用统一数据库);
  • 服务间通过轻量级通信机制 交互,主流为基于 HTTP 的 RESTful API
  • 服务可独立扩展,根据业务压力仅扩展高并发服务(如秒杀场景仅扩展订单服务),资源利用率高。
③ 对研发团队的影响

改变传统水平团队架构 (前端、后端、DBA、测试分属不同团队,按技术分工),转向垂直团队架构 (按业务分工,如订单团队、支付团队、用户团队),每个团队负责一个微服务的全生命周期(开发、测试、部署、运维),实现 "让专业的人干专业的事"。企业实际情况 :不会绝对拆分,多为水平 + 垂直的混合架构,兼顾技术复用和业务独立。

④ 核心优势
  1. 服务内聚性强,代码量少,易理解、易修改、易维护;
  2. 小团队(2-5 人)可独立开发一个微服务,开发效率高,团队协作冲突少;
  3. 服务独立部署 ,修改或升级无需停止其他服务,支持快速迭代
  4. 支持多语言开发,可根据业务场景选择最优技术栈(如大数据场景用 Python,高并发场景用 Go);
  5. 易与第三方系统集成,可通过持续集成工具(Jenkins、Hudson、Bamboo)实现自动化部署
  6. 前后端彻底分离,微服务仅负责业务逻辑和数据接口,不涉及 HTML/CSS 等前端内容;
  7. 服务可独立存储,根据业务需求设计数据库,提升数据安全性和性能。
⑤ 核心劣势
  1. 架构复杂度提升,增加开发、测试、运维、监控的成本(需维护多个服务、多个数据库);
  2. 分布式问题突出,需解决服务注册 / 发现、服务治理、分布式事务、数据一致性等问题,引入异步补偿机制;
  3. 对开发人员和运维人员的技术能力要求高,需掌握分布式、微服务框架、容器化(Docker/K8s)等技术;
  4. 不适合小型项目,盲目拆分会导致架构过度设计,维护成本远高于开发成本。
⑥ 常见微服务框架
框架 核心定位 通信协议 服务治理 适用场景
Dubbo 高性能 Java RPC 框架 RPC(自定义) Zookeeper 纯 Java 技术栈、高并发场景
Spring Cloud 完整微服务解决方案 HTTP/RESTful Eureka/Nacos 多语言技术栈、分布式场景
✅ Dubbo
  • 阿里开源,后捐赠给 ASF(Apache 软件基金会),成为 Apache 顶级项目;
  • 核心能力:将单体程序拆分为多个功能服务模块,模块间通过高性能 RPC 协议通信,比 HTTP 协议效率更高;
  • 服务治理:基于Zookeeper实现服务注册、服务发现、负载均衡、服务熔断、服务降级。
✅ Spring Cloud
  • 基于 Spring 生态的微服务全家桶 ,是 Dubbo 的超集,提供完整的微服务解决方案;
  • 核心能力:将单体应用拆分为粒度更细的单一功能服务,模块间通过HTTP/RESTful API通信,兼容性更强;
  • 生态丰富:包含 Eureka(服务注册)、Ribbon(负载均衡)、Hystrix(服务熔断)、Feign(远程调用)、Config(配置中心)、Sleuth(链路追踪)等组件。
(3)单体架构与微服务架构核心对比
对比维度 单体架构 微服务架构
工程结构 一个工程,所有代码整合 多个独立工程,按业务拆分
部署方式 一个包(jar/war),一个进程 多个包,多个独立进程
耦合度 模块高耦合,代码相互依赖 服务松耦合,无代码依赖,业务边界清晰
扩展方式 水平扩展,复制整个应用 独立扩展,仅复制高并发服务
数据库 单一数据库,所有模块共用 各服务可独立数据库,也可共用
技术栈 必须统一 支持多语言、多技术栈
部署成本 低,单包部署 高,多服务独立部署
维护成本 小型项目低,大型项目极高 小型项目高,大型项目低
迭代速度 慢,需整体重启 快,服务独立更新
分布式问题 无,单机运行 有,需解决服务治理、分布式事务等
团队架构 水平架构,按技术分工 垂直架构,按业务分工
适用场景 小型项目、初创团队、传统企业项目 大型互联网项目、高并发场景、快速迭代业务

三、Tomcat 核心详解

3.1 Tomcat 基础认知

(1)官方定义

Apache Tomcat免费、开源的轻量级 WEB 应用服务器 ,由 Apache 软件基金会维护,适用于中小型系统并发访问用户不多的场景,是目前最主流的 Java WEB 应用服务器。

(2)核心能力
  1. 具备处理静态 HTML 页面的能力;
  2. 是标准的Servlet 容器JSP 引擎,支持 JSP+Servlet 开发的 Java WEB 项目部署;
  3. 支持 HTTP/1.1 协议,兼容主流浏览器;
  4. 支持虚拟主机、负载均衡、集群部署等高级功能。
(3)发展历程
  1. 起源:源于SUN 公司 的 Servlet 参考实现项目Java Web Server,由 James Duncan Davidson 开发;
  2. 1999 年:SUN 将项目捐赠给Apache 软件基金会(ASF),与 ASF 的 JServ 项目合并,开源成为 Apache 顶级项目,命名为 Tomcat;
  3. 1999 年:发布Tomcat 3.0 ,实现Servlet 2.2JSP 1.1规范,是第一个正式版本;
  4. Tomcat 4.x:内置Catalina(Servlet 容器)Jasper(JSP 引擎),成为核心架构,沿用至今;
  5. 版本现状:正式版已更新至 9.0.x,企业主流使用 7.x 和 8.x 版本(稳定性高、生态完善)。
(4)Java EE 规范支持

Tomcat仅实现了 Java EE 规范中与 Servlet、JSP 相关的类库 ,是Java EE 的不完整实现 ,未实现 EJB、JMS、JTA 等企业级规范,因此被称为轻量级应用服务器;若需使用完整 Java EE 规范,需使用 Weblogic、Websphere 等重量级商用服务器。

(5)官方资源

3.2 Tomcat 安装(Linux 环境,CentOS 为例)

Tomcat 基于 Java 开发,运行前必须先安装Java 环境(JDK),推荐使用 JDK1.8(兼容性最好,与 Tomcat 7/8/9 完美匹配)。

步骤 1:安装并验证 Java 环境
复制代码
# 1. 安装OpenJDK 1.8(开源免费,企业主流)
[root@tomcat ~]# yum install java-1.8.0-openjdk.x86_64 -y

# 2. 验证Java版本,确认安装成功
[root@tomcatA ~]# java -version
# 预期输出:
openjdk version "1.8.0_402"
OpenJDK Runtime Environment (build 1.8.0_402-b06)
OpenJDK 64-Bit Server VM (build 25.402-b06, mixed mode)

# 3. 查看Java可执行文件路径
[root@tomcatA ~]# which java
# 预期输出:/usr/bin/java

# 4. 查看Java软链接指向的实际路径(JRE目录)
[root@tomcatA ~]# ll /usr/bin/java
# 预期输出:lrwxrwxrwx 1 root root 22 Jul 30 10:41 /usr/bin/java -> /etc/alternatives/java

# 5. 进入JRE运行环境目录,验证文件完整性
[root@tomcatA ~]# cd /etc/alternatives/jre
[root@tomcatA jre]# ls
# 预期输出:ASSEMBLY_EXCEPTION bin lib LICENSE THIRD_PARTY_README
步骤 2:安装并启动 Tomcat
复制代码
# 1. 从Apache官网下载Tomcat安装包(以9.0.107为例),上传至Linux服务器/root目录
# 2. 解压安装包至/usr/local/(Linux常用软件安装目录)
[root@tomcatA ~]# tar zxf apache-tomcat-9.0.107.tar.gz -C /usr/local/

# 3. 重命名解压目录,简化操作(可选,推荐)
[root@tomcatA ~]# cd /usr/local/
[root@tomcatA local]# mv apache-tomcat-9.0.107/ tomcat

# 4. 进入Tomcat的bin目录(存放启动/停止脚本)
[root@tomcatA local]# cd tomcat/bin/

# 5. 启动Tomcat(./startup.sh为Linux启动脚本,catalina.bat为Windows脚本)
[root@tomcatA bin]# ./startup.sh
# 预期输出,确认启动成功:
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
步骤 3:验证 Tomcat 启动
复制代码
# 1. 查看Tomcat端口(默认8080,TCP6协议)
[root@tomcat ~]# netstat -antlupe | grep java
# 预期输出:tcp6 0 0 :::8080 :::* LISTEN 0 68636 32887/java

# 2. 浏览器访问Tomcat默认页面,验证是否可访问
# 访问地址:http://服务器IP:8080
# 若页面显示"Apache Tomcat/9.0.91"及欢迎信息,说明启动成功
步骤 4:配置 Tomcat 为系统服务(开机自启,推荐)

默认通过./startup.sh启动的 Tomcat,重启服务器后会停止,需配置为systemd 系统服务,实现开机自启和便捷的服务管理。

复制代码
# 1. 生成Tomcat配置文件,指定JAVA_HOME(JRE目录)
[root@tomcat ~]# vim /usr/local/tomcat/conf/tomcat.conf
# 写入以下内容:
JAVA_HOME=/etc/alternatives/jre

# 2. 生成systemd服务文件(/lib/systemd/system/为系统服务默认目录)
[root@tomcat ~]# vim /lib/systemd/system/tomcat.service
# 写入以下内容:
[Unit]
Description=Tomcat  # 服务描述
After=syslog.target network.target  # 依赖服务:日志、网络

[Service]
Type=forking  # 后台运行模式
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf  # 加载配置文件
ExecStart=/usr/local/tomcat/bin/startup.sh  # 启动命令
ExecStop=/usr/local/tomcat/bin/shutdown.sh  # 停止命令
PrivateTmp=true  # 私有临时目录
User=tomcat  # 运行用户
Group=tomcat  # 运行用户组

[Install]
WantedBy=multi-user.target  # 开机自启级别

# 3. 创建tomcat用户和用户组(禁止登录,仅用于运行服务)
[root@tomcatB bin]# useradd -s /sbin/nologin -M tomcat

# 4. 给Tomcat安装目录赋予tomcat用户/组的权限
[root@tomcatB bin]# chown tomcat.tomcat /usr/local/tomcat/ -R

# 5. 重新加载systemd配置,使服务文件生效
[root@tomcatB ~]# systemctl daemon-reload

# 6. 启动Tomcat并设置开机自启
[root@tomcatB ~]# systemctl enable --now tomcat

# 7. 验证服务状态
[root@tomcatB ~]# systemctl status tomcat
# 显示active (running)即为成功

3.3 Tomcat 文件结构与核心目录

Tomcat 的安装目录结构清晰,各目录各司其职,核心目录共 7 个,掌握目录功能是配置和部署 Tomcat 的基础,默认安装目录:/usr/local/tomcat

(1)完整目录列表
复制代码
[root@tomcat ~]# ls /usr/local/tomcat/
bin  BUILDING.txt  conf  CONTRIBUTING.md  lib  LICENSE  logs  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  temp  webapps  work
(2)核心目录详细说明
目录名 英文全称 核心功能与详细说明
bin Binary 存放 Tomcat启动、停止、配置等脚本文件,核心脚本:・startup.sh/shutdown.sh:Linux 启动 / 停止脚本・catalina.sh:核心运行脚本(startup/shutdown 最终调用它)・configtest.sh:配置文件检测脚本・version.sh:版本查看脚本
conf Configuration 存放 Tomcat核心配置文件,是 Tomcat 配置的核心目录,关键文件:・server.xml:全局核心配置(端口、连接器、引擎、虚拟主机)・context.xml:全局应用上下文配置・web.xml:全局 WEB 应用配置・tomcat-users.xml:用户权限配置(管理后台)・catalina/:Catalina 容器配置目录
lib Library 存放 Tomcat 运行所需的所有 Java 类库(jar 包) ,包括 Servlet、JSP 核心包、第三方依赖包;注意:放入此目录的 jar 包对所有部署在 Tomcat 上的应用生效
logs Logs 存放 Tomcat所有日志文件 ,关键日志:・catalina.out:Tomcat 核心运行日志(包含启动日志、运行异常日志)• localhost.log:本地主机访问日志・localhost_access_log.*.txt:访问日志(记录所有 HTTP 请求)・manager.log/host-manager.log:管理后台日志
webapps Web Applications Tomcat 的应用部署默认目录,相当于 Nginx 的 root 目录;・将 Java WEB 项目的 war 包或解压后的目录放入此目录,Tomcat 会自动部署;・内置默认应用:ROOT(默认首页)、manager(管理后台)、host-manager(虚拟主机管理)
temp Temporary 存放 Tomcat 运行过程中产生的临时文件,由 JVM 自动创建和清理,可手动删除
work Workspace 存放 Tomcat 对JSP 编译后的 class 文件 (JSP 最终会被编译为 Servlet 执行);优化建议:生产环境提前预热访问,让 JSP 提前编译,避免首次访问卡顿;删除此目录,Tomcat 重启后会重新编译 JSP

四、结合反向代理实现 Tomcat 部署

Tomcat 的standalone(单机独立运行)模式 存在明显缺陷:静态资源处理性能低、并发能力有限、易单点故障,因此生产环境不推荐单独使用 Tomcat ,主流方案是结合 Nginx/Apache 做反向代理,实现 "静态资源由代理服务器处理,动态请求由 Tomcat 处理" 的分工,同时可实现 Tomcat 集群负载均衡。

4.1 Tomcat 常见部署方式

根据业务规模和并发需求,Tomcat 部署方式分为 4 种,复杂度由低到高,适用于不同场景:

(1)Standalone Tomcat(单机独立运行)
  • 架构:Tomcat 直接暴露给用户,接收所有 HTTP 请求,同时处理静态资源和动态请求;
  • 优点:架构简单,无额外依赖;
  • 缺点:静态资源处理性能低、并发能力有限、单点故障;
  • 适用场景:开发环境、测试环境,生产环境绝对不推荐。
(2)单机反向代理部署
  • 架构:代理服务器(Nginx/Apache)+ 单台 Tomcat,代理服务器作为前端,接收所有请求;
  • 分工:静态资源(HTML、CSS、JS、图片) 由代理服务器直接响应,动态请求(JSP、Servlet) 通过反向代理转发至 Tomcat 处理;
  • 主流组合:・LNMT :Linux + Nginx + MySQL + Tomcat(企业主流,Nginx 静态处理性能远高于 Apache);・LAMT:Linux + Apache + Httpd + MySQL + Tomcat;
  • 优点:提升静态资源处理性能,降低 Tomcat 负载;
  • 缺点:Tomcat 单点故障,仍无法支撑高并发;
  • 适用场景:中小型企业,低并发业务场景。
(3)多机反向代理部署
  • 架构:Nginx(负载均衡)+ 多台 Tomcat 集群,Nginx 作为前端反向代理和负载均衡器,将动态请求分发至多台 Tomcat;
  • 核心优势:解决单点故障,提升并发处理能力,可水平扩展 Tomcat 节点;
  • 适用场景:中大型互联网企业,中高并发业务场景(如电商、社交、资讯)。
(4)多机多级反向代理部署
  • 架构:多层 Nginx + Tomcat 集群,第一层 Nginx 做入口代理,第二层 Nginx 做负载均衡,分发至 Tomcat 集群;
  • 核心优势:架构更灵活,可实现地域级、机房级的负载均衡,提升架构的高可用性和扩展性;
  • 主流组合:LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat;
  • 适用场景:大型互联网企业,高并发、高可用要求的核心业务(如秒杀、双十一、全国性平台)。

4.2 Nginx 单机反向代理 Tomcat(实操配置)

核心原理:通过 Nginx 的proxy_pass指令,将JSP 动态请求 转发至 Tomcat,静态资源由 Nginx 本地直接响应,实现动静分离。

前提条件
  1. Linux 服务器已安装 Nginx(参考 Nginx 官方安装文档);
  2. Tomcat 已启动,监听 8080 端口,可正常访问;
  3. 配置 Nginx 的域名解析(如lee.timinglee.org),或直接使用 IP 访问。
配置步骤
复制代码
# 1. 进入Nginx的虚拟主机配置目录(企业主流配置方式,避免修改主配置文件)
[root@Nginx ~]# cd /usr/local/nginx/conf.d/

# 2. 创建/编辑虚拟主机配置文件(vhosts.conf,名称自定义)
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

# 3. 写入配置内容,实现动静分离和反向代理
server {
    listen 80;  # 监听80端口
    server_name lee.timinglee.org;  # 域名/服务器IP

    # 静态资源根目录(存放HTML、CSS、JS、图片等)
    root /webdata/nginx/timinglee.org/lee;
    index index.html index.htm;

    # 访问日志和错误日志
    access_log /var/log/nginx/lee_access.log main;
    error_log /var/log/nginx/lee_error.log warn;

    # 动态JSP请求,转发至Tomcat
    location ~ \.jsp$ {
        proxy_pass http://172.25.254.10:8080;  # Tomcat的IP+端口
        # 反向代理优化配置(推荐添加)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 60;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
    }
}

# 4. 检测Nginx配置文件语法是否正确
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -t
# 显示"nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful"即为正确

# 5. 重新加载Nginx配置,使配置生效(无需重启,不中断服务)
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -s reload
测试验证
  1. 在 Nginx 的静态资源根目录/webdata/nginx/timinglee.org/lee放入静态 HTML 文件,访问http://lee.timinglee.org,验证静态资源由 Nginx 响应;
  2. 在 Tomcat 的 webapps 目录部署 JSP 项目,访问http://lee.timinglee.org/test.jsp,验证 JSP 请求被转发至 Tomcat 处理,实现动静分离。

4.3 Tomcat 负载均衡实现(Nginx + 多 Tomcat,实操配置)

当单台 Tomcat 无法支撑高并发时,需部署Tomcat 集群 ,通过 Nginx 实现负载均衡,将请求分发至多台 Tomcat,提升并发能力和高可用性。

4.3.1 核心问题:HTTP 无状态与 Session 一致性

负载均衡的核心痛点是Session 一致性问题 ,根源在于HTTP 协议的无状态性

(1)HTTP 协议的三大特性
  1. 无状态 :服务器无法识别两次 HTTP 请求的关联,即使来自同一浏览器,服务器也视为独立请求;为解决此问题,诞生了Cookie+Session 机制
    • 浏览器第一次请求时,服务器生成SessionID(随机唯一值),创建 Session 对象存储用户信息;
    • 服务器将 SessionID 通过 Cookie 返回给浏览器,浏览器保存在本地;
    • 后续请求时,浏览器携带 SessionID,服务器通过 SessionID 找到对应的 Session 对象,实现用户状态保持。
    • 注意:Session 默认存储在服务器内存中,未持久化时易丢失,且有过期时间(默认 30 分钟);关闭浏览器、更换浏览器会丢失 SessionID,需重新生成。
  2. 有连接 :HTTP 基于TCP 协议 ,是面向连接的协议,需通过三次握手 建立连接,四次挥手断开连接。
  3. 短连接(HTTP1.1 之前) :一请求一连接,TCP 连接创建和销毁的成本高,服务器压力大;HTTP1.1 引入keep-alive(长连接),默认开启,一个 TCP 连接可处理多个 HTTP 请求,保持一段时间后断开,大幅降低服务器压力。
(2)负载均衡的 Session 问题

Nginx 将请求调度至不同的 Tomcat 节点 时,由于 Session 存储在单个 Tomcat 的内存中,其他 Tomcat 节点无此 SessionID,导致会话失效(如用户登录后,再次请求被调度至其他 Tomcat,需重新登录)。

(3)Session 问题的临时解决方案

Nginx 提供两种调度算法,可临时解决 Session 一致性问题:

  1. ip_hash :基于客户端 IP 地址 进行哈希计算,将同一 IP 的所有请求固定调度至同一台 Tomcat ,实现 Session 保持;
    • 优点:配置简单,无需修改 Tomcat;
    • 缺点:若 Tomcat 节点故障,该 IP 的用户 Session 丢失;且同一局域网的用户(同一公网 IP)会被调度至同一 Tomcat,导致负载不均。
  2. hash $cookie_JSESSIONID :基于浏览器的 SessionID 进行哈希计算,将同一 SessionID 的请求固定调度至同一台 Tomcat;
    • 优点:比 ip_hash 更精准,负载更均衡;
    • 缺点:若 Tomcat 节点故障,Session 仍会丢失。

注意 :以上两种方法为临时解决方案 ,生产环境需使用Session 共享技术(如 Memcached、Redis)实现持久化,从根本上解决 Session 一致性问题。

4.3.2 Nginx 配置 Tomcat 负载均衡(实操)

核心指令:upstream ,定义 Tomcat 集群节点,通过调度算法实现负载均衡;再通过proxy_pass将请求转发至 upstream 定义的集群。

配置步骤
复制代码
# 1. 编辑Nginx虚拟主机配置文件
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

# 2. 写入配置内容,定义Tomcat集群并实现负载均衡
# 第一步:定义Tomcat集群,命名为tomcat(自定义)
upstream tomcat {
    # 调度算法:ip_hash 或 hash $cookie_JSESSIONID(二选一)
    # ip_hash;
    hash $cookie_JSESSIONID;

    # Tomcat集群节点,格式:server IP:端口;
    server 172.25.254.10:8080;  # Tomcat1
    server 172.25.254.20:8080;  # Tomcat2
    # 可添加更多节点,支持权重配置:server 172.25.254.30:8080 weight=2;(权重2,调度概率更高)
}

# 第二步:配置服务器,将动态请求转发至Tomcat集群
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    try_files $uri $uri.html $uri/index.html /error/default.html;

    # 动态JSP请求转发至Tomcat集群
    location ~ \.jsp$ {
        proxy_pass http://tomcat;  # 指向upstream定义的集群名称
        # 反向代理优化配置(必须添加)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# 3. 检测配置语法,重新加载Nginx
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -t
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -s reload
测试验证
  1. 启动所有 Tomcat 节点,确保均可正常访问;
  2. 浏览器访问http://lee.timinglee.org/test.jsp,多次刷新,查看 Nginx 的访问日志,验证请求被分发至不同 Tomcat(若未用 ip_hash/hash);
  3. 登录测试,验证 Session 是否保持(若使用 ip_hash/hash,登录后多次请求不会重新登录)。

五、Memcached 核心详解(Tomcat Session 共享基础)

为从根本上解决 Tomcat 集群的 Session 一致性问题,需使用分布式缓存 将 Session 持久化,Memcached是轻量级分布式内存缓存系统,是 Tomcat Session 共享的主流选择之一。

5.1 Memcached 基础认知

(1)官方定义

Memcached 是免费、开源、基于 Key-Value 的分布式内存缓存系统,由 Danga Interactive 开发,核心作用是将热点数据缓存至内存,提升数据读取速度,降低数据库压力。

(2)核心特性
  1. 纯内存存储:数据全部存储在内存中,读取速度极快(毫秒级),无磁盘 IO 开销;
  2. 无持久化能力 :不支持 RDB、AOF 等持久化方式,服务器重启后数据丢失;可通过集群同步实现数据一致性,避免单点丢失;
  3. 支持序列化 :仅能存储可序列化的数据类型(如字符串、对象、数组),非序列化数据无法存储;
  4. 内存限制 :单个存储对象的最大大小为 1M ,超过 1M 的数据可通过客户端压缩拆分为多个 Key 存储;
  5. 高性能 IO :基于libevent 库实现高效的 IO 多路复用,libevent 封装了 Linux 的 epoll、BSD 的 kqueue 等底层事件处理接口,即使高连接数下仍能保持高性能;
  6. 跨平台、跨语言:支持 Linux、BSD、Solaris 等操作系统,支持 Java、C、Python、PHP、C# 等几乎所有开发语言;
  7. 简单的内存管理 :存储数据时,自动申请1MB 的内存块 ,称为slab(页),按 slab 管理内存,避免内存碎片。
(3)核心适用场景
  1. 热点数据缓存:将数据库的热点查询结果缓存至 Memcached,降低数据库压力;
  2. Tomcat Session 共享 :将 Tomcat 的 Session 对象缓存至 Memcached 集群,实现多 Tomcat 节点的 Session 一致性(最核心场景);
  3. 计数器缓存:如商品浏览量、点赞数、访问量等高频更新的计数器。
(4)与 Redis 的核心区别(简版)
特性 Memcached Redis
持久化 不支持 支持 RDB、AOF、混合持久化
数据类型 仅 Key-Value 字符串 支持 String、List、Hash、Set 等多种类型
单个对象大小 最大 1M 最大 512M
内存管理 预分配 slab,简单高效 动态分配,支持内存淘汰策略
集群能力 原生集群同步,简单 支持主从、哨兵、集群(Redis Cluster)
适用场景 简单缓存、Session 共享 复杂缓存、分布式锁、消息队列、持久化存储
(5)官方资源

5.2 Memcached 安装与启动(Linux CentOS 为例)

Memcached 可通过 yum 快速安装,配置简单,默认端口11211

步骤 1:安装 Memcached
复制代码
# 1. 通过yum安装Memcached(开源免费,官方源已收录)
[root@tomcat ~]# yum install memcached -y

# 2. 查看Memcached版本,确认安装成功
[root@tomcat ~]# memcached -V
步骤 2:配置 Memcached

Memcached 的配置文件为/etc/sysconfig/memcached,可配置端口、运行用户、最大连接数、缓存大小等核心参数。

复制代码
# 编辑配置文件
[root@tomcat ~]# vim /etc/sysconfig/memcached

# 核心配置参数,按需修改(默认配置即可满足大部分场景)
PORT="11211"        # 监听端口,默认11211
USER="memcached"    # 运行用户,默认memcached
MAXCONN="1024"      # 最大并发连接数,默认1024
CACHESIZE="64"      # 缓存大小,单位MB,默认64MB(根据服务器内存调整)
OPTIONS="-l 0.0.0.0,::1"  # 监听地址,0.0.0.0表示监听所有IP,支持IPv4和IPv6
步骤 3:启动 Memcached 并设置开机自启
复制代码
# 1. 启动Memcached服务
[root@tomcat ~]# systemctl start memcached

# 2. 设置开机自启
[root@tomcat ~]# systemctl enable --now memcached

# 3. 验证服务状态
[root@tomcat ~]# systemctl status memcached
# 显示active (running)即为成功

# 4. 查看端口监听,确认Memcached正常运行
[root@tomcat ~]# netstat -antlupe | grep memcache
# 预期输出:tcp 0 0 0.0.0.0:11211 :::* LISTEN 980 97815 34711/memcached

5.3 Memcached 基本操作命令

Memcached 提供简单的命令行操作,可通过telnetnc 连接 Memcached 服务(默认端口 11211),核心命令共 5 个:set、add、replace、get、delete,涵盖增删改查核心操作。

步骤 1:连接 Memcached
复制代码
[root@tomcat ~]# telnet localhost 11211
# 成功连接后输出:Trying ::1... Connected to localhost. Escape character is '^]'.
步骤 2:核心命令语法与示例
(1)通用语法(set/add/replace)
复制代码
command <key> <flags> <expiration time> <bytes>
<value>
  • command:操作命令(set/add/replace);
  • key:缓存的键,唯一标识,字符串类型;
  • flags:整型参数,0 表示不压缩,用于存储键值对的额外信息;
  • expiration time:过期时间,单位秒,0 表示永久有效;
  • bytes :存储值的字节数,必须与实际值的字节数一致;
  • value:存储的值,必须在第二行输入,与 bytes 字节数匹配。
(2)具体命令示例
复制代码
# 1. add:添加键值对,键不存在时成功,存在则失败(新增)
add leekey 0 60 4  # 键:leekey,不压缩,60秒过期,值4字节
test               # 值:test(4字节)
# 成功输出:STORED;失败输出:NOT_STORED

# 2. get:查询键值对,支持多键查询(get key1 key2)
get leekey
# 成功输出:VALUE leekey 0 4 \n test \n END;失败输出:END

# 3. set:设置键值对,键存在则修改,不存在则新增(新增/修改)
set leekey 0 60 5  # 键:leekey,5字节
test1              # 值:test1
# 成功输出:STORED

# 4. replace:替换键值对,键存在则成功,不存在则失败(修改)
replace leekey1 0 60 3
lee
# 成功输出:STORED

# 5. delete:删除键值对
delete leekey
# 成功输出:DELETED;失败输出:NOT_FOUND

# 6. flush_all:清空所有缓存(谨慎使用,生产环境禁止)
flush_all
# 成功输出:OK

# 7. 退出连接:按Ctrl+],再输入quit
^]
quit

六、Tomcat Session 共享实现(Memcached+MSM,生产环境方案)

通过MSM(Memcached Session Manager) 实现 Tomcat Session 的分布式共享 ,将 Tomcat 的 Session 对象序列化后存储至Memcached 集群,所有 Tomcat 节点从 Memcached 读取和写入 Session,从根本上解决 Session 一致性问题,实现高可用。

6.1 MSM 核心认知

(1)MSM 定义

MSM(Memcached Session Manager)是 Tomcat 的Session 管理插件,专门用于将 Tomcat 的 Session 存储至 Memcached,实现多 Tomcat 节点的 Session 共享和高可用。

(2)核心特性
  1. 支持Tomcat 6.x/7.x/8.x/9.x(覆盖企业主流版本);
  2. 支持Session 序列化 / 反序列化 ,官方推荐Kryo 序列化框架(高效、轻量,比 Java 原生序列化性能更高);
  3. 支持Session 备份,可将 Session 同步至多个 Memcached 节点,实现故障转移;
  4. 支持静态资源忽略,不缓存静态资源的 Session 请求,提升性能;
  5. 开源免费,项目早期托管在 Google Code,目前托管在Github
(3)项目地址
(4)核心依赖包

MSM 运行需要三类 jar 包,需放入 Tomcat 的lib目录($CATALINA_HOME/lib/,即 /usr/local/tomcat/lib/),所有 Tomcat 节点都需放入相同的 jar 包:

  1. MSM 核心包:memcached-session-manager-2.3.2.jar、memcached-session-manager-tc9-2.3.2.jar(tc9 对应 Tomcat9,tc8 对应 Tomcat8,依版本调整);
  2. Kryo 序列化包:kryo-3.0.3.jar、asm-5.2.jar、objenesis-2.6.jar、reflectasm-1.11.9.jar、minlog-1.3.1.jar、kryo-serializers-0.45.jar、msm-kryo-serializer-2.3.2.jar;
  3. Memcached 驱动包:spymemcached-2.12.3.jar(Java 操作 Memcached 的官方驱动)。

6.2 MSM 安装(核心:放入依赖 jar 包)

步骤 1:下载核心 jar 包

从 MSM 官方 Github 仓库或 Maven 中央仓库(https://mvnrepository.com/)下载上述所有 jar 包,确保版本匹配(推荐 2.3.2 版本,稳定)。

步骤 2:放入 Tomcat 的 lib 目录

将所有下载的 jar 包上传至每台 Tomcat/usr/local/tomcat/lib/目录,确保所有 Tomcat 节点的 jar 包一致,无缺失。

复制代码
# 示例:将jar包放入Tomcat lib目录
[root@tomcat-1 ~]# cp *.jar /usr/local/tomcat/lib/
[root@tomcat-2 ~]# cp *.jar /usr/local/tomcat/lib/

# 赋予权限(可选,避免权限不足)
[root@tomcat-1 ~]# chmod 644 /usr/local/tomcat/lib/*.jar

6.3 Tomcat+MSM+Memcached 配置(实操)

核心配置分为两部分:Tomcat 配置(context.xml) (指定 Memcached 集群、序列化方式)和Nginx 配置(调整调度算法),所有 Tomcat 节点需单独配置,Nginx 仅需一次配置。

前提条件
  1. 已部署Tomcat 集群(如 2 台:172.25.254.10、172.25.254.20);
  2. 已部署Memcached 集群(如 2 台:172.25.254.10:11211、172.25.254.20:11211);
  3. 所有 Tomcat 节点已放入 MSM 核心 jar 包;
  4. Nginx 已配置 Tomcat 负载均衡。
步骤 1:配置 Tomcat(context.xml)

修改 Tomcat 的核心配置文件/usr/local/tomcat/conf/context.xml,添加 MSM 的 Session 管理器配置,两台 Tomcat 配置仅failoverNodes参数不同(用于 Session 故障转移)。

(1)Tomcat1 配置(172.25.254.10)
复制代码
[root@tomcat-1 ~]# vim /usr/local/tomcat/conf/context.xml
<!-- 清空原有默认Manager节点,添加以下配置 -->
<Manager 
    className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    <!-- Memcached集群地址(多个节点用空格分隔) -->
    memcachedNodes="n1:172.25.254.10:11211 n2:172.25.254.20:11211"
    <!-- 故障转移节点:当前节点故障时,Session切换至n2(Tomcat2) -->
    failoverNodes="n2"
    <!-- 序列化方式:推荐kryo(高性能) -->
    sessionBackupAsync="false"
    sessionBackupTimeout="100"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    <!-- 忽略静态资源的Session请求,提升性能 -->
    ignorePattern=".*\.(png|gif|jpg|css|js)$"
    <!-- Session过期时间(秒),与Tomcat默认一致为1800秒(30分钟) -->
    maxInactiveInterval="1800"
    <!-- 连接Memcached超时时间(毫秒) -->
    operationTimeout="1000"
/>
(2)Tomcat2 配置(172.25.254.20)
复制代码
[root@tomcat-2 ~]# vim /usr/local/tomcat/conf/context.xml
<!-- 核心区别:failoverNodes指向n1(Tomcat1) -->
<Manager 
    className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="n1:172.25.254.10:11211 n2:172.25.254.20:11211"
    failoverNodes="n1"  <!-- 当前节点故障时,Session切换至n1 -->
    sessionBackupAsync="false"
    sessionBackupTimeout="100"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    ignorePattern=".*\.(png|gif|jpg|css|js)$"
    maxInactiveInterval="1800"
    operationTimeout="1000"
/>
关键参数说明
参数名 作用 生产环境建议值
memcachedNodes 定义 Memcached 集群节点,格式:节点名:IP:端口 多个节点用空格分隔,至少 2 个实现高可用
failoverNodes 故障转移节点,当前 Tomcat 故障时 Session 切换至该节点 指向集群中另一台 Tomcat 对应的 Memcached 节点
sessionBackupAsync 是否异步备份 Session false(同步更可靠,避免 Session 丢失)
transcoderFactoryClass Session 序列化方式 kryo(性能比 Java 原生高 3-5 倍)
ignorePattern 忽略静态资源的 Session 请求 包含所有静态资源后缀(png/gif/css/js 等)
maxInactiveInterval Session 过期时间 1800 秒(30 分钟),与业务需求匹配
重启 Tomcat 使配置生效
复制代码
# Tomcat1重启
[root@tomcat-1 ~]# systemctl restart tomcat
# Tomcat2重启
[root@tomcat-2 ~]# systemctl restart tomcat

# 验证Tomcat启动状态(无报错则配置生效)
[root@tomcat-1 ~]# systemctl status tomcat
[root@tomcat-2 ~]# systemctl status tomcat
步骤 2:调整 Nginx 配置(移除 IP 绑定,实现真正负载均衡)

由于 Session 已存储在 Memcached 集群,无需再用ip_hashcookie_JSESSIONID绑定 IP,可使用 Nginx 默认的轮询算法(或加权轮询),实现请求均匀分发。

复制代码
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
# 修改upstream配置,移除ip_hash/hash指令
upstream tomcat {
    # 轮询算法(默认),也可添加weight调整权重(如weight=2)
    server 172.25.254.10:8080;  # Tomcat1
    server 172.25.254.20:8080;  # Tomcat2
    # 可选:添加down(节点下线)、backup(备用节点)参数
    # server 172.25.254.30:8080 backup;
}

server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # 动态请求转发至Tomcat集群
    location ~ \.jsp$ {
        proxy_pass http://tomcat;
        # 必须保留的反向代理头信息(传递真实IP、Host)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

# 检测配置语法并重新加载
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -t
[root@Nginx ~]# /usr/local/nginx/sbin/nginx -s reload
步骤 3:验证 Session 共享(生产环境标准验证方法)
(1)编写测试 JSP 页面(所有 Tomcat 节点部署)

在 Tomcat 的webapps/ROOT目录创建session_test.jsp,用于展示当前 Tomcat 节点 IP 和 SessionID:

复制代码
[root@tomcat-1 ~]# vim /usr/local/tomcat/webapps/ROOT/session_test.jsp
[root@tomcat-2 ~]# vim /usr/local/tomcat/webapps/ROOT/session_test.jsp

<!-- 测试页面内容 -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <title>Tomcat Session共享测试</title>
</head>
<body>
    <h1>Session共享测试结果</h1>
    <p>当前Tomcat节点IP:<%= request.getLocalAddr() %></p>
    <p>当前Tomcat端口:<%= request.getLocalPort() %></p>
    <p>SessionID:<%= session.getId() %></p>
    <p>Session创建时间:<%= new java.util.Date(session.getCreationTime()) %></p>
    <p>Session最后访问时间:<%= new java.util.Date(session.getLastAccessedTime()) %></p>
</body>
</html>
(2)访问测试页面验证
  1. 浏览器访问 http://lee.timinglee.org/session_test.jsp,记录 SessionID 和当前 Tomcat 节点 IP;
  2. 多次刷新页面,观察 Tomcat 节点 IP 会在 172.25.254.10 和 172.25.254.20 之间切换,但SessionID 始终不变
  3. 手动停止其中一台 Tomcat(如 Tomcat1),继续访问页面,请求会自动切换至 Tomcat2,SessionID 仍不变,证明 Session 共享生效。
(3)Memcached 中验证 Session 存储
复制代码
# 连接Memcached集群,查询Session数据
[root@memcached-1 ~]# telnet 172.25.254.10 11211
Trying 172.25.254.10...
Connected to 172.25.254.10.
Escape character is '^]'.

# 查询所有Session键(以"tomcat_"开头)
stats items  # 查看缓存项统计
stats cachedump 1 0  # 列出缓存键(1为slab编号,0为列出所有)
# 输出中会看到类似"tomcat_xxxxxx"的Session键,证明Session已存储至Memcached

# 退出连接
^]
quit
步骤 4:常见问题排查
问题现象 可能原因 解决方案
Tomcat 启动报错:ClassNotFound MSM 缺少 MSM 核心 jar 包 检查 Tomcat/lib 目录,确保所有 MSM、Kryo、spymemcached jar 包齐全
SessionID 刷新后变化 Memcached 连接失败 检查 Memcached 集群是否启动,Tomcat 配置的 memcachedNodes IP / 端口是否正确
静态资源加载异常 ignorePattern 配置错误 核对静态资源后缀是否完整,格式为 `.*.(png gif jpg css js)$`
故障转移不生效 failoverNodes 配置错误 确保 Tomcat1 的 failoverNodes 是 n2,To
相关推荐
礼拜天没时间.3 小时前
Docker Registry私有仓库搭建与使用
java·运维·docker·云原生·容器·centos
tritone4 小时前
初探云原生:在阿贝云免费服务器上学习负载均衡的实践心得
服务器·学习·云原生
nix.gnehc4 小时前
零基础部署K8s单节点集群:一键脚本实现快速落地
云原生·容器·kubernetes
hrhcode4 小时前
【云原生】四.Kubernetes核心对象(下):Deployment、Service与Namespace
云原生·k8s
百锦再4 小时前
Java ForkJoin 框架全面解析:分而治之的并行编程艺术
java·开发语言·spring boot·spring cloud·kafka·tomcat·maven
王德印4 小时前
工作踩坑之导入数据库报错:Got a packet bigger than ‘max_allowed_packet‘ bytes
java·数据库·后端·mysql·云原生·运维开发
AI_56785 小时前
ableau可视化进阶:颜色与交互设计让数据会说话
数据库·云原生·excel
弹简特6 小时前
【JavaEE09-后端部分】SpringMVC04-SpringMVC第三大核心-处理响应和@RequestMapping详解
java·spring boot·spring·java-ee·tomcat
认真的薛薛6 小时前
5.k8s的deploy-ds-nfs-loadbalancer
云原生·容器·kubernetes