WEB集群-Tomcat集群
WEB集群-Tomcat集群
1. WEB集群-Tomcat集群
1.2 Java容器
- java 容器:用于存放与运行 java 代码的环境.
- web 中间件
| java 容器 | 说明 |
|---|---|
| Tomcat | 最常用,较重,功能完善. |
| Jetty | 轻量,功能较少. |
| Weblogic | 用于 Oracle 数据库环境使用,Weblogic 属于甲骨文. |
| 东方通 | 国产 java 容器. |
| …… |
1.3 JVM-JRE-JDK
- 1 份代码处处运行与使用。代码的可移植性.
- JVM:java 虚拟机中,运行 java 代码的地方.
- JRE:java Runtime Enviroment(java 运行环境). 提供 jvm 环境,java 命令.
- JDK:Java Development Kit(java 开发环境), jvm+jre + 额外功能.
JRE = JVM + 核心类库
JDK = JRE + 开发工具(编译器、调试器等)
1.4 Tomcat极速上手指南
1) 环境准备
| 环境 | IP 地址 | 服务 |
|---|---|---|
| web03 | 10.0.0.9/172.16.1.9 | tomcat |
| web04 | 10.0.0.10/172.16.1.10 | tomcat |
| db01 | 10.0.0.51/172.16.1.51 |
2) 部署jdk
mkdir -p /app/tools/
tar xf jdk-8u341-linux-x64.tar.gz -C /app/tools/
ll /app/tools/
ln -s /app/tools/jdk1.8.0_341/ /app/tools/jdk
# 配置JAVA环境变量,一般是二进制安装需要配置(yum安装或rpm包方式安装就不需要配置).
cat >>/etc/profile<<'EOF'
export JAVA_HOME=/app/tools/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
EOF
source /etc/profile
java -version
3) 部署tomcat
tar xf apache-tomcat-9.0.65.tar.gz -C /app/tools/
ln -s /app/tools/apache-tomcat-9.0.65/ /app/tools/tomcat
/app/tools/tomcat/bin/version.sh #检查jdk,tomcat信息
4) 启动tomcat

1.5 Tomcat目录结构
1) 目录概述
| 目录 | 说明 |
|---|---|
| bin 目录 | 存放 tomcat 管理命令 |
| conf | tomcat 配置文件 |
| lib | 依赖与库文件,插件文件 |
| logs | 日志目录 |
| webapps | 站点目录 |
| work | tomcat 运行 java 代码的存放代码的目录 |
2) bin 目录
| bin 目录 | 说明 |
|---|---|
| startup.sh | 启动脚本 |
| shutdown.sh | 关闭脚本 |
| catalina.sh | 核心脚本,配置 tomcat 优化,jvm 优化 |
3) conf
| conf 配置文件 | 说明 |
|---|---|
| server.xml | tomcat 配置文件 |
| web.xml | 配置文件,辅助配置 |
4) logs 日志
| logs 目录 | 说明 |
|---|---|
| catalina.out | tomcat 应用日志,启动过程,关闭,错误信息核心找: startup 启动用时,错误提示:error, failed, exception |
| catalina.2025-09-15.log | catalina.out 的切割日志。按照每天进行切割. |
| localhost_access_log.2025-09-15.txt | 访问日志,未来可以重新定义名字和内容 |
- webapps
- 站点目录
- war包,自动解压,自动部署
1.6 Tomcat日常管理与访问
- 日常启动与维护

- 浏览器访问: http://10.0.0.9:8080

- 书写systemctl管理配置文件进行管理
- 服务管理指令.
- 存放在
/usr/lib/systemd/system/xxx.service - 分为 3 个部分.
- 修改或设置 systemctl 配置要进行重新加载配置.
| systemctl 配置文件的结构 | 说明 |
|---|---|
| [Unit] | 指定注释信息,依赖 (先后顺序) |
| Description | 说明与注释 |
| After | 在这里指定的服务之后运行. network.target |
| [Service] | 用于指定服务开启命令,关闭命令,重启命令. |
Type=notify |
指定类型 simple 或 forking即可 |
| ExecStart | 服务启动命令 |
| ExecStop | 服务关闭命令 |
| ExecReload | 重启命令 |
| EnvironmentFile | 配置环境变量的文件 (一般对于编译安装,二进制安装需要加上) |
| [Install] | 内容固定,用于指定运行级别. |
WantedBy=multi-user.target |
运行级别,一般都是多用户模式. |
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
tomcat systemctl 配置
#环境变量配置
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
#systemctl 配置
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 /app/tools/tomcat]# systemctl daemon-reload
3)运行代码
- 开发人员书写的java代码: java源代码,无法直接部署tomcat中.
- 需要对源代码进行编译: 生成war包或jar包.
| 如何运行 java 相关软件包 | 说明 | 应用场景 |
|---|---|---|
| war 包 | 需要放在 java 容器中运行,比如放到 tomcat 的 webapps 目录下.(tomcat 会自动加载与运行 war 包内容) | 功能复杂 |
| jar 包 | 不需要 java 容器,内置 tomcat, 只需要 jdk , 通过 java -jar xxx.jar 运行 |
功能简单 |
如何编译java源代码:
通过 maven , Gradle 把java源代码,编译生成war包或jar包.
-
案例01:war包案例,运行memtest.war包案例,放在webapps目录,然后访问即可
-
案例02:jar包案例,运行指定的jar包
启动程序:
nginxWebUI-3.4.0.jar
java -jar -Dfile.encoding=UTF-8 nginxWebUI-3.4.0.jar --server.port=8848 --project.home=/root/
Linux 后台启动命令:
nohup java -jar -Dfile.encoding=UTF-8 /home/nginxWebUI/nginxWebUI.jar --server.port=8080 --project.home=/home/nginxWebUI/ > /dev/null &
> /dev/null:将标准输出重定向到空设备,避免日志占满磁盘。
参数说明(都是非必填)
--server.port:占用端口,默认以 8080 端口启动--project.home:项目配置文件目录,存放数据库文件、证书文件、日志等,默认为/home/nginxWebUI/
注意:Linux 命令最后加一个 & 号,表示项目后台运行
1.7 Tomcat管理端
- tomcat 管理端,web 页面管理与查看 tomcat 信息的功能
- 对 tomcat 进行调优的时候
- 未来优化的时候需要关闭
conf/tomcat-users.xml
-
开启管理端功能
- 修改配置文件tomcat-users.xml
- 修改代码(安全措施,只能127访问)
-
修改配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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="lidao996" password="1" roles="manager-gui,admin-gui"/>
</tomcat-users>
- 只能127访问
curl -u lidao996:1
http://127.0.0.1:8080/manager/status
- 修改代码
cd /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
sed -i 's#127#\\d+#g':将配置文件中的 127 替换为 \d+,修改后的规则变为 \d+\.\d+\.\d+\.\d+,即允许所有 IP 地址访问管理端。

1.8 配置文件
- server.xml
#8005端口
<Server port="8005" shutdown="SHUTDOWN">
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>
#8080 处理用户的http请求的.
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
这里的 8443 是用于处理 https 请求。
#engine部分,指定默认的虚拟主机.
<Engine name="Catalina" defaultHost="localhost">
defaultHost="localhost" 指定 localhost 作为默认的虚拟主机。
#Host部分,虚拟主机的配置部分.
<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>
Host 部分
name="域名"
| tomcat | ngx | |
|---|---|---|
| 虚拟主机 | Host 部分 | server {} |
| 域名 | name="域名" | server_name java.oldboylinux.cn; |
| 端口 | Connector 部分 port="8080" | listen 80; |
| 站点目录 | appBase="webapps" | root /app/code/blog; |
| 自动解压 | unpackWARs="true" | 无 |
| 自动部署 | autoDeploy="true" 加载到 jvm 中 | 无 |
| 日志目录 | <Valve 部分 日志目录 directory="logs" |
access_log /var/log/nginx/access.log main; |
| 日志名字 | <Valve 部分前半部分prefix="localhost_access_log" 后半部分suffix=".txt" |
access_log /var/log/nginx/access.log main; |
| 日志格式 | <Valve 部分pattern="%h %l %u %t "%r" %s %b" |
log_format main ...............; |
1.9 规范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"" />
1.10 tomcat与用户请求
[root@web03 /app/tools/tomcat]# cat conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<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"
suffix=".log"
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i"" />
</Host>
</Engine>
</Service>
</Server>
<Host name="zrlog.oldboylinux.cn"
appBase="/app/code/zrlog/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="zrlog_access" suffix=".log"
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i"" />
</Host>
</Engine>
</Service>
</Server>
1. 请求与8080端口连接
2. 域名与Host部分的Name进行匹配,
a)匹配成功则使用对应的虚拟主机.
b)匹配失败则使用Engine部分defaultHost指定的默认的虚拟主机进行处理.
案例03: Tomcat部署zrlog应用
- 代码war
- 创建数据库,用户.
- Tomcat
可以修改下war包的名字为:zrlog.war
- 数据库
create database zrlog;
grant all on zrlog.* to 'zrlog'@'172.16.1.%' identified by '2';
show databases;
select user,host from mysql.user;
- 部署代码
改名为zrlog.war后 移动到webapps目录
[root@web03 /app/tools/tomcat/webapps]# ll
total 10988
drwxr-x--- 15 root root 4096 Sep 15 11:35 docs
drwxr-x--- 7 root root 99 Sep 15 11:35 examples
drwxr-x--- 6 root root 79 Sep 15 11:35 host-manager
drwxr-x--- 6 root root 114 Sep 15 11:35 manager
drwxr-x--- 3 root root 41 Sep 15 15:41 memtest
-rw-r--r-- 1 root root 643 Sep 15 15:40 memtest.war
drwxr-x--- 3 root root 223 Sep 15 11:35 ROOT
drwxr-x--- 9 root root 126 Sep 16 10:40 zrlog
-rw-r--r-- 1 root root 11243048 Sep 16 10:40 zrlog.war
- 浏览器访问 zrlog.oldboylinux.cn/zrlog/
前台:
http://zrlog.oldboylinux.cn:8080/zrlog/
后台管理:
http://zrlog.oldboylinux.cn:8080/zrlog/admin/
1.11 接入ngx
tomcat访问规则:
访问路径 zrlog.oldboylinux.cn:8080/zrlog/
用户访问的时候不加上路径,直接访问文件,就会访问ROOT下面的内容.
zrlog.oldboylinux.cn:8080/lidao.jsp = webapps/ROOT/lidao.jsp
zrlog.oldboylinux.cn:8080/oldboy/lidao996.jsp (webapps/oldboy/lidao996.jsp)
应用建议:
把应用war包和目录放在ROOT目录下面即可
可以把war包改为 ROOT.war ROOT
zrlog数据库连接配置文件:
#This is a database configuration file
#Wed Feb 22 09:05:24 CST 2023
driverClass=com.mysql.cj.jdbc.Driver
user=zrlog
password=1
jdbcUrl=jdbc\:mysql\://172.16.1.51\:3306/zrlog?characterEncoding\=UTF-8&allowPublicKeyRetrieval\=true&useSSL\=false&serverTimezone\=GMT
#jdbcUrl=jdbc\:mysql\://数据库地址\:3306/数据库名字?characterEncoding\=UTF-8&allowPublicKeyRetrieval\=true&useSSL\=false&serverTimezone\=GMT
-
zrlog.war改名为ROOT.war然后部署.
-
ngx配置文件
[root@web03 /etc/nginx/conf.d]# cat zrlog.oldboylinux.cn.conf
server {
listen 80;
server_name zrlog.oldboylinux.cn;
error_log /var/log/nginx/zrlog.oldboylinux.cn-error.log notice;
access_log /var/log/nginx/zrlog.oldboylinux.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 264 Sep 16 11:53 WEB-INF/db.properties
[root@web03 /app/tools/tomcat/webapps/ROOT]# cat WEB-INF/db.properties
#This is a database configuration file
#Fri Sep 16 11:53:15 CST 2022
driverClass=com.mysql.cj.jdbc.Driver
user=zrlog
password=2
jdbcUrl=jdbc:mysql://172.16.1.51:3306/zrlog?characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=GMT
- tomcat+ngx动静分离
1.12 Tomcat多实例
- 目标:在同一台 Linux 主机上运行多个 Tomcat 实例。
- 原因:充分利用服务器资源。
- 步骤
- 多个 Tomcat 目录
- 配置文件端口 8080, 8005
- 启动
准备多个 Tomcat
tar xf apache-tomcat-9.0.65.tar.gz
cp -r apache-tomcat-9.0.65 tomcat-8081
cp -r apache-tomcat-9.0.65 tomcat-8082
mv tomcat-808* /app/tools/
修改配置
sed -i 's#8005#8006#g' tomcat-8081/conf/server.xml
sed -i 's#8080#8081#g' tomcat-8081/conf/server.xml
sed -i 's#8005#8007#g' tomcat-8082/conf/server.xml
sed -i 's#8080#8082#g' tomcat-8082/conf/server.xml
手动启动
echo java oldboylinux 8081 >/app/tools/tomcat-8081/webapps/ROOT/lidao.jsp
echo java oldboylinux 8082 >/app/tools/tomcat-8082/webapps/ROOT/lidao.jsp
提示:生产上,可以直接把 Tomcat + 应用整体打包,使用的时候直接解压即可。
1.13 监控功能
1)概述
- 未来通过各种监控工具(Zabbix/Grafana/Prometheus/....),监控Tomcat/java。
- 需要我们开启java远程监控功能(JMX remote)
2)步骤
- tomcat配置中修改tomcat启动的选项,开启jmx远程监控功能。
- 交给zbx就可以了(使用windows jdk连接tomcat)。
catalina.sh 文件中125 后面
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"
| 开启远程监控功能选项 | 说明 | 备注 |
|---|---|---|
-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 |
写上本地网卡的 ip, 监听的地址. | 未来需要修改的. |
修改后java进程中增加了上面添加的那些选项.
/app/tools/jdk/bin/java
-Djava.util.logging.config.file=/app/tools/tomcat/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-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
-Dignore.endorsed.dirs= -classpath
/app/tools/tomcat/bin/bootstrap.jar:/app/tools/tomcat/bin/tomcat-juli.jar
-Dcatalina.base=/app/tools/tomcat
-Dcatalina.home=/app/tools/tomcat
-Djava.io.tmpdir=/app/tools/tomcat/temp
org.apache.catalina.startup.Bootstrap start
- 在windows下,通过jdk连接tomcat(模拟监控软件连接)
C:\Program Files\Java\jdk1.8.0_201\bin\jconsole.exe


2. java故障案例
2.1 java监控命令
1) 命令
a. jps
jps → java ps 命令,只显示java进程. 类似于 ps -ef | grep java
jps -lvm|grep tomcat-8081
b. jstack
jstack查看java进程内部信息,线程信息.
进程:占空间,占系统资源,厂房.
线程:厂房里面的工人,处理与用户的请求.
需要代码使用多线程技术. 通过ps aux 查看进程是否支持线程(是否使用多线程技术
jstack 1786
查看java线程状态:
jstack 1786 |grep -i state
线程状态:
1、新建状态New;
2、就绪状态Runnable;
3、运行状态Running;
4、阻塞状态Blocked;
5、死亡状态Dead.
c. jmap
##jmap查看或导出jvm信息
##查看jvm使用情况
jmap -heap java-pid
##导出java进程的jvm内存使用情况.
## 导出jvm内存镜像,将堆内存完整导出为二进制的 .hprof 镜像文件(生产环境该文件较大)
jmap -dump:format=b,file=8081.hprof 1786
Dumping heap to /root/8081.hprof ...
Heap dump file created
[root@web03 ~]# ll -h 8081.hprof
-rw------- 1 root root 20M Sep 19 09:43 8081.hprof
d. mat分析工具
jvm内存映像文件,在windows/mac/ubuntu系统下通过MemoryAnalyzer Tool(MA/MAT)
- 需要jdk环境
- 软件包解压即可使用
- MemoryAnalyzer.exe
下载地址:https://www.eclipse.org/mat/downloads.php
命令小结
- jps-查看java进程信息(pid,进程名字),更加详细信息看ps
- jstack-查看java线程信息,过滤线程状态
- jmap-查看jvm内存信息(导出)
2)脚本
show-busy-java-thread.sh 显示当前环境中,所有繁忙的java线程. 以百分数显示使用率最高的前几个线程.
1 sh show-busy-java-threads.sh
2 繁忙的线程id号(10进制和16进制)
3 知晓线程属于的进程
2.2 java应用负载高故障案例
排查流程小结
| Java应用系统负载高排查流程 | 涉及命令 | 结果 |
|---|---|---|
| 1 通过监控服务发现系统负载高 | zbx, prometheus | 告警 |
| 2 登录到对应的节点,通过命令检查系统负载是否高 | w, uptime, top, lscpu | CPU核心总数与负载对比 |
| 3 真的高,定位什么导致的系统负载高 | top, ps aux, iotop, vmstat | 判断出cpu, io导致的. |
| 4 找出原因并且找出对应的进程,需要根据进程找服务相关日志 | 根据找出的进程,查看日志信息 | |
| 5 java进程查看进程中的线程信息. | jps, jstack | |
| 6 导出jvm信息,通过mat工具进行分析. | jmap, MA | 需要与开发一起看. |
分析出什么原因导致的故障.
3. Java会话共享方案
| 会话共享方案 | 说明 | 备注 |
|---|---|---|
| 单机 | 如果单个应用,tomcat,不用考虑会话共享的问题。 | |
| session 复制功能 | tomcat 进行配置后可以把 session 信息复制给其他节点。 | 只适用于集群节点较少的情况,比如 4 个及以内的节点。 |
| 通过插件实现会话共享,存放在 redis 中。 | tomcat 通过插件,把用户会话保存在指定的服务器中(redis 中)tomcat-cluster-session-manager | 需要插件,进行配置,代码支持。 |
| 通过代码直接指定 session 位置 | 修改代码与增加功能,依赖。 | 需要修改代码,实现效果与 3 类似 |
| 使用其他方式替换会话 | oauth 认证,token 认证 |
4. Tomcat配置https
下载tomcat使用证书. 修改配置文件(配置跳转)
应用建议:
tomcat可以支持https,可以在tomcat中配置https证书.
未来可以在nginx中配置证书加密,tomcat未加密.
tomcat配置文件:
[root@web03 /app/tools/tomcat/conf]# cat server.xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener
className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener
className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener
className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<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>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8443"
protocol="HTTP/1.1"
SSLEnabled="true"
scheme="https"
secure="true"
keystoreFile="/app/tools/tomcat/cert/ssl.oldboylinux.cn.pfx"
keystoreType="PKCS12"
keystorePass="AGrnHD9j"
clientAuth="false"
SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3" />
ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256" />
<Engine name="Catalina" defaultHost="localhost">
<Realm
className="org.apache.catalina.realm.LockOutRealm">
<Realm
className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve
className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access"
suffix=".log"
pattern="%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i"" />
</Host>
</Engine>
</Service>
</Server>
说明:关于tomcat其他类型的证书格式配置 jks格式
keystoreFile="/app/tools/tomcat/cert/ssl.oldboylinux.cn.jks"
keystoreType="PKCS12" #删除这一行
keystorePass="AGrnHD9j" #密码
访问测试: https://ssl.oldboylinux.cn:8443
配置tomcat → http8080→https 8443
web.xml的在文件</welcome-file-list>后添加以下内容
<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection >
<web-resource-name>ssl</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
5. tomcat优化
安全优化
性能优化
jvm优化
5.1 安全优化
| 条目 | 配置 | 备注 |
|---|---|---|
| Tomcat shutdown 端口的保护 | 改为其他的特殊端口,暗号也要修改.<Server port="8115" shutdown="lidao996"> |
|
| ajp 连接端口禁用 | 已经从 tomcat 8.5 开始默认就注释了. | 8009 端口,用于与 apache 进行连接. |
| 禁用管理端 | 把管理端相关配置,文件,目录清理掉webapps 下面的 docs examples host-manager manager |
如果开启较为危险. |
| 降权启动 (监牢模式) | 通过普通用户运行与管理服务. | 端口大于 1024,1024 以内的端口特权端口,只能 root 使用.对于二进制,编译安装的软件较为容易配置. |
| 文件列表访问控制 | 类似于 nginx autoindex, 是否会默认列表站点目录的内容,默认关闭的. | |
| tomcat 版本信息隐藏 | 遇到 4xx,5xx 错误的时候显示指定的页面,不包含服务器版本信息. | |
| tomcat web 服务隐藏 | http 响应头里面的内容 connector 8080 部分增加头部信息 Server 信息 | |
| 访问限制 | 类似于 ngx, 使用 allow 和 deny | 一般推荐使用 ngx 限制. |
| 起停脚本权限回收 | tomcat/bin 目录,脚本,700/500 , 从 tomcat 8.5 开始 750 | 权限最小化 |
| 访问日志格式规范 | tomcat server.xml 中配置访问日志的格式,参考 ngx. |
5.2 性能优化
io模型优化.
线程数量,压缩的配置.
1) io模型优化
类似于nginx同步,异步模型.
决定了tomcat如何处理数据.
| IO模型 | 说明 |
|---|---|
| BIO | Blocked IO,阻塞,同步模型. tomcat7及之前版本默认是BIO |
| NIO(NIO1 NIO2) | New IO,非阻塞,异步模型. tomcat8开始默认就是nio. |
| APR | 应对高并发场景 |
应用建议:
使用默认的即可.
tomcat设置为nio2模型
Connector port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
看日志catalina.out (截图中 http-ni2-8080 表示配置完成)

设置apr模型:
安装依赖apr-devel tomcat-native
protocol="org.apache.coyote.http11.Http11AprProtocol"
2) tomcat java线程数
maxThreads="500" 最大的线程数量 200-400之间,具体的数值需要进行压力测试.
acceptCount="500" 当达到最大线程数量的时候,队列长度,acceptCount一般与maxThreads 一致
acceptorThreadCount="2" 请求分成几队伍进行,数值上与cpu核心总数一致或2倍默认是1
minSpareThreads="10" 空闲时候最小的线程数量,不忙的时候,最少留几个服务员,值班的线程数量设置数值的建议,搭建好环境,部署应用,通过测试软件测试,监控状态.
测试软件:ab,压力测试工具loadrunner....,jmeter
3) DNS,压缩
#禁用DNS反向解析功能,加速访问. 域名—→ip ip—→域名
enableLookups="false"
#类型与ngx gzip压缩(推荐在ngx配置)
compression="on" 开启tomcat压缩功能 静态文本资源 html js css
compressionMinSize="2048" 大于2048字节的文件才会被压缩
compressableMimeType="text/html,text/plain,text/css,application/javascript,application/json,application/x-font-ttf,application/x-font-otf"
5.3 JVM优化
catalina.sh文件中的内容.
设置jvm内存大小.
配置gc日志(垃圾回收)
配置自动dump功能.
配置JVM内存大小
设置 jvm初始内存大小(默认物理内存1/64)jvm最大内存大小(默认物理内存的1/4 )
修改 catalina.sh文件
JAVA_OPTS='-Xms1024m -Xmx1024m -Xloggc:/var/log/tomcat_gc.log'
-Xms jvm jvm初始内存大小
-Xmx max jvm最大内存
方案01:一般 -Xmx 是 -Xms 2倍.
方法02:-Xmx 与-Xms 一致,防止重复gc垃圾回收.
gc garbage collect 垃圾回收 定期清理 jvm内存.
-Xloggc:/var/log/tomcat_gc.log 垃圾回收的日志
配置GC日志
-Xloggc:/var/log/tomcat_gc.log
自动DUMP功能(jvm发生异常,自动导出jvm内存镜像)
-XX:+HeapDumpOnOutOfMemoryError #OOM故障
-XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof
-XX:+HeapDumpOnOutOfMemoryError 开启导出jvm镜像功能,用于java/tomcat加载应用故障,内存不足
oom out of memory 内存不足.
-XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof
用于指定jvm内存镜像导出到哪里.
6. java前后端分离项目
Tomcat 动静分离.提取出静态资源.
静态资源:前端(html,css,js).
后端:(Java,PHP,Python,Golang...) 连接使用数据库.
前后端分离,拆分为前端部分和后端部分,一般前后端通过API接口的进行连接.
API应用程序接口: 开发人员书写好的,可以直接调用的代码.使用的人员不需要关注功能如何实现的,只需要关注如何调用接口即可.
API接口在各种服务中广泛存在.
调用天气预报API接口
curl "https://v0.yiketianqi.com/api?
unescape=1&version=v91&appid=43656176&appsecret=I42og
6Lm&ext=&cityid=&city="
6.1 前端分离
前端(静态资源)
API接口(Rest API)
后端(动态功能)
全栈:前端+后端
前端,后端下载的代码是源代码
前端代码需要编译, nodejs环境编译—→静态资源(html,css,js)-->nginx中.
后端代码java,通过maven/gradle编译—→war包/jar包 运行.
6.2 项目
1)概述
考试系统项目
| 主机 | 环境 |
|---|---|
| web03 | 前端(ngx)+后端(jdk) |
| db02(52) | 数据库 mysql 8.0 二进制方法安装 /app/tools/mysql/ 数据目录/app/data/3306/ |
2)数据库准备
解压
配置
初始化
管理,连接
创建库
创建用户
导入数据库表与数据(sql文件)
a) 解压
#解压,环境准备
mkdir -p /app/tools/ /app/data/3306/
tar xf mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz -C /app/tools/
ln -s /app/tools/mysql-8.0.27-linux-glibc2.12-x86_64/ /app/tools/mysql
yum install ncurses ncurses-devel libaio-devel openssl openssl-devel -y
#配置文件,用户
useradd -s /sbin/nologin -M mysql
#设置配置文件
cat>/etc/my.cnf<<'EOF'
#by oldboy weixin:oldboy0102
[mysqld]
##用户
user=mysql
##安装目录
basedir=/app/tools/mysql/
##数据目录
datadir=/app/data/3306/
port=3306
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
EOF
cat /etc/my.cnf
#修改配置和数据目录的所有者.
chown mysql.mysql /etc/my.cnf
chown -R mysql.mysql /app/data/3306
#配置PATH环境变量
echo 'export PATH=/app/tools/mysql/bin:$PATH' >>/etc/profile
source /etc/profile
#检查
mysql -V
初始化数据库(不需要重复运行,重复运行会报错)
#初始化
mysqld --initialize-insecure --user=mysql \
--basedir=/app/tools/mysql/ --datadir=/app/data/3306/
echo $?
启动
#拷贝已经准备好的启动管理文件
cp /app/tools/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
#开机自启动服务,运行服务
systemctl enable mysqld
systemctl start mysqld
登录
mysql
创建数据库
#创建exam数据库并指定字符集.
create database exam charset utf8mb4;
添加用户(请注意)
#添加用户(请注意)
#创建用户
create user exam@'172.16.1.%' identified with mysql_native_password by '1';
#授权
grant all on exam.* to exam@'172.16.1.%' ;
#测试
mysql -uexam -p1 -h 172.16.1.52
导入数据(创建表,导入数据)
mysql exam <xzs-mysql.sql
- 部署后端
mkdir -p /app/code/exam/{front,backend}
解压
cd /app/code/exam/backend/
java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.9.0.jar
#说明
-Dspring.profiles.active=prod jar包目录同层的 application-prod.yml application.yml
#说明
-Dspring.profiles.active=prod jar包目录同层的 application-prod.yml application.yml
配置文件内容:
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
nohup java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.9.0.jar > start1.log 2>&1 &
访问与测试后端
http://10.0.0.9:8000/student 学生 student 123456
http://10.0.0.9:8000/admin admin 123456
4)部署前端
[root@web03 ~]# cat /etc/nginx/conf.d/exam.conf
server {
listen 80;
server_name admin.oldboylinux.cn;
root /app/code/exam/front/admin/;
#前端
location / {
index index.html;
}
#后端
location /api/ {
proxy_pass http://localhost:8000;
}
}
server {
listen 80;
server_name stu.oldboylinux.cn;
root /app/code/exam/front/student/;
location / {
index index.html;
}
location /api/ {
proxy_pass http://localhost:8000;
}
}
- 联调
hosts解析
ip exam.oldboylinux.cn/student/
ip exam.oldboylinux.cn/admin/

浙公网安备 33010602011771号