文章目录
- 1. Web技术
-
- 1.1 核心概念
- 1.2 静、动态网页
- 1.3 同步、异步
- 2 Web架构
-
- 2.1 单体架构(Monolithic)
- 2.2 微服务架构(Microservices)
- 2.3 常见Web服务器/容器
- 3 Tomcat
-
- 3.1 定位
- 3.2 核心功能
- 3.3 核心组件
- 3.4 目录结构
- 4 反向代理与负载均衡
-
- 4.1 部署方式演进
- 4.2 LNMT/LAMT架构对比
- 4.3 Session问题详解
- 5 Memcached缓存
-
- 5.1 简介
- 5.2 与Redis对比
- 5.3 基本命令详解
- 6 Session共享方案(MSM)
-
- 6.1 背景
- 6.2 所需Jar包
- 6.3 工作原理
-
- Sticky模式(粘性会话,推荐)
- Non-Sticky模式(非粘性)
- 序列化过程
- 故障恢复机制
- 7 实践
1. Web技术
1.1 核心概念
| B/S架构 | Browser/Server,浏览器/服务器模式。客户端只需浏览器,业务逻辑集中在服务器,维护成本低,但受网络影响大 |
| C/S架构 | Client/Server,客户端/服务器模式(如QQ、迅雷、游戏客户端)。需安装专用软件,性能好、功能强,但升级维护麻烦 |
| HTTP协议 | HyperText Transfer Protocol,应用层文本传输协议,1990年由Tim Berners-Lee发明,默认端口80,HTTPS为443 |
| 动态网页 | 服务端根据请求动态生成HTML。演进:CGI(通用网关接口)→ ASP/PHP/JSP(脚本嵌入HTML)→ 现代MVC框架 |
1.2 静、动态网页
| 内容生成 | 预存HTML文件 | 服务器实时生成 |
| 交互性 | 无 | 支持用户交互、数据库操作 |
| 扩展名 | .html/.htm | .php/.jsp/.asp/.py等 |
| 性能 | 加载快,适合CDN | 需服务器处理,相对较慢 |
| 适用场景 | 企业官网、文档 | 电商、社交、管理系统 |
1.3 同步、异步
| 同步 | 请求后整个页面刷新,用户体验差,服务器压力大 | 传统form提交、超链接跳转 |
| 异步(Ajax) | 局部更新,不刷新整个页面,提升用户体验和性能 | XMLHttpRequest、Fetch API、Axios |
Ajax工作流程:JavaScript发起异步请求 → 服务器返回数据(JSON/XML)→ JavaScript更新DOM局部内容
2 Web架构
2.1 单体架构(Monolithic)
- 定义:所有功能模块打包在一个应用中,统一部署运行
- 优点:
- 易于开发测试:单一代码库,调试方便
- 部署简单:一个WAR/JAR包直接部署
- 扩展方便:水平复制(多实例部署)
- 事务处理简单:本地事务即可保证一致性
- 缺点:
- 耦合度高:模块间边界模糊,代码纠缠
- 全站风险:任一模块故障影响整个系统
- 技术栈锁定:难以引入新技术
- 不适合快速迭代:小改动需全量部署
- 团队协作难:大量开发者冲突频繁
2.2 微服务架构(Microservices)
- 核心思想:按业务领域拆分成独立服务,一个服务只做一件事(单一职责原则)
- 服务特征:
- 独立部署、独立扩展
- 拥有自己的数据库(Database per Service)
- 轻量级通信机制
- 通信方式:HTTP RESTful API、消息队列(RabbitMQ/Kafka)、gRPC
- 基础设施:服务注册发现(Eureka/Nacos)、配置中心、网关(Gateway)、熔断限流(Hystrix/Sentinel)
- 优点:
- 松耦合:服务间通过接口通信
- 独立部署:单个服务升级不影响全局
- 小团队开发:2 Pizza Team(亚马逊原则)
- 技术栈灵活:不同服务可用不同语言/框架
- 故障隔离:单点故障不会拖垮整体
- 缺点:
- 分布式复杂性:网络延迟、超时、重试
- 数据一致性挑战:分布式事务(Saga、TCC模式)
- 运维成本高:监控、日志、链路追踪
- 测试复杂:集成测试需协调多服务
2.3 常见Web服务器/容器
| 开源 | Tomcat | Apache开源,Servlet/JSP容器,轻量 |
| Jetty | Eclipse开源,嵌入式场景,轻量快速 | |
| GlassFish | Oracle开源,Java EE完整实现 | |
| Undertow | JBoss开源,基于NIO,性能高 | |
| 商用 | WebLogic | Oracle,企业级,功能全面,收费 |
| WebSphere | IBM,大型金融电信首选,收费 | |
| JBoss EAP | RedHat,开源+商业支持 |
3 Tomcat
3.1 定位
- 官方定义:Apache Tomcat是开源的Servlet容器(Servlet Container),实现了Java EE(现Jakarta EE)中的Servlet、JSP、WebSocket等规范
- 与Web服务器区别:
- Web服务器(如Nginx、Apache Httpd):处理静态资源、反向代理、负载均衡
- Servlet容器(如Tomcat):运行Java Web应用,处理动态请求
- 双重角色:既是Servlet容器,也可作为轻量级Web服务器使用(支持静态资源,但性能不如Nginx)
3.2 核心功能
| Servlet生命周期管理 | 加载、初始化、调用service()、销毁Servlet实例 |
| 请求处理 | 监听端口(默认8080),解析HTTP请求,分发给对应Servlet |
| JSP编译执行 | 将JSP翻译为Servlet源码,编译为class并执行 |
| 会话管理 | Session创建、维护、持久化(支持Cookie/URL重写) |
| 连接器架构 | Coyote(HTTP连接器)+ Catalina(Servlet容器) |
| 多协议支持 | HTTP/1.1、AJP(Apache JServ Protocol,与Apache Httpd集成) |
3.3 核心组件
- Catalina:Servlet容器核心,实现Servlet规范
- Coyote:HTTP连接器,处理网络连接、解析HTTP协议
- Jasper:JSP引擎,负责JSP编译
- Cluster:集群组件,支持Session复制
- Realm:安全域,提供用户认证授权
3.4 目录结构
$CATALINA_HOME/
├── bin/ # 启动/关闭脚本(startup.sh/shutdown.sh)
├── conf/ # 配置文件(server.xml、web.xml)
├── lib/ # 公共类库(Servlet API、JDBC驱动等)
├── logs/ # 日志文件
├── webapps/ # 部署目录(WAR包自动解压)
├── work/ # JSP编译后的Servlet源码和class
└── temp/ # 临时文件
4 反向代理与负载均衡
4.1 部署方式演进
| Standalone | Tomcat单独运行 | 开发测试环境 | 直接暴露Tomcat,性能差、不安全,生产不推荐 |
| 单机反向代理 | Nginx→Tomcat | 中小型应用 | Nginx处理静态资源(CSS/JS/图片),动态请求转发Tomcat,动静分离 |
| 反向代理多机 | Nginx→多Tomcat | 高并发生产环境 | 负载均衡(轮询/权重/IP哈希),Tomcat水平扩展 |
| 多级代理 | Nginx→Nginx→Tomcat | 超大规模/多机房 | LVS/Nginx做四层负载,Nginx做七层负载,Tomcat集群 |
4.2 LNMT/LAMT架构对比
| LNMT | Linux + Nginx + MySQL + Tomcat | 性能高、并发强、配置简洁、资源占用低,现代主流选择 |
| LAMT | Linux + Apache(Httpd) + MySQL + Tomcat | Apache模块丰富、.htaccess灵活、与PHP集成好,传统LAMP变种 |
Nginx vs Apache Httpd:
- Nginx:异步非阻塞事件驱动,高并发低内存,适合反向代理
- Apache:进程/线程模型,模块多、功能全,适合复杂业务逻辑
4.3 Session问题详解
- HTTP无状态本质:每个请求独立,服务器不保存客户端上下文
- Session机制:
- 首次请求:服务器创建Session对象,生成唯一SessionID
- 响应头:Set-Cookie: JSESSIONID=xxx
- 后续请求:浏览器自动携带Cookie,服务器通过ID找到Session
- 负载均衡下的Session问题:
- 请求1→Tomcat A(创建Session)
- 请求2→Tomcat B(无此SessionID,重新创建→用户登录状态丢失)
- 解决方案:
- Session复制(Tomcat Cluster):实时同步Session到所有节点,网络开销大
- Session粘滞(IP Hash):固定用户到固定节点,单点故障风险
- Session集中存储(Memcached/Redis):推荐方案,MSM实现
5 Memcached缓存
5.1 简介
- 定位:高性能分布式内存对象缓存系统,LiveJournal团队2003年开发
- 设计哲学:简单、快速、分布式,专注缓存不做持久化
- 核心特点:
- 纯内存操作,读写速度极快(微秒级)
- 基于libevent实现高效事件驱动网络IO
- 分布式:客户端通过一致性哈希选择服务器节点
- 不支持持久化:重启数据丢失,纯缓存用途
- LRU淘汰:内存满时自动淘汰最少使用数据
- 限制:
- 单个对象最大1MB(适合Session、小对象,不适合大文件)
- 仅支持Key-Value(String),无复杂数据结构
- 无认证机制,需部署在内网
5.2 与Redis对比
| 数据结构 | 仅String | String、Hash、List、Set、ZSet等 |
| 持久化 | 不支持 | RDB快照、AOF日志 |
| 集群 | 客户端分片 | Redis Cluster原生支持 |
| 功能 | 简单缓存 | 缓存、消息队列、分布式锁等 |
| 内存管理 | 预分配内存池 | 现场申请内存 |
| 适用场景 | 纯缓存、简单KV | 复杂数据结构、持久化需求 |
5.3 基本命令详解
| set | 设置/更新键值(存在覆盖,不存在创建) | set username 0 3600 5 | STORED/ERROR |
| add | 仅新增(键不存在才添加) | add counter 0 60 1 | STORED/NOT_STORED |
| replace | 仅替换(键存在才更新) | replace config 0 0 10 | STORED/NOT_STORED |
| get | 获取值 | get username | VALUE…END |
| gets | 获取值和CAS令牌(用于乐观锁) | gets username | 含版本号 |
| delete | 删除键 | delete oldkey | DELETED/NOT_FOUND |
| incr/decr | 原子增减(仅数字) | incr counter 1 | 新值/ERROR |
| flush_all | 清空所有数据(危险!) | flush_all | OK |
| stats | 查看统计信息 | stats | 多行状态数据 |
参数格式:command <key> <flags> <exptime> <bytes> [noreply]\\r\\n<value>\\r\\n
- key:键名,最大250字节,不能含空格/控制字符
- flags:16位无符号整数,存储额外标记(如数据类型),客户端自定义
- exptime:过期时间(秒)
- 0 = 永久存储(但受LRU淘汰)
- 30天内:秒数(如3600=1小时)
- Unix时间戳:1970年1月1日以来的秒数
- bytes:数据字节数(不含\\r\\n),必须与value实际长度一致
- noreply:可选,不等待服务器响应(提升性能)
6 Session共享方案(MSM)
6.1 背景
MSM(Memcached Session Manager):开源Tomcat扩展,将Session序列化后存储到Memcached,实现:
- Session共享:多Tomcat实例共享同一Session存储
- 高可用:Memcached集群故障时自动切换节点
- 弹性伸缩:Tomcat实例随意增减,不影响用户会话
6.2 所需Jar包
将以下jar包放入 $CATALINA_HOME/lib/ 目录:
| memcached-session-manager | MSM核心 |
| memcached-session-manager-tc9 | Tomcat 9适配器(根据Tomcat版本选择tc7/tc8/tc9) |
| spymemcached | Memcached Java客户端驱动 |
| kryo | 高性能Java序列化库(替代默认Java序列化) |
| kryo-serializers | Kryo扩展序列化器 |
| minlog | Kryo依赖 |
| objenesis | Kryo依赖(无参构造实例化) |
| asm | 字节码操作库 |
版本匹配:tc9对应Tomcat 9.x,tc8对应Tomcat 8.x,务必匹配
6.3 工作原理
Sticky模式(粘性会话,推荐)
用户请求 → Nginx(IP Hash固定到Tomcat A)→ Tomcat A
↓
Session存储:Memcached Node 1(主)
↓
异步备份到:Memcached Node 2(备)
流程:
Non-Sticky模式(非粘性)
用户请求1 → Tomcat A → 写入Memcached Node 1/2(根据SessionID哈希)
用户请求2 → Tomcat B → 从Memcached读取(可能不同节点)
特点:每个请求都可能到不同Tomcat,每次需从Memcached读取Session,网络开销大,但Tomcat故障无感知
序列化过程
Tomcat Session对象
↓
Kryo序列化(二进制,高效)
↓
压缩(可选Snappy/LZ4)
↓
存储到Memcached(Key=SessionID,Value=序列化数据)
SessionID映射:Memcached的Key = 会话ID + – + Tomcat标识(避免多Tomcat冲突)
故障恢复机制
- Memcached节点故障:自动切换到备份节点,Session不丢失(Sticky模式)
- Tomcat节点故障:Nginx剔除故障节点,请求转到其他Tomcat,从Memcached恢复Session
- 网络分区:依赖Memcached集群自身的高可用(如Repcached双向复制)
7 实践
Tomcat实践
网硕互联帮助中心



评论前必须登录!
注册