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

image-20260119103106694

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 访问日志,未来可以重新定义名字和内容
  1. webapps
  • 站点目录
  • war包,自动解压,自动部署

1.6 Tomcat日常管理与访问

  1. 日常启动与维护

image-20260119103502499

image-20260119103546546

  1. 书写systemctl管理配置文件进行管理
  • 服务管理指令.
  • 存放在/usr/lib/systemd/system/xxx.service
  • 分为 3 个部分.
  • 修改或设置 systemctl 配置要进行重新加载配置.
systemctl 配置文件的结构 说明
[Unit] 指定注释信息,依赖 (先后顺序)
Description 说明与注释
After 在这里指定的服务之后运行. network.target
[Service] 用于指定服务开启命令,关闭命令,重启命令.
Type=notify 指定类型 simpleforking即可
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 地址访问管理端。

image-20260119114111112

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 &quot;%r&quot; %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
" , &quot; 表示双引号.

pattern="%h %l %u %t &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />

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 &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />
        </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 &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />
</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

image-20260119151943072

image-20260119151955515

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)

  1. 需要jdk环境
  2. 软件包解压即可使用
  3. 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 &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />

  </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 表示配置完成)

image-20260119161405673

设置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
  1. 部署后端
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;
  }
}
  1. 联调

hosts解析
ip exam.oldboylinux.cn/student/
ip exam.oldboylinux.cn/admin/

posted @ 2026-01-19 17:57  gzjwo  阅读(0)  评论(0)    收藏  举报