-
jdk tomcat版本选择
jdk版本一般根据开发使用的版本为准1.8.0
jdk(Oracle官方)
a. rpm包安装
b. 二进制包
c. 源码(编译安装)
openJDK Linux (yum安装)tomcat 8.5
-
下载Jdk
进入官网
https://www.oracle.com/java/technologies/javase/jdk18-archive-downloads.html
下载tomcat
进入官网
https://tomcat.apache.org/download-80.cgi
通过xftp7软件传送到linux
-
解压安装jdk
[root@sunny2 ~]# tar -xvf jdk-18.0.1.1_linux-x64_bin.tar.gz -C /app/
jdk-18.0.1.1/LICENSE
jdk-18.0.1.1/README
jdk-18.0.1.1/bin/jar
jdk-18.0.1.1/bin/jarsigner
jdk-18.0.1.1/bin/java
jdk-18.0.1.1/bin/javac
查看jdk 安装
[root@sunny2 ~]# ll -h /app/
总用量 0
drwxr-xr-x 9 root root 136 5月 16 11:39 jdk-18.0.1.1
查看jdk 安装大小
[root@sunny tomcat]# du -sh /app/jdk-18.0.1.1/
305M /app/jdk-18.0.1.1/
创建软链接
[root@sunny2 ~]# ln -s /app/jdk-18.0.1.1/ /app/jdk
[root@sunny2 ~]# ll /app/
总用量 0
lrwxrwxrwx 1 root root 18 5月 16 11:45 jdk -> /app/jdk-18.0.1.1/
drwxr-xr-x 9 root root 136 5月 16 11:39 jdk-18.0.1.1
配置jdk环境变量
[root@sunny ~]# cat >>/etc/profile<<'EOF'
> export JAVA_HOME=/app/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
> export TOMCAT_HOME=/app/tomcat
> EOF
[root@sunny ~]# source /etc/profile
[root@sunny ~]# java -version
java version "18.0.1.1" 2022-04-22
Java(TM) SE Runtime Environment (build 18.0.1.1+2-6)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.1.1+2-6, mixed mode, sharing)
[root@sunny ~]# javac -version
javac 18.0.1.1
配置成功后输入java -version、javac -version可查看当前jdk安装信息.
安装tomcat
进入到tomcat文件中,将tomcat压缩包解压
[root@sunny ~]# tar -xvf apache-tomcat-8.5.78.tar.gz -C /app/
apache-tomcat-8.5.78/conf/
apache-tomcat-8.5.78/conf/catalina.policy
apache-tomcat-8.5.78/conf/catalina.properties
apache-tomcat-8.5.78/conf/context.xml
[root@sunny ~]# ll /app
总用量 0
drwxr-xr-x 9 root root 220 5月 16 14:14 apache-tomcat-8.5.78
lrwxrwxrwx 1 root root 18 5月 16 14:01 jdk -> /app/jdk-18.0.1.1/
drwxr-xr-x 9 root root 136 5月 16 14:00 jdk-18.0.1.1
[root@sunny ~]# ln -s /app/apache-tomcat-8.5.78/ /app/tomcat
检查tomcat+ jdk安装情况
[root@sunny ~]# /app/tomcat/bin/version.sh
Using CATALINA_BASE: /app/tomcat
Using CATALINA_HOME: /app/tomcat
Using CATALINA_TMPDIR: /app/tomcat/temp
Using JRE_HOME: /app/jdk
Using CLASSPATH: /app/tomcat/bin/bootstrap.jar:/app/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
Server version: Apache Tomcat/8.5.78
Server built: Mar 31 2022 16:05:28 UTC
Server number: 8.5.78.0
OS Name: Linux
OS Version: 3.10.0-1062.el7.x86_64
Architecture: amd64
JVM Version: 18.0.1.1+2-6
JVM Vendor: Oracle Corporation
- Tomcat 服务管理
/app/tomcat/bin/ startup.sh 启动tomcat
shutdown.sh 关闭tomcat
version.sh jdk与tomcat
catalina.sh tomcat核心脚本 startup shutdown
都会调用这个脚本
配置java启动参数,tomcat远程
管理,配置jvm参数
[root@sunny ~]# /app/tomcat/bin/startup.sh
Using CATALINA_BASE: /app/tomcat
Using CATALINA_HOME: /app/tomcat
Using CATALINA_TMPDIR: /app/tomcat/temp
Using JRE_HOME: /app/jdk
Using CLASSPATH: /app/tomcat/bin/bootstrap.jar:/app/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@sunny ~]# ss -lntup|grep java
tcp LISTEN 0 1 [::ffff:127.0.0.1]:8005 [::]:* users:(("java",pid=4043,fd=48))
tcp LISTEN 0 100 [::]:8080 [::]:* users:(("java",pid=4043,fd=40))
http://222.111.106.85:8080/
5. Tomcat 目录结构
目录 含义
conf/ tomcat配置文件
server.xml 主配置文件
web.xml 额外功能
tomcat-user.xml tomcat管理端配
置文件 用户名和密码
logs 日志
catalina.out tomcat最全日志 查看
error startup启动的时间
catalina.2019-13-2.log catalina.out
的日志
localhost_access_log.2019-12-12.txt tomcat access.log访问日志
webapps tomcat站点目录
tomcat对管理端限制更严格了, 页面打不开
修改tomcat-user.xml
[root@sunny ~]# vim /app/tomcat/conf/tomcat-users.xml
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>
重启tomcat服务
[root@sunny ~]# /app/tomcat/bin/shutdown.sh
[root@sunny ~]# ps -ef |grep java
root 55484 2943 0 15:18 pts/0 00:00:00 grep --color=auto java
[root@sunny ~]# /app/tomcat/bin/startup.sh
[root@sunny ~]# curl -u tomcat http://222.111.106.85:8080/manager/status
Enter host password for user 'tomcat':
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>403 Access Denied</title>
还是出现错误
[root@sunny ~]# curl -u tomcat http://127.0.0.1:8080/manager/status
Enter host password for user ‘tomcat’:
修改为127.0.0.1 就可以成功访问
a.要配置tomcat-user.xml
b.还限制只能在本地访问管理的
查找127配置的文件
[root@sunny tomcat]# find -type f -name "*.xml"| xargs grep '127'
./webapps/host-manager/META-INF/context.xml: allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
./webapps/host-manager/WEB-INF/manager.xml: allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
./webapps/manager/META-INF/context.xml: allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
\d 是perl正则,代表数据, 用\d+ 替换127.
[root@sunny tomcat]# find -type f -name "*.xml"| xargs grep '127' -l
./webapps/host-manager/META-INF/context.xml
./webapps/host-manager/WEB-INF/manager.xml
./webapps/manager/META-INF/context.xml
[root@sunny tomcat]# sed -i.bak 's#127#\\d+#g' ./webapps/host-manager/META-INF/context.xml
[root@sunny tomcat]# sed -i.bak 's#127#\\d+#g' ./webapps/host-manager/WEB-INF/manager.xml
[root@sunny tomcat]# sed -i.bak 's#127#\\d+#g' ./webapps/manager/META-INF/context.xml
重启tomcat后
检查进程
ps -ef | grep java
[root@sunny tomcat]# ps -ef | grep java
root 56223 1 2 15:54 pts/0 00:00:05 /app/jdk/bin/java -Djava.util.logging.config.file=/app/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 -Dignore.endorsed.dirs= -classpath /app/tomcat/bin/bootstrap.jar:/app/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/app/tomcat -Dcatalina.home=/app/tomcat -Djava.io.tmpdir=/app/tomcat/temp org.apache.catalina.startup.Bootstrap start
检查端口
ss -lntup | grep java
[root@sunny tomcat]# ss -lntup | grep java
tcp LISTEN 0 1 [::ffff:127.0.0.1]:8005 [::]:* users:(("java",pid=56223,fd=48))
tcp LISTEN 0 100 [::]:8080 [::]:* users:(("java",pid=56223,fd=40))
tomcat 日志
[root@sunny ~]# tail -f /app/tomcat/logs/catalina.out
- tomcat部署应用及方式
a. 如果开发给你的是war包, 直接把war包放入到tomcat webapps 自动解压 自动部署
b. 如果开发给你的是jar包 相当于把tomcat放到jar中 命令: java -jar xxxx.jar
cp /app/tools/jpress.war ./app/tomcat/webapps/
- tomcat 3种工作模式:bio , nio , apr
bio blocking io tomcat7及之前,同步模型 阻塞 一个线程处理一个请求 缺点: 并发量高时,线程数较多,浪费资源。
nio new io tomcat8及以后的工作模式 异步 非阻塞 可以通过少量的线程处理大量的请求
apr apache portable runtime Tomcat对静态文件的处理性能,tomcat apr也是在tomcat上运行高并发应用的首选模式
- tomcat 监控
a. 使用命令进行监控
ps 和jps 命令
#ps -ef | grep java
jps命令是java jdk 自带的命令
jps -l
配置远程监控
修改/app/tomcat/bin/catalina.sh
添加命令:
# -----------------------------------------------------------------------------
CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote \
-Dcom.sun.mangement.jmxremote.port=12345 \
-Dcom.sun.mangement.jmxremote.authenticate=false \
-Dcom.sun.mangement.jmxremote.ssl=false \
-Djava.rmi.server.hostname=222.111.105.251"
注意分行写命令要加 \
重启tomcat, 查看运行情况
[root@sunny ~]# ss -lntup | grep java
tcp LISTEN 0 1 [::ffff:222.111.105.251]:8005 [::]:* users:(("java",pid=6468,fd=46))
tcp LISTEN 0 1 [::ffff:127.0.0.1]:8005 [::]:* users:(("java",pid=6269,fd=50))
tcp LISTEN 0 50 [::]:43016 [::]:* users:(("java",pid=6468,fd=14))
tcp LISTEN 0 50 [::]:43375 [::]:* users:(("java",pid=6269,fd=14))
tcp LISTEN 0 100 [::]:8080 [::]:* users:(("java",pid=6269,fd=45))
使用Jconsole.exe(jdk自带工具)模拟zabbix远程管理。
-
tomcat相关故障与排错
9.1. 背景:
a. tomcat环境使用的jdk是二进制
b. tomcat 设置开机自启动
使用二进制安装的jdk ,环境变量不在/bin /sbin /usr/local/bin
在重启时没有找到命令
即使在/etc/profile/ 中也没有找到
需要这样配置
#vim /etc/rc.local
. /etc/profile
/app/tomcat/bin/startup.sh
9.2. tomcat(java) 服务器运行占用大量swap 物理内存占用少
Linux内核参数:
/etc/sysctl.conf
sysctl -p #内核参数生效
vm.swappiness=0 #控制系统是否优先使用物理内存 数值越少,越优先使用物理内存
9.3 tomcat负载高 如何排查
排查流程:
a. 整体排查:vmstat /top/ps aux 找出哪个进程的问题
b. 找出进程对应线程id:通过top -Hp java进程ID (找出哪个线程有问题)
c. 转换线程ID到16进制: 问题线程的id 转为16进制 线程id
d. 找出线程的详细信息:jstack 进程id | grep -i 线程id -A 10
e. 显示jvm 信息: jmap 显示jvm的内存使用情况
f. jvm 内存内容导出:jmap 显示jvm内存的内容
g. 给开发分析jvm导出文件:通过mat(Eclipse memory analyzer tool )分析
- 使用VMstat 查看运行情况
vmstat 1 10 1(代表每一秒更新10行数据)
10 (代表更新的行数)
[root@sunny yum.repos.d]# vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
4 0 264 158592 212 704544 0 0 26 10 175 238 1 1 98 0 0
0 0 264 158560 212 704544 0 0 0 0 208 333 4 1 95 0 0
0 0 264 158560 212 704544 0 0 0 0 207 330 4 1 95 0 0
1 0 264 158560 212 704544 0 0 0 0 183 289 3 1 96 0 0
0 0 264 159268 212 704544 0 0 0 0 238 339 8 2 90 0 0
0 0 264 159336 212 704544 0 0 0 0 217 342 4 1 95 0 0
2 0 264 159336 212 704544 0 0 0 0 199 332 3 1 96 0 0
- 查看进程和线程命令
ps aux 或 top 或htop 查看进程的占用cpu,内存情况
iotop 查看进程io流情况
top -Hp 进程号(6468)
-H 查看进程相关的 线程
-p 进程号
例如:
#jps -lvm
[root@sunny yum.repos.d]# jps -lvm
12226 jdk.jcmd/sun.tools.jps.Jps -lvm -Denv.class.path=.:/app/jdk/lib:/app/jdk/jre/lib:/app/jdk/lib/tools.jar -Dapplication.home=/app/jdk-18.0.1.1 -Xms8m -Djdk.module.main=jdk.jcmd
6468
#top -Hp 6468
查找进程号相关的线程
root@sunny yum.repos.d]# top -Hp 6468
top - 11:08:42 up 9:07, 3 users, load average: 0.00, 0.01, 0.05
Threads: 17 total, 0 running, 17 sleeping, 0 stopped, 0 zombie
%Cpu(s): 15.1 us, 5.2 sy, 0.0 ni, 79.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1863076 total, 160652 free, 997336 used, 705088 buff/cache
KiB Swap: 2097148 total, 2096884 free, 264 used. 679552 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6468 root 20 0 2665424 99552 21240 S 0.0 5.3 0:00.00 java
**6472** root 20 0 2665424 99552 21240 S 0.0 5.3 0:00.93 java
如果没有htop, 首先安装
root@sunny yum.repos.d]# yum install epel-release
[root@sunny yum.repos.d]# yum -y intall htop
- 问题线程号转16进制
[root@sunny yum.repos.d]# echo 'obase=16;10' |bc
A
[root@sunny yum.repos.d]# echo 'obase=16;6472' |bc
1948
- jstack 导出java进程 线程的问题信息,进而解决问题
#jstack 进程号 | grep -i 线程号 -A 10 (-A 10 代表显示10行)
#jstack 6468 |grep -i 6477 -A 10
[root@sunny yum.repos.d]# jstack 6468 | grep -i 6477
"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=1.02ms elapsed=21105.87s tid=0x00007ff8d40a93c0 nid=6477 waiting on condition [0x00007ff8da99d000]
[root@sunny yum.repos.d]# jstack 6468 | grep -i 6477
"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=1.02ms elapsed=21113.09s tid=0x00007ff8d40a93c0 nid=6477 waiting on condition [0x00007ff8da99d000]
[root@sunny yum.repos.d]# jstack 6468 | grep -i 6477 -A 10
"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=1.02ms elapsed=21117.26s tid=0x00007ff8d40a93c0 nid=6477 waiting on condition [0x00007ff8da99d000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@18.0.1.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@18.0.1.1/Reference.java:253)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@18.0.1.1/Reference.java:215)
"Finalizer" #3 daemon prio=8 os_prio=0 cpu=0.14ms elapsed=21117.26s tid=0x00007ff8d40aa9c0 nid=6478 in Object.wait() [0x00007ff8da89c000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@18.0.1.1/Native Method)
- waiting on <0x00000000ed2e6150> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@18.0.1.1/ReferenceQueue.java:155)
[root@sunny yum.repos.d]# jstack 6468 | grep -i 6480 -A 20
"Service Thread" #5 daemon prio=9 os_prio=0 cpu=1.42ms elapsed=21380.66s tid=0x00007ff8d40b1fa0 nid=6480 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Deflation Thread" #6 daemon prio=9 os_prio=0 cpu=1310.16ms elapsed=21380.66s tid=0x00007ff8d40b3470 nid=6481 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=0 cpu=3128.38ms elapsed=21380.66s tid=0x00007ff8d40b4f20 nid=6482 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"C1 CompilerThread0" #8 daemon prio=9 os_prio=0 cpu=1642.49ms elapsed=21380.65s tid=0x00007ff8d40b6530 nid=6483 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"Sweeper thread" #9 daemon prio=9 os_prio=0 cpu=6.96ms elapsed=21380.65s tid=0x00007ff8d40b76a0 nid=6484 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Common-Cleaner" #10 daemon prio=8 os_prio=0 cpu=53.35ms elapsed=21380.62s tid=0x00007ff8d40c2ba0 nid=6485 in Object.wait() [0x00007ff8da195000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(java.base@18.0.1.1/Native Method)
- waiting on <no object reference available>
-
与jvm相关的jmap导出或者显示jvm信息
a. 显示jvm的使用情况 一共多少使用多少 剩余多少
b. 导出jvm内存信息 数据等等导出到磁盘
#jmap -heap javapid -
jvm 内存内容导出
jmap -dump:format=b,file=/root/tomcat.bin pid
7.通过mat分析