提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会
一、Tomcat简介
1.1 什么是tomcat
Tomcat 是Apache软件基金会(Apache Software Foundation)的一个开源 Java Web 中间件,本质上是一个 Servlet 容器,它基于 Java 技术构建,核心作用是
- 作为 Servlet 容器和 JSP 解析器,承载 Java Web 应用的运行
- 接收客户端 HTTP 请求,将动态资源请求(如Servlet、JSP)转发给对应组件处理
- 管理 Servlet 生命周期,解析 JSP 为 Servlet 执行,处理业务逻辑
1.2 为什么要学tomcat
因为市面上Java 在后端开发中占比极高,电商、金融、政企系统等大多用 Java 构建,这些项目都需要中间件承载运行,而tomcat是开源且成熟的 Java Web 中间件,轻量、稳定又易部署,能直接解析运行 Servlet、JSP 等 Java Web 核心组件,是 Java 项目部署的 “标配工具”
二、Tomcat与JDK
Tomcat作为Java Web中间件,完全依赖JDK环境。 没有JDK,Tomcat无法启动;JDK版本需与Tomcat兼容(如高版本Tomcat需匹配高版本JDK),否则会出现运行异常
其中JDK包括:
JVM:Java虚拟机,翻译java程序给cpu识别
JRE:Java运行时环境
Java类库:import,jdbc等各种功能模块
三、Tomcat安装
3.1 安装jdk
安装tomcat前先要准备好jdk环境
JDK官网:https://www.oracle.com/cn/java/technologies/downloads/
#安装jdk
root@tomcat:~# ls
jdk-8u211-linux-x64.tar.gz //我这里下载的时jdk1.8
root@tomcat:~# tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local
root@tomcat:~# ls /usr/local/
bin etc games include jdk1.8.0_211 lib man mysql mysql-8.0.37 sbin share src
root@tomcat:~# mv /usr/local/jdk1.8.0_211/ /usr/local/java
root@tomcat:~# vim /etc/profile //在最后添加上这两行
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
root@tomcat:~#
root@tomcat:~# source /etc/profile
root@tomcat:~# java -version //查看版本
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
3.2 安装tomcat
Tomcat官网:https://tomcat.apache.org/
//安装tomcat
root@tomcat:~# ls //我下载的版本是8.5.45
apache-tomcat-8.5.45.tar.gz jdk-8u211-linux-x64.tar.gz
root@tomcat:~# mkdir -p /data/application
root@tomcat:~# tar xf apache-tomcat-8.5.45.tar.gz -C /data/application/
root@tomcat:~# ls /data/application/
apache-tomcat-8.5.45
root@tomcat:~# mv /data/application/apache-tomcat-8.5.45/ /data/application/tomcat
root@tomcat:~#
root@tomcat:~# /data/application/tomcat/bin/startup.sh //启动tomcat
//tomcat启动后会占用3个端口
//8080 http用的
//8005 负责监听关闭tomcat的请求
//8009 与其他服务通信的端口
root@tomcat:~# netstat -tanlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1714/nginx: master
tcp6 0 0 :::8080 :::* LISTEN 5943/java
tcp6 0 0 :::80 :::* LISTEN 1714/nginx: master
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 5943/java
tcp6 0 0 :::8009 :::* LISTEN 5943/java
访问ip:8080

3.3 tomcat目录介绍
root@tomcat:~# cd /data/application/tomcat/
root@tomcat:/data/application/tomcat# tree -L 1 #相当于ls
.
├── bin //存放tomcat管理脚本,其中startup.sh启动,shutdown.sh停止,version.sh查看tomcat版本,
├── BUILDING.txt
├── conf //配置文件存放目录,其中server.xml尤为重要,里面可以改端口等各种信息
├── CONTRIBUTING.md
├── lib //web应用调用的jar包存放路径
├── LICENSE
├── logs //存放日志,catalina.out是核心日志文件,localhost_access_log记录访问日志
├── NOTICE
├── README.md
├── RELEASE-NOTES
├── RUNNING.txt
├── temp
├── webapps //默认网站发布目录,其中/ROOT/index.jsp是默认网页
└── work
四、Tomcat实例
4.1 tomcat上安装Jenkins
server.xml配置文件中有两个参数:unpackWARs和autoDeploy
unpackWARs:如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序
autoDeploy:在tomcat启动时,是否自动部署
appBase指定发布目录,此目录可以修改
root@tomcat:~# vim /data/application/tomcat/conf/server.xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
所以直接把Jenkins的war包放在发布目录下,tomcat会自动解压部署
jenkins官网:https://www.jenkins.io/download/
root@tomcat:~# /data/application/tomcat/bin/startup.sh
root@tomcat:~# rm -rf /data/application/tomcat/webapps/*
root@tomcat:~# ls
apache-tomcat-8.5.45.tar.gz jdk-8u211-linux-x64.tar.gz jenkins.war
root@tomcat:~# mv jenkins.war /data/application/tomcat/webapps/
root@tomcat:~# /data/application/tomcat/bin/startup.sh
root@tomcat:~# ls /data/application/tomcat/webapps/
jenkins jenkins.war
访问网页,然后查看密码cat /root/.jenkins/secrets/initialAdminPassword

到这一步Jenkins已经安装成功

4.2 一台机器上运行多实例tomcat
这里演示一台机器上运行两个tomcat
只需要让它们端口不一致即可
root@tomcat:~# rm -rf /data/application/*
root@tomcat:~# ls
apache-tomcat-8.5.45.tar.gz jdk-8u211-linux-x64.tar.gz
root@tomcat:~# tar xf apache-tomcat-8.5.45.tar.gz -C /data/application/
root@tomcat:~# ls /data/application/
apache-tomcat-8.5.45
root@tomcat:~# mv /data/application/apache-tomcat-8.5.45/ /data/application/tomcat1
root@tomcat:~# tar xf apache-tomcat-8.5.45.tar.gz -C /data/application/
root@tomcat:~# mv /data/application/apache-tomcat-8.5.45/ /data/application/tomcat2
root@tomcat:~# ls /data/application/
tomcat1 tomcat2
#修改端口8005-->8006 8009-->8010 8080-->8081
root@tomcat:~# vim /data/application/tomcat2/conf/server.xml
...
<Server port="8006" shutdown="SHUTDOWN">
...
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
...
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
...
root@tomcat:~# /data/application/tomcat1/bin/startup.sh #启动tomcat1
root@tomcat:~# /data/application/tomcat2/bin/startup.sh #启动tomcat2
root@tomcat:~# netstat -tanlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1782/nginx: master
tcp6 0 0 127.0.0.1:8006 :::* LISTEN 3727/java
tcp6 0 0 :::8009 :::* LISTEN 3669/java
tcp6 0 0 :::8010 :::* LISTEN 3727/java
tcp6 0 0 :::8080 :::* LISTEN 3669/java
tcp6 0 0 :::80 :::* LISTEN 1782/nginx: master
tcp6 0 0 :::8081 :::* LISTEN 3727/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 3669/java
tcp6 0 0 ::1:42140 ::1:8080 TIME_WAIT -
tcp6 0 0 127.0.0.1:47354 127.0.0.1:8005 TIME_WAIT -
tcp6 0 0 ::1:8009 ::1:38770 TIME_WAIT -
root@tomcat:~#
访问相同ip的不同端口


4.3 tomcat上部署jspgou商城
先去网上下载jspgou商场的zip包
本实验还需要用到mysql
root@tomcat:~# ls
apache-tomcat-8.5.45.tar.gz DB jdk-8u211-linux-x64.tar.gz jspgouV6-ROOT.zip
root@tomcat:~# unzip jspgouV6.1-ROOT.zip #解压
root@tomcat:~# ls #DB下是sql的逻辑备份语句,需要导入数据库
apache-tomcat-8.5.45.tar.gz DB jdk-8u211-linux-x64.tar.gz jspgouV6-ROOT.zip ROOT
root@tomcat:~#
root@tomcat:~# ls /data/application/tomcat/webapps/
docs examples host-manager manager ROOT
root@tomcat:~# rm -rf /data/application/tomcat/webapps/*
root@tomcat:~# cp -r ROOT/ /data/application/tomcat/webapps/ #将ROOT目录拷贝到tomcat的发布目录下
root@tomcat:~# ls /data/application/tomcat/webapps/
ROOT
root@tomcat:~# mysql -p'Qing@123'
mysql> create database jspgou default charset=utf8; #创建库,待会需要导入数据
mysql> set global sql_mode='NO_ENGINE_SUBSTITUTION'; #临时关闭严格模式
mysql> set session sql_mode='NO_ENGINE_SUBSTITUTION';
mysql> \q
root@tomcat:~# vim /data/application/tomcat/webapps/ROOT/WEB-INF/config/jdbc.properties
...
#我的mysql是在本机,所以ip不用改,你们的mysql在哪台机器上就写哪台的ip
#刚才创建的什么库这里就写什么库,我创建的是jspgou
jdbc.url=jdbc:mysql://127.0.0.1:3306/jspgou?characterEncoding=UTF-8
jdbc.username=root #mysql登录账户
jdbc.password=Qing@123 #登录密码
...
root@tomcat:~# mysql -uroot -p'Qing@123' jspgou < DB/jspgou.sql #导入数据
root@tomcat:~# /data/application/tomcat/bin/startup.sh #启动tomcat
root@tomcat:~# netstat -tanlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1782/nginx: master
tcp 0 0 127.0.0.1:3306 127.0.0.1:47180 ESTABLISHED 1755/mysqld
tcp6 0 0 :::8009 :::* LISTEN 5055/java
tcp6 0 0 :::8080 :::* LISTEN 5055/java
tcp6 0 0 :::80 :::* LISTEN 1782/nginx: master
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 5055/java
tcp6 0 0 127.0.0.1:47180 127.0.0.1:3306 ESTABLISHED 5055/java
root@tomcat:~#
访问网页,jspgou商场搭建完毕

4.4 tomcat配合nginx实现动静分离
4.1.1 环境介绍
大部分情况下,nginx提供静态页面,tomcat提供动态页面
对nginx不了解的可以看这个专栏https://blog.csdn.net/m0_63756214/category_13055829.html
实验环境:
| 主机名 | IP地址 | 占用端口 | 服务 | 作用 |
|---|---|---|---|---|
| tomcat | 192.168.136.134 | 8080 | tomcat | 提供动态页面 |
| tomcat | 192.168.136.134 | 80 | nginx | 提供静态页面 |
| nginx | 192.168.136.135 | 80 | nginx | 负载均衡器 |
4.1.2 页面制作
#动态页面准备
root@tomcat:~# rm -rf /data/application/*
root@tomcat:~# tar xf apache-tomcat-8.5.45.tar.gz -C /data/application/
root@tomcat:~# mv /data/application/apache-tomcat-8.5.45/ /data/application/tomcat
root@tomcat:~# vim /data/application/tomcat/webapps/ROOT/index.jsp #我这写了一个生成随机数的页面
root@tomcat:~# /data/application/tomcat/bin/startup.sh
访问网页

#静态页面准备
root@tomcat:~# vim /var/www/html/index.nginx-debian.html #去nginx的页面随便写点什么都行
root@tomcat:~# systemctl start nginx
访问网页

4.1.2 配置负载均衡
#nginx做负载均衡器实现动静分离
root@nginx:~# vim /etc/nginx/conf.d/test.conf
upstream static {
server 192.168.136.134:80;
}
upstream dynamic {
server 192.168.136.134:8080;
}
server {
listen 80;
server_name localhost;
# 静态页面:匹配所有 .html 结尾的请求
location ~ \.html$ {
proxy_pass http://static;
proxy_set_header Host $host; # 去掉 $server_port,避免后端端口错误
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 动态页面:匹配所有 .jsp 结尾的请求
location ~ \.jsp$ {
proxy_pass http://dynamic;
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:~#
访问网页

五、扩展
5.1常用JVM虚拟机参数
JVM 虚拟机提供了三种类型参数:标准参数,X类型参数,XX类型参数
这里我们着重讲一下XX类型参数
用一句话来说明 XX 参数的语法。所有的 XX 参数都以"-XX:"开始,但是随后的语法不同,取决于参数的类型:
- 对于布尔类型的参数,我们有"+“或”-",然后才设置 JVM 选项的实际名称
例:-XX:+ 用于激活选项,而 -XX:- 用于注销选项。
例:开启GC日志的参数: -XX:+PrintGC - 对于非布尔值的参数,如 string 或者 integer,我们先写参数的名称,后面加上"=",最后赋值
例:-XX:MaxPermSize=2048m
5.2 开启JAVA虚拟机的垃圾回收
要跟踪 Java 虚拟机(JVM)的垃圾回收(GC)过程,可通过添加 JVM 启动参数 开启 GC 日志,记录 GC 的触发时间、类型、回收内存大小、耗时等详细信息
开启 GC 日志不会直接提升应用性能,但是可直观了解 JVM 的垃圾回收行为,帮助排查内存泄漏、优化 GC 性能(如调整堆内存大小、选择合适的 GC 收集器)
5.2.1 JDK 8 及以下版本常用参数
| 参数 | 作用说明 |
|---|---|
-XX:+PrintGCDetails | 打印 GC 详细信息(包括回收前后各内存区域大小、耗时等) |
-XX:+PrintGCDateStamps | 输出 GC 发生的时间戳(格式:YYYY-MM-DDTHH:MM:SS),便于定位时间点 |
-Xloggc:/path/to/gc.log | 指定 GC 日志输出文件路径(需确保目录有写入权限) |
-XX:+PrintGC | 简化版 GC 日志(仅显示 GC 类型、耗时、堆内存变化,信息较少) |
-XX:+PrintGCTimeStamps | 输出 GC 发生的相对时间戳(从 JVM 启动开始计算的秒数) |
5.2.1 GC配置方法
#开启GC日志
vim /tomcat/bin/catalina.sh # 在文件开头(#!/bin/sh 下方)添加
export JAVA_OPTS="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/usr/local/tomcat/logs/gc.log"
5.2.3 GC注意事项
日志滚动
JDK 8 需配合 -XX:+UseGCLogFileRotation 等参数实现日志滚动(避免单文件过大):
# JDK 8 日志滚动配置(最多 5 个文件,每个 100MB)
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M
权限问题
确保日志输出目录(如 /path/to/)有写入权限,否则 JVM 启动会失败
5.3 配置JAVA虚拟机的堆空间
堆内存是 JVM 中最大的内存区域,专门用于存储对象实例,是垃圾回收GC的主要区域
控制 JVM 堆内存的两个关键参数:
-Xms:设置堆内存的初始大小(JVM 启动时分配的内存)
-Xmx:设置堆内存的最大大小(JVM 运行中允许使用的最大内存)
通常建议将 Xms 和 Xmx 设置为相同值,避免 JVM 频繁调整堆内存大小,减少性能损耗
# 设置堆内存初始值和最大值(单位:m 表示兆字节,g 表示千兆字节)
vim /tomcat/bin/catalina.sh # 在文件开头(#!/bin/sh 下方)添加
export JAVA_OPTS="-Xms512m -Xmx1024m"
5.4 配置JAVA虚拟机的元数据区域
元空间用于存储类元数据(如类结构、方法信息、注解等)。元空间默认使用操作系统的本地内存(而非 JVM 堆内存),但可以通过 JVM 参数进行配置,避免其无限制占用系统资源
5.4.1 元空间参数
元空间的核心配置参数有两个,分别控制其初始阈值和最大内存限制:
| 参数 | 作用说明 |
|---|---|
-XX:MetaspaceSize | 设置元空间的初始触发 GC 阈值(默认约 21MB,不同 JDK 版本略有差异) 当元空间使用量达到该值时,会触发元空间的垃圾回收(GC),并动态调整后续阈值 |
-XX:MaxMetaspaceSize | 设置元空间的最大内存上限(默认无限制,仅受系统可用内存限制) 若不设置,元空间可能因类加载过多(如动态生成类)导致本地内存溢出(OOM) |
5.4.2 元空间配置方法
启动 Jar 包时配置直接在启动命令中添加参数
# 元空间初始阈值 128MB,最大限制 256MB
java -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -jar your-application.jar
Tomcat 中配置
编辑 Tomcat 的 bin/catalina.sh 文件,在开头添加参数:
vim /tomcat/bin/catalina.sh # 在文件开头(#!/bin/sh 下方)添加
export JAVA_OPTS="-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
容器化部署(Docker)
在 Dockerfile 或启动命令中通过 JAVA_OPTS 传递参数:
# Dockerfile 示例
FROM openjdk:11-jre-slim
ENV JAVA_OPTS="-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
CMD ["sh", "-c", "java $JAVA_OPTS -jar /app/your-application.jar"]
5.4.3 验证配置是否生效
查看 JVM 进程参数
# 查找 Java 进程 ID
ps -ef | grep java
# 查看元空间配置(替换 PID 为实际进程号)
jinfo -flags PID | grep Metaspace
若输出包含 MetaspaceSize=134217728(128m)和 MaxMetaspaceSize=268435456(256m),则配置生效
查看 GC 日志
元空间相关的 GC 日志会显示元空间的使用量、GC 前后的大小变化,例如:
[GC (Metadata GC Threshold) ... Metaspace: 128.0M->128.0M(256.0M)]
5.5 JVM运维排障工具
5.5.1 jps
jps是列出当前系统中所有正在运行的 Java 进程,类似 ps 命令但专门针对 Java 进程
root@tomcat:~# jps
5680 Bootstrap # tomcat进程
9262 Jps # jps自身进程
root@tomcat:~#
5.5.2 jstack
jstack生成指定 Java 进程的线程堆栈跟踪信息,包括线程状态、调用栈、锁信息等,主要用于排查线程死锁、线程阻塞、CPU 占用过高等问题
jstack [选项] <进程 PID>
注:
文中若有疏漏,欢迎大家指正赐教。
本文为100%原创,转载请务必标注原创作者,尊重劳动成果。
求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~
Tomcat与JVM核心实战指南
951

被折叠的 条评论
为什么被折叠?



