Tomcat
tomcat可以处理动态和静态请求,处理静态请求的效率较低,善于处理动态请求
Java基础知识
Java容器(java中间件)⭐
java容器:用于存放与运行java代码的环境
| java容器 | 说明 |
|
Tomcat(常用)
|
功能完善
|
| Jetty | 轻量,功能较少 |
| Weblogic |
用于Oracle数据库环境使用(Weblogic属于甲骨文)
|
| 东方通 | 国产java容器 |
JVM--JRE--JDK⭐⭐
| JVM(Java Virtual Machine) | java虚拟机 | 运行java代码的地方 |
| JRE(Java Runtime Enviroment) | java运行环境 | jvm + java命令 |
| JDK(Java Development Kit) | java开发环境 | jvm + jre + 额外功能 |

运行代码⭐⭐⭐
- 开发人员书写的java代码: java源代码,无法直接部署tomcat中
- 需要对源代码进行编译:生成war包或jar包
- 如何编译java源代码:通过maven,gradle工具将java源代码编译成war包或则jar包
| 如何运行java相关软件包 | 说明 | 应用场景 |
| war包 | 需要放在java容器中运行(比如将软件包放到tomcat的webapps目录下,tomcat会自动加载与运行war包内容) | 功能复杂 |
| jar包 | 不需要java容器,内置tomcat,只需要jdk(通过Java -jar xxx.jar运行) | 功能简单 |
javat环境部署
|
环境
|
||
|
web03
|
10.0.0.9/172.16.1.9
|
tomcat
|
|
db01
|
10.0.0.51/172.16.1.51
|
部署jdk⭐⭐⭐
[root@web03 ~]# mkdir -p /app/tools/ [root@web03 ~]# tar xf jdk-8u351-linux-x64.tar -C /app/tools/ [root@web03 ~]# ln -s /app/tools/jdk1.8.0_351/ /app/tools/jdk [root@web03 /app/tools]# ll lrwxrwxrwx 1 root root 24 Mar 11 19:12 jdk -> /app/tools/jdk1.8.0_351/ drwxr-xr-x 8 root root 273 Mar 11 19:09 jdk1.8.0_351 # 二进制安装jdk需要配置java环境变量(yum或rpm安装则不需要配置环境变量) cat >>/etc/profile<<'EOF' export JAVA_HOME=/app/tools/jdk # JDK安装目录的环境变量 export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH # 将JDK和JRE的bin目录添加到PATH export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar # CLASSPPATH:用于指定查找类文件时的目录和文件 EOF [root@web03 ~]# source /etc/profile # source:用于执行指定文件的命令(shell内置命令) [root@web03 ~]# java -version java version "1.8.0_351" Java(TM) SE Runtime Environment (build 1.8.0_351-b10) Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)
部署tomcat⭐⭐⭐
[root@web03 ~]# tar xf apache-tomcat-9.0.52.tar.gz -C /app/tools/ [root@web03 ~]# ln -s /app/tools/apache-tomcat-9.0.52/ /app/tools/tomcat [root@web03 ~]# ll /app/tools/ total 0 drwxr-xr-x 9 root root 220 Mar 11 19:55 apache-tomcat-9.0.52 lrwxrwxrwx 1 root root 32 Mar 11 19:56 tomcat -> /app/tools/apache-tomcat-9.0.52/ [root@web03 ~]# /app/tools/tomcat/bin/version.sh # 检查jdk、tomcat信息 Using CATALINA_BASE: /app/tools/tomcat Using CATALINA_HOME: /app/tools/tomcat Using CATALINA_TMPDIR: /app/tools/tomcat/temp Using JRE_HOME: /app/tools/jdk Server number: 9.0.52.0 JVM Version: 1.8.0_351-b10
启动tomcat


tomcat目录结构⭐⭐⭐
目录概述
| 目录 | |
| bin | 存放tomcat命令 |
| conf | tomcat配置文件 |
| lib | 依赖文件、库文件、插件文件 |
| logs | 日志文件 |
| webapps | 站点目录 |
| work | 用于存放tomcat在运行时生成的工作文件 |
bin目录
| bin目录 | 说明 |
| startup.sh | 启动脚本 |
| shutdown.sh | 关闭脚本 |
| catalina.sh | 核心脚本(配置tomcat优化,jvm优化) |
conf目录
| conf配置文件 | 说明 |
| server.xml |
tomcat配置文件(主要用于配置Tomcat服务器的整体设置) |
| web.xml | 配置文件(通常用于配置单个web应用程序的设置) |
logs目录
| logs目录 | 说明 |
| catalina.out |
tomcat应用日志(启动过程、关闭、错误信息等记录) 核心找:startup启动时 错误提示:error,failed,exception |
| catalina.2025-03-11.log | catalina.out的切割日志(按照每天进行切割) |
| localhost_access_log.2025-03-11.txt | 访问日志 |
tomcat基础配置
书写systemctl管理配置文件
服务器管理指令存放在/usr/lib/systemd/system/xxx.service
systemctl cat 需要查看的服务
| systemctl配置文件的结构 | |
| [Unit] | 指明注释信息,依赖(指定的服务运行之后才运行) |
| Description | 说明与注释 |
| After |
指定此单元在启动时依赖的其他单元(network.target)
|
|
[Service]
|
用于指定服务开启命令,关闭命令,重启命令
|
|
Type=notify
|
指定服务类型(指定simple或forking即可)
|
|
ExecStart
|
服务启动命令
|
|
ExecStop
|
服务关闭命令
|
|
ExecReload
|
重启命令
|
|
EnvironmentFile
|
配置环境变量的文件(一般对于编译安装,二进制安装需要配置)
|
|
[Install]
|
内容固定,用于指定运行级别.
|
|
WantedBy=multi-user.target
|
运行级别,一般都是多用户模式.(表明该服务在某个目标(multi-user.target)启动时被启动)
|
tomcat环境变量配置配置
[root@web03 ~]# cat /etc/sysconfig/tomcat JAVA_HOME=/app/tools/jdk PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:/usr/bin/:/usr/sbin/:/usr/local/bin/:/usr/local/sbin/ CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
tomcat的systemctl管理配置文件
[root@web03 ~]# cat /usr/lib/systemd/system/tomcat.service [Unit] Description=Tomcat java web container After=network.target [Service] Type=forking EnvironmentFile=/etc/sysconfig/tomcat ExecStart=/app/tools/tomcat/bin/startup.sh ExecStop=/app/tools/tomcat/bin/shutdown.sh ExecReload=/app/tools/tomcat/bin/shutdown.sh && sleep 1 && /app/tools/tomcat/bin/startup.sh [Install] WantedBy=multi-user.target [root@web03 ~]# systemctl daemon-reload # 当系统服务的配置文件修改、添加、删除后,需要执行systemctl daemon-reload命令,重新加载服务
tomcat管理端(熟悉)
- tomcat管理端使用场景:
- web页面管理与查看tomcat信息功能
- 对tomcat进行调优(调优完需要关闭)

修改配置文件conf/tomcat-users.xml
[root@web03 /app/tools/tomcat/conf]# cat tomcat-users.xml <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"> <role rolename="manager-gui" <role rolename="admin-gui" <user username="yuanxiaojiang"password="1" roles="manager-gui,admin-gui" </tomcat-users>
修改访问地址
# 只能127本地访问 curl -u yuanxiaojiang:1 http:127.0.0.1:8080/manager/status # cd /app/tools/tomcat/webapps/ # 修改代码 [root@web03 /app/tools/tomcat/webapps]# sed -i 's#127#\\d+#g' ./host-manager/META-INF/context.xml ./host-manager/WEB-INF/manager.xml ./manager/META-INF/context.xml
配置文件

server.xml
# shutdown端口:本地连接该端口输入shutdown,可以关闭tomcat <Server port="8005" shutdown="SHUTDOWN"> # tomcat管理端认证功能 <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Connector port="8080" protocol="HTTP/1.1" # 8080处理用户的http请求 connectionTimeout="20000" redirectPort="8443" /> # 此处的8443用于处理https请求 <Engine name="Catalina" defaultHost="localhost"> # 指定默认的虚拟主机 # 虚拟主机的配置部分 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
| tomcat | nginx | |
| 虚拟主机 | Host部分 | server {} |
| 域名 | name=“域名” | server_name blog.linux.cn; |
| 端口 | Connector部分,port="8080" | listen 80; |
| 站点目录 | appBase="webapps" | root /app/code/blog; |
| 自动解压 | unpackWARs="true" | 无 |
| 自动部署 | autoDeploy="true"(自动加载到jvm中) | 无 |
| 日志目录 | <Valve prefix="日志目录" directory="logs"> | access_log /var/nginx/access.log main; |
| 日志名字 | <Valve prefix="日志目录" suffic=".txt"> | access_log /var/nginx/access.log main; |
| 日志格式 | <Valve pattern="%h %l %u %t %r %s %b"> | log_format main; |
规范tomcat访问日志格式⭐⭐
| 说明 | tomcat | nginx |
| 定义访问日志格式 | Host部分的pattern | http区域 log_format 部分 |
| 客户端ip | %h | $remote_addr |
| 访问的时间 | %t | $local_time |
| 请求起始行 | %r | $request |
| 状态码 | %s | $status |
| 大小 | %b | $body_bytes_sent |
| 从哪里跳转来(用户如何访问网站) |
%{Referer}i
|
$http_referer
|
|
客户端类型,浏览器
|
%{User-Agent}i
|
$http_user_agent
|
|
XFF头记录
|
%{X-Forwarded-For}i
|
$http_x_forwarded_for
|
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i"" # ":表示双引号
部署应用
部署war包、jar包
案例:运行memtest.war
![]()

案例:运行nginxWebUI-3.4.0.jar
https://gitee.com/cym1102/nginxWebUI

nohup java -jar -Dfile.encoding=UTF-8 /home/nginxWebUI/nginxWebUI.jar --server.port=8080 --project.home=/home/nginxWebUI/ > /dev/null & # 参数说明(非必填) -Dfile.encoding:指定字符集 --server.port :占用端口, 默认以8080端口启动 project.home :项目配置文件目录,存放数据库文件,证书文件,日志等, 默认为/home/nginxWebUI/ nohup &:后台运行命令(程序在用户退出后依然继续运行)
案例:Tomcat部署zrlog应用
- 创建数据库、用户
- tomcat中部署程序代码war
# db01 create database zrlog; grant all on zrlog.* to 'zrlog'@'172.16.1.%' identified by '2'; show databases ; select user,host from mysql.user; # web03 root@web03 /app/tools/tomcat/webapps]# ll drwxr-x--- 4 root root 101 Mar 17 13:42 zrlog -rw-r--r-- 1 root root 23275721 Mar 17 13:40 zrlog.war # 测试 前台: http://10.0.0.9:8080/zrlog/ 后台管理: http://10.0.0.9:8080/zrlog/admin/

接入nginx⭐⭐
[root@web03 /app/tools/tomcat/webapps]# echo "webapps/index.jsp" > ./index.jsp [root@web03 /app/tools/tomcat/webapps]# curl 10.0.0.9:8080/index.jsp # 访问的是webapps/ROOT/index.jsp # tomcat中用户访问的时不加路劲,直接访问文件,就会访问ROOT下面对应的文件 # 建议:可以将原先的ROOT移除,然后将war包改为ROOT.war [root@web03 /app/tools/tomcat/webapps]# rm -rf ROOT [root@web03 /app/tools/tomcat/webapps]# mv zrlog.war ROOT.war
子配置文件
[root@web03 /etc/nginx/conf.d]# cat zrlog.linux.cn.conf server { listen 80; server_name zrlog.linux.cn; error_log /var/log/nginx/zrlog.linux.cn-error.log notice; access_log /var/log/nginx/zrlog.linux.cn-access.log main; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
数据库连接配置
[root@web03 /app/tools/tomcat/webapps/ROOT]# ll WEB-INF/db.properties -rw-r----- 1 root root 266 Mar 17 17:05 WEB-INF/db.properties [root@web03 /app/tools/tomcat/webapps/ROOT]# cat WEB-INF/db.properties #This is a database configuration file #Mon Mar 17 17:05:21 CST 2025 driverClass=com.mysql.cj.jdbc.Driver user=zrlog password=123 jdbcUrl=jdbc\:mysql\://172.16.1.51\:3306/zrlog?characterEncoding\=UTF-8&allowPublicKeyRetrieval\=true&useSSL\=false&serverTimezone\=GMT
Tomcat多实例
- 在同一台linux主机上运行多个tomcat实例
- 步骤:
- 多个tomcat目录
- 配置文件端口8080,8005
- 启动
[root@web03 /app/tools]# ll drwxr-xr-x 9 root root 220 Mar 17 17:25 tomcat_8081 drwxr-xr-x 9 root root 220 Mar 17 17:38 tomcat_8082 [root@web03 /app/tools]# sed -i 's#8080#8081#g' tomcat_8081/conf/server.xml [root@web03 /app/tools]# sed -i 's#8005#8006#g' tomcat_8081/conf/server.xml [root@web03 /app/tools]# sed -i 's#8080#8082#g' tomcat_8082/conf/server.xml [root@web03 /app/tools]# sed -i 's#8005#8007#g' tomcat_8082/conf/server.xml [root@web03 /app/tools]# /app/tools/tomcat_8081/bin/startup.sh [root@web03 /app/tools]# /app/tools/tomcat_8082/bin/startup.sh [root@web03 /app/tools]# echo tomcat 8081 >tomcat_8081/webapps/ROOT/test.jsp [root@web03 /app/tools]# echo tomcat 8082 >tomcat_8082/webapps/ROOT/test.jsp [root@web03 /app/tools]# curl 10.0.0.9:8081/test.jsp tomcat 8081 [root@web03 /app/tools]# curl 10.0.0.9:8082/test.jsp tomcat 8082
监控功能⭐⭐⭐
- 未来通过各种监控工具(Zabbix、Grafana、Prometheus),监控Tomcat/java,需要我们开启java远程监控功能(JMX remote)
- 步骤:
- tomcat配置中修改tomcat启动的选项,开启jmx远程监控功能
- 使用Zabbix监控(使用windows jdk连接tomcat)
Error:Could not find or load main class

开启远程监控功能
# CATALINA_OPTS:Java环境变量,指定java启动时的选项 CATALINA_OPTS="$CATALINA_OPTS" \ -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=12345 \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false \ -Djava.rmi.server.hostname=10.0.0.9 存放于catalina.sh文件的第125行后面
# 修改后的内容可以在java进程中显示
|
开启远程监控功能选项
|
|
-Dcom.sun.management.jmxremote |
开启远程监控功能 |
-Dcom.sun.management.jmxremote.port=12345 |
指点端口 |
-Dcom.sun.management.jmxremote.authenticate=false
|
关闭认证功能 |
-Dcom.sun.management.jmxremote.ssl=false
|
关闭ssl加密功能 |
-Djava.rmi.server.hostname=10.0.0.9 |
监听的地址(未来需要改动) |
在windows下通过jdk连接tomcat(模拟监控软件连接)
D:\Program Files\Java\jdk1.8.0_201\bin\jconsole.exe

java监控命令(jps、jstack、jmap)⭐⭐
jps
jps ==》java ps 命令,只显示java进程(类似于ps -ef |grep java) jps -lvm |grep tomcat -l 显示应用的完整包名 -v 显示JVM参数 -m 显示传递给主类的参数
jstack
jstack查看java进程内部信息(线程信息) 进程: 占空间,占系统资源,厂房. 线程: 厂房里面的工人,处理与用户的请求. 需要代码使用多线程技术. 通过ps aux 查看进程是否支持线程(是否使用多线程技术) 先过滤出java进程的pid 查看java进程的线程信息 jstack 1786 查看java线程状态 jstack 1786 |grep -i state 新建状态New; 就绪状态Runnable 运行状态Running 阻塞状态Blocked 死亡状态Dead
jmap
jmap主要用于查看和导出 Java (jvm)进程的内存状态 -heap:打印堆的摘要信息。 -histo:打印堆中对象实例的统计信息。 -dump:生成堆转储文件(jvm信息)(将生成的内容通过mat分析工具查看) jmap 参数 java_pid jmpa -dump:format=b,file=/tmp/heap_dump.hprof java_pid # 进程浩为java_pid的java应用生成一个名为heap_dump.hprof的完整对转储文件
系统高排查流程⭐⭐⭐⭐⭐

|
Java应用系统负载高排查流程
|
涉及命令
|
结果 |
|
通过监控服务发现系统负载高
|
zbx,prometheus
|
告警
|
|
登录到对应的节点,通过命令检查系统负载是否高
|
w,uptime,top,lscpu | cpu核心总数于负载做对比 |
| 定位什么导致系统负载高 |
top,ps -aux,iotop,vmstat
|
判断出cpu、io导致 |
|
找出原因并且找出对应的进程,需要根据进程找服务相关日志
|
根据找出的进程,查看日志信息
|
|
|
java进程查看进程中的线程信息
|
jps,jstack
|
|
|
导出jvm信息,通过mat工具进行分析
|
jmap,MA
|
java会话共享方案
|
会话共享方案
|
说明 | 备注 |
| 单机 |
如果单个应用,tomcat,不用考虑会话共享的问
题
|
|
|
session复制功能
|
tomcat进行配置后可以把session信息复制给其
他节点
|
只适用于集群节点较少的 情况,比如4个及
以内的节点
|
|
通过插件实现会话共享,存放在redis中
|
tomcat通过插件,把用户会话保存在指定的服务器中(redis中)
tomcat-cluster-session-manager
|
需要插件,进行配置,代码支持
|
|
通过代码直接指定session位
置
|
修改代码与增加功能,依赖
|
需要修改代码,实现效果与通过插件类似
|
|
使用其他方式替换会话
|
oauth认证,token认证
|
代码级别
|
前后端分离(学之思管理系统)⭐⭐⭐
- tomcat动静分离,提取出静态资源
- 静态资源:前端(html、css、js)
- 动态资源:后端(java、PHP、python、Golang)连接使用数据库
- 前后端分离:拆分为前端和后端部分,一般前后端通过API接口进行连接
- API应用程序接口:开发人员写好的,可以直接调用的代码

| 主机 | 环境 |
| web03 | nginx + jdk (由于资源有限,前端后端放在一台服务器) |
| db02 |
数据库 mysql 二进制方式安装 /app/tools/mysql/ 数据目录 /app/data/3306/ |
数据库部署(本机器上需要没有其他数据库)
[root@db02 ~]# mkdir -p /app/tools/ /app/data/3306/ [root@db02 ~]# tar xf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz -C /app/tools/ [root@db02 ~]# ln -s /app/tools/mysql-8.0.30-linux-glibc2.12-x86_64/ /app/tools/mysql # 安装依赖 [root@db02 ~]# yum install -y ncurses ncurses-devel libaio-devel openssl openssl-devel useradd -s /sbin/nologin -M mysql # 设置配置文件 [root@db02 ~]# cat /etc/my.cnf [mysqld] ##用户 user=mysql ##安装目录 basedir=/app/tools/mysql/ ##数据目录 datadir=/app/data/3306/ port=3306 socket=/tmp/mysql.sock [client] socket=/tmp/mysql.sock #修改配置和数据目录的所有者. [root@db02 ~]# chown mysql.mysql /etc/my.cnf [root@db02 ~]# chown -R mysql.mysql /app/data/3306 [root@db02 ~]# echo 'export PATH=/app/tools/mysql/bin:$PATH' >>/etc/profile [root@db02 ~]# source /etc/profile [root@db02 ~]# mysql -V mysql Ver 8.0.30 for Linux on x86_64 (MySQL Community Server - GPL) # 初始化数据库(不需要重复运行,重复运行会报错) [root@db02 ~]# mysqld --initialize-insecure --user=mysql --basedir=/app/tools/mysql/ --datadir=/app/data/3306/ [root@db02 ~]# echo $? # 0 # 拷贝已经准备好的启动管理文件 [root@db02 ~]# cp /app/tools/mysql/support-files/mysql.server /etc/init.d/mysqld [root@db02 ~]# chmod +x /etc/init.d/mysqld # 开机自启动服务 [root@db02 ~]# systemctl start mysqld.service [root@db02 ~]# systemctl enable mysqld.service mysqld.service is not a native service, redirecting to /sbin/chkconfig. Executing /sbin/chkconfig mysqld on [root@db02 ~]# /sbin/chkconfig mysqld on
-- 创建数据库 mysql> create database exam; -- 创建用户 mysql> create user exam@'172.16.1.%' identified with mysql_native_password by '1'; # mysql_native_password:一种传统生根验证插件,主要用于兼容性和安全性较低的服务 -- 授权用户 mysql> grant all on exam.* to 'exam'@'172.16.1.%'; -- 测试 [root@web03 ~]# mysql -uexam -h 172.16.1.52 -p
后端部署
[root@web03 ~]# mkdir -p /app/code/exam/{front,backend} [root@web03 ~]# mv xzs-3.9.0.jar /app/code/exam/backend/ [root@web03 ~]# cd /app/code/exam/backend/ [root@web03 ~]# cat> application-prod.yml<<'EOF' logging: path: /usr/log/xzs/ spring: datasource: url: jdbc:mysql://172.16.1.52:3306/exam?useSSL=false&useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&allowMultiQueries=true username: exam password: 1 driver-class-name: com.mysql.cj.jdbc.Driver EOF [root@web03 /app/code/exam/backend]# java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.9.0.jar root@web03 /app/code/exam/backend]# ps -ef|grep java root 2529 1722 28 12:03 pts/0 00:00:05 java -Duser.timezone=Asia/Shanghai -jar -Dspring.proiles.active=prod xzs-3.9.0.jar
前端部署
[root@web03 ~]# mv exam-web-前端/admin /app/code/exam/front/ [root@web03 ~]# mv exam-web-前端/student /app/code/exam/front/ [root@web03 ~]# cat /app/code/exam/front/exam.conf server { listen 80; server_name admin.exam.cn; root /app/code/exam/front/admin/; location / { index index.html; } location /api/ { proxy_pass http://localhost:8000; } } server { listen 80; server_name student.exam.cn; root /app/code/exam/front/student/; location / { index index.html; } location /api/ { proxy_pass http://localhost:8000; } } # hosts解析 10.0.0.9 admin.exam.cn student.exam.cn
浙公网安备 33010602011771号