yuanxiaojiang
人的放纵是本能,自律才是修行

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 &quot;%r&quot; %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 &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;"
# &quot:表示双引号

 

部署应用

  部署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

 

posted on 2025-03-11 18:46  猿小姜  阅读(54)  评论(0)    收藏  举报

levels of contents