TOMCAT笔记
一、前置知识:Web 技术演进
-
C/S vs B/S
– C/S:Socket 编程,QQ、迅雷等,通信层 TCP/UDP,协议私有。
– B/S:浏览器 + HTTP,文本协议跨网络。 -
动态网页诞生
早期静态 HTML → 1990 年 HTTP + 浏览器 → 1995 年 JavaScript → CGI → ASP/PHP/JSP,逻辑搬到服务器,Browser/Server 模式形成。
二、前端三剑客:HTML / CSS / JavaScript
-
HTML:超文本标记语言,标签 + 数据。
-
CSS:层叠样式表,解决 HTML 臃肿,1996 CSS1、1998 CSS2、CSS3 模块化。
-
JavaScript:
– 1995 LiveScript → JavaScript;1997 ECMAScript 标准。
– 2008 Chrome V8 引擎本地编译,2009 Node.js 诞生 → JS 可以写后端。
– Ajax(1999):XMLHttpRequest + JS 实现局部刷新,前后端彻底分离。
三、Web 框架与访问模式
-
资源划分
PC/手机浏览器:
– 静态文件 → 静态服务器
– 图片 → 图片服务器
– 动态内容 → 业务服务器(Tomcat 等)手机 App:
– 静态资源内置包,必要时才访问图片/业务服务器。 -
典型调用链
浏览器 → Nginx(80) → (静态)
→ (动态)Tomcat(8080) → DB
四、后台架构演进
-
单体架构
– 所有功能打包成一个 war;横向扩展复制多份 + 负载均衡。
– 缺点:一处修改全站重启,耦合高。 -
微服务
– 把单体按业务拆成独立服务;独立数据库;HTTP/REST 通信。
– 优点:小团队、独立部署、技术异构。
– 缺点:分布式事务、运维复杂度、监控链路。
– 框架:Dubbo(RPC + ZooKeeper)、Spring Cloud(HTTP REST + Eureka)。
五、Tomcat 全景速览
• 1999 年起源于 Sun JWS → 贡献 Apache → 合并 JServ → 顶级项目。
• 仅实现 Servlet/JSP 规范,不完整 JavaEE。
• 重要版本:3.0(Servlet2.2/JSP1.1) → 4.x(Catalina/Jasper) → 9.x。
• 官方:http://tomcat.apache.org
六、Tomcat 安装
-
安装 JDK
[root]# yum install java-1.8.0-openjdk.x86_64 -y -
解压并做软链
[root]# tar zxf apache-tomcat-9.0.91.tar.gz -C /usr/local/
[root]# ln -s /usr/local/apache-tomcat-9.0.91 /usr/local/tomcat -
启动
[root]# /usr/local/tomcat/bin/startup.sh -
验证端口
[root]# netstat -antlupe | grep java
tcp6 0 0 :::8080 :::* LISTEN 32887/java -
浏览器访问
http://服务器IP:8080 → 出现 Tomcat 欢迎页。
七、目录结构逐目录说明

bin 启动/关闭脚本 (startup.sh shutdown.sh catalina.sh)
conf 配置文件 (server.xml context.xml web.xml tomcat-users.xml)
lib Tomcat 自身以及全局 jar
logs catalina.out、localhost.log、access_log 等
webapps 应用部署目录,/webapps/ROOT 默认首页
work JSP 编译后生成的 servlet 类文件
temp 运行期临时目录
八、systemd 启动脚本制作
-
新建环境变量文件
cat > /usr/local/tomcat/conf/tomcat.conf <<EOF
JAVA_HOME=/etc/alternatives/jre_openjdk
EOF -
新建 systemd unit
cat > /lib/systemd/system/tomcat.service <<'EOF'
[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
EOF -
加载并开机自启
systemctl daemon-reload
systemctl enable --now tomcat
九、结合反向代理部署(Nginx)
-
单机反向代理
location ~ .jsp$ {
proxy_pass http://127.0.0.1:8080;
} -
静态 + 动态分离
server {
root /webdata/nginx/html;
location / { try_files uriuri/ =404; }
location ~ .jsp$ { proxy_pass http://tomcat; }
}
十、负载均衡与会话漂移
-
HTTP 特点
– 无状态:服务器默认记不住两次请求。
– 有连接:基于 TCP,三次握手。
– 短连接:HTTP/1.0 一次请求一次连接;HTTP/1.1 keep-alive 复用。 -
负载均衡配置(Nginx)
upstream tomcat {
ip_hash; # 或 hash $cookie_JSESSIONID;
server 192.168.65.131:8080;
server 192.168.65.132:8080;
} -
问题
ip_hash 会导致:
– 客户端出口 IP 变化 → 漂移;
– 单节点故障 → 会话丢失。
因此需要集中式 Session 存储。
十一、Memcached 缓存系统
-
特点
– 内存 Key-Value,最大 1 MB/对象;
– 支持多语言客户端;
– 基于 libevent,高并发;
– 无持久化,可通过集群同步实现高可用。 -
安装与启动
yum install memcached -y
vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1"
systemctl enable --now memcached
-
常用命令示例(telnet localhost 11211)
add leekey 0 60 4
test
get leekey
set leekey 0 60 5
test1
delete leekey
flush_all
十二、msm(memcached-session-manager)实现 Session 共享
-
原理
– Tomcat 把 Session 序列化后写入 Memcached;
– 多个 Tomcat 共用同一份 Session,故障无丢失;
– 支持 Tomcat 6/7/8/9,官方推荐 Kryo 序列化。 -
所需 jar(全部放到 $CATALINA_HOME/lib)
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
memcached-session-manager-tc9-2.3.2.jar
spymemcached-2.12.3.jar
memcached-session-manager-2.3.2.jar -
context.xml 修改
Tomcat-1:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211" failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />Tomcat-2:
failoverNodes="n2" 其余同上。 -
Nginx 调度器
upstream tomcat {
hash $cookie_JSESSIONID;
server 172.25.254.10:8080;
server 172.25.254.20:8080;
} -
验证步骤
a) 两台 Tomcat + 两台 Memcached 全启动,浏览器登录。
b) 关闭其中一台 Tomcat 或 Memcached,刷新页面 → 会话保持。
模拟132tomcat故障
正常情况下
• 192.168.65.131 上的 Tomcat-A 把 Session 主本 写在对端 192.168.65.132 的 Memcached-n2;
• 192.168.65.132 上的 Tomcat-B 把 Session 主本 写在 131 的 Memcached-n1。
两台 Memcached 各自只保存「对方 Tomcat 的主 Session」,本地 Memcached 并没有这份数据。
关闭 132 的 Tomcat-B(不是 Memcached)
• 浏览器下次请求被 Nginx 调度到 仍在运行的 131 Tomcat-A;
• 131 Tomcat-A 发现本地 Memcached-n1 没有 该 Session,于是根据 msm 机制,从 132 Memcached-n2 读取到原来的主本 Session;
• 131 把这份 Session 重新写回本地 Memcached-n1 作为新的备份,并继续提供服务。
结论(正确表述)
“关闭 192.168.65.132 的 Tomcat 后,192.168.65.131 的 Tomcat 从 192.168.65.132 的 Memcached 成功拉回原 Session,并在本地 Memcached 重新备份,验证会话未丢失。”
如果模拟132memcached故障
-
正常时
192.168.65.131 这台 Tomcat 把 Session 主本保存在 192.168.65.132 的 Memcached(n2)中;
131 本地的 Memcached(n1)并不存放该 Session。 -
关闭 132 的 Memcached 后
131 的 Tomcat 检测到 n2 不可写,立即把同一 Session 改写到本机 n1;
因此后续请求由 131 处理时,能够从本地 n1 读取到刚才新写入的备份 Session,验证数据未丢失。.
结论:
关闭 132 的 Memcached 后,131 的 Tomcat 将 Session 实时转存到本地 Memcached,随后从本地节点成功读取,验证无数据丢失。