下载

镜像仓库:https://mirrors.cnnic.cn/apache/tomcat/

所有版本:https://archive.apache.org/dist/tomcat/

https://tomcat.apache.org/download-90.cgi

推荐 Windows 安装文件版本

image-20200624110102910

安装

apache-tomcat-9.0.36.exe

启动

image-20200704093031416

JVM 可视化工具

参考 《Java-JVM》,使用 JDK 自带工具 jconsole.exejvisualvm.exe

线程、连接数、最大上传大小

连接数配置「提高 CPU 利用率」

Apache Tomcat 9 Configuration Reference

server.xml

1
<Connector connectionTimeout="20000" port="8000" protocol="HTTP/1.1" maxPostSize="20485760" URIEncoding="UTF-8" redirectPort="8443" acceptCount="500" maxThreads="500"/>

配置内存

  1. 远程代码调试,详细参考《IDEA-远程调试》

    1
    -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=9000
  2. JVM 内存配置「提高内存利用率」

    • catalina.bat

      1
      set JAVA_OPTS=-server -Xms4g -Xmx8g
    • catalina.sh

      1
      JAVA_OPTS="-server -Xms4g -Xmx8g"

    说明:-server 参数:表示以服务模式启动,启动速度会稍微慢一点,但性能会高很多。不加这个参数,默认是以客户端模式启动

    • 服务运行-可视化配置

      1
      2
      3
      4
      5
      6
      7
      -XX:+UseG1GC
      -XX:MaxGCPauseMillis=500
      -XX:ParallelGCThreads=4
      -XX:+PrintGCDetails
      -XX:+PrintGCTimeStamps
      -XX:+PrintGCDateStamps
      -Xloggc:./gc.log
    image-20200713172611523 image-20200805200439378

    根据运行情况,配置上述参数:参考:

    参数名称 含义 默认值
    -Xms 初始堆大小 物理内存的 1/64 (<1GB) 默认 (MinHeapFreeRatio 参数可以调整) 空余堆内存小于 40% 时,JVM 就会增大堆直到 - Xmx 的最大限制.
    -Xmx 最大堆大小 物理内存的 1/4 (<1GB) 默认 (MaxHeapFreeRatio 参数可以调整) 空余堆内存大于 70% 时,JVM 会减少堆直到 -Xms 的最小限制
    -Xss 每个线程的堆栈大小 JDK5.0 以后每个线程堆栈大小为 1M, 以前每个线程堆栈大小为 256K. 更具应用的线程所需内存大小进行 调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在 3000~5000 左右
    一般小的应用, 如果栈不是很深, 应该是 128k 够用的 大的应用建议使用 256k。这个选项对性能影响比较大,需要严格的测试。(校长)
    和 threadstacksize 选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:””
    -Xss is translated in a VM flag named ThreadStackSize”
    一般设置这个值就可以了。
    -Xmn 年轻代大小 (1.4or lator) eden + 2 survivor space 注意: 与 jmap -heap 中显示的 New gen 是不同的。 增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun 官方推荐配置为整个堆的 3/8
    -XX:SurvivorRatio Eden 区与 Survivor 区的大小比值 设置为 8, 则两个 Survivor 区与一个 Eden 区的比值为 2:8, 一个 Survivor 区占整个年轻代的 1/10
    -XX:PermSize 设置持久代 (perm gen) 初始值 物理内存的 1/64
    -XX:MaxPermSize 设置持久代最大值 物理内存 的 1/4
    -XX:NewRatio 年轻代 (包括 Eden 和两个 Survivor 区) 与年老代的比值 (除去持久代) -XX:NewRatio=4 表示年轻代与年老代所占比值为 1:4, 年轻代占整个堆栈的 1/5
    Xms=Xmx 并且设置了 Xmn 的情况下,该参数不需要进行设置。
  3. CATALINA_HOME 与 CATALINA_BASE

    注意:不要在环境变量中加入这两个变量,否则启动多个Tomcat错误

  • CATALINA_HOME 是 Tomcat 的安装目录,CATALINA_BASE 是 Tomcat 的工作目录
  • 使用场景:一个 Tomcat 运行多个实例。Tomcat 中 bin、lib 目录为公用目录,其它目录每个实例都有一份,各自配置,独立运行。
  • 参考 https://blog.csdn.net/jiaotuwoaini/article/details/51455829

服务运行

  1. 安装 JDK 并配置环境变量 JAVA_HOME

  2. 进入 Tomcat/bin目录,执行 ./service.bat install 安装服务

  3. 执行./service.bat remove 卸载服务

  4. 在「服务」中修改启动类型「手动、自动、禁用等」,启动、停止、重启服务

  5. 修改服务名Tomcat8,打开service.bat

    1
    2
    set SERVICE_NAME=Tomcat8
    set DISPLAYNAME=Apache Tomcat 8.0 %SERVICE_NAME%
    image-20200526181435910

指定项目目录发布

server.xml Host 内部添加

1
<Context docBase="scm" path="../scm" reloadable="true"/>

Web 控制台管理页面配置

  1. 修改 conf/tomcat-users.xml,加入账号密码验证

    1
    2
    3
    4
    <role rolename="admin-gui"/>
    <role rolename="manager-gui"/>
    <role rolename="manager-script"/>
    <user username="admin" password="admin123456" roles="manager-gui,admin-gui,manager-script"/>
  2. 修改 webapps/manager/META-INF/context.xmlwebapps/host-manager/META-INF/context.xml注释掉下面内容

    1
    2
    3
    4
    5
    <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

    或者改为
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
    allow="^.*$" />
  3. 默认支持上传war 文件最大大小为 50MB,修改为 500MB

    webapps/manager/WEB-INF/web.xml

    1
    2
    3
    4
    5
    6
    <multipart-config>
    <!-- 500MB max -->
    <max-file-size>524288000</max-file-size>
    <max-request-size>524288000</max-request-size>
    <file-size-threshold>0</file-size-threshold>
    </multipart-config>

注意

  1. 360 浏览器中,Web 控制台页面点击Server StatusManager App没有反应,可能是浏览器兼容性问题,需要切换为极速模式

  2. Tomcat 远程无法访问情况,如果防火墙打开,注意将 Tomcat 端口添加到「入站规则」中

定时重启 Tomcat

Linux

  1. 重启 Tomcat 脚本文件restarttomcat.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/bin/bash

    export LANG=zh_CN.UTF-8
    export JAVA_HOME=/usr/java/jdk1.8.0_191
    export JRE_HOME=$JAVA_HOME/jre
    export CATALINA_BASE=/home/wangwz/Desktop/apache-tomcat-8.0.53
    export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$CATALINA_BASE/bin:$PATH
    export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH

    echo "[$(date +'%F %T')] >>> Tomcat begin to restart."
    $CATALINA_BASE/bin/shutdown.sh

    # Kill all remaining processes
    pidList=$(ps aux | grep $CATALINA_BASE | grep -v grep | awk '{print $2}')
    for pid in $pidList; do
    kill -9 $pid
    echo "[$(date +'%F %T')] >>> Kill the process [$pid] successfully."
    done

    sleep 5
    $CATALINA_BASE/bin/startup.sh
    echo "[$(date +'%F %T')] >>> Tomcat restart complete."
  2. 授权

    1
    2
    //赋予可执行权限命令
    chmod 777 restarttomcat.sh
  3. 执行

    1
    2
    //执行命令-单独执行模式
    nohup ./restarttomcat.sh &
  4. 定时重启

    1
    2
    3
    4
    5
    6
    7
    crontab -e

    添加内容如下:
    0 1 * * * /bin/bash /home/wangwz/Desktop/restarttomcat.sh >> /home/restart.log

    查看:
    crontab -l

    crontab定时器:https://www.cnblogs.com/zoulongbin/p/6187238.html

Windows

  1. 重启脚本文件 restart_tomcat_service.bat以服务形式启动或停止」,Tomcat8 为服务名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @echo off
    rem 停止服务,删除日志文件和缓存文件,启动服务

    echo %date% %time% >> D:\Tomcat8\restart_service.log

    net stop Tomcat8 >> D:\Tomcat8\restart_service.log
    ping 127.0.0.1 -n 5
    del /f /s /q "D:\Tomcat8\logs\*"
    ping 127.0.0.1 -n 5
    net start Tomcat8 >> D:\Tomcat8\restart_service.log
  2. 定时任务脚本 task_restart_tomcat_service.bat,每天 1:00 执行重启脚本

    1
    schtasks /create /tn "task_restart_tomcat_service" /tr "D:\Tomcat8\restart_tomcat_service.bat" /sc daily /st 01:00:00

定时重启 Tomcat 及 Windows 服务器

  1. Tomcat 服务随系统启动
  2. 创建脚本,内容如下
  3. 创建定时任务,选择脚本

脚本内容解释:先停止 Tomcat 服务,并记录日志。10 秒后,重启服务器

1
2
3
4
5
6
7
8
9
echo %date% %time% >> D:\Tomcat8\restart_service.log

net stop Tomcat8 >> D:\Tomcat8\restart_service.log
ping 127.0.0.1 -n 5
del /f /s /q "D:\Tomcat8\logs\*"
ping 127.0.0.1 -n 5

#其中,-r 表示重启,-f 表示强制关闭正在运行的程序,-t 0 表示立即重启
shutdown.exe -r -f -t 0

检测 Tomcat 服务运行状态

检测服务运行状态,服务没有运行则启动

Windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@echo off
rem 定义窗口自动关闭时间和监测的服务名称:
set secs=10
set srvname="Tomcat90"
echo.
echo ========================================
echo == 查询计算机服务的状态, ==
echo == 如发现其停止,则立即启动。 ==
echo ========================================
echo.
echo 此脚本监测的服务是:% srvname%
echo.
if %srvname%. == . goto end
:chkit
set svrst=0
for /F "tokens=1* delims= " %%a in ('net start') do if /I "%%a %%b" == %srvname% set svrst=1
if %svrst% == 0 net start %srvname%
set svrst=
rem 下面的命令用于延时,否则可能会导致 cpu 单个核心满载。
:end
rem 下面的命令用于延时自动关闭窗口
ping -n %secs% 127.0.0.1 > nul
exit

Linux

参考:https://blog.csdn.net/ZERO_TO_NIL/article/details/79588730

原理:查看进程是否存在,不存在则启动;存在则请求项目,返回正常,则表示系统正常,异常,则重启服务「停止、启动」

检测脚本 monitor.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#tomcat监控脚本,记录tomcat运行状况,并在系统出现异常的时候重启服务

# 获取线程ID,执行该命令,可以得到tomcat线程,grep -w用于执行单词搜索
TomcatID=$(ps -ef |grep tomcat |grep -w 'apache-tomcat-8.5.20'|grep -v 'grep'|awk '{print $2}')

# tomcat启动的脚本文件,一般位于tomcat服务器bin目录下面
StartTomcat=/tal/apache-tomcat-8.5.20/bin/startup.sh

# 项目的一个方法,该方法只要能够请求到,则返回成功
WebUrl=http://47.92.108.67:8080/ProjectSystem/shTest

#tomcatwork空间
TomcatCache=/tal/apache-tomcat-8.5.20/work

# 日志输出地址
GetPageInfo=/dev/null
TomcatMonitorLog=/tmp/TomcatMonitor.log

#监控的代码
Monitor()
{
#输出到日志文件,并将时间保存
echo "[info]开始监控tomcat...[$(date +'%F %H:%M:%S')]"
#查看tomcatID,如果存在,则进入处理逻辑,如果不存在,则重启tomcat
if [ $TomcatID ];then
#记录日志
echo "[info]tomcat进程ID为:$TomcatID."
# 请求项目,$WebUrl是相应的请求地址,该命令执行之后会得到相应的线程ID
TomcatServiceCode=$(curl -s -o $GetPageInfo -m 10 --connect-timeout 10 $WebUrl -w %{http_code})
#系统运行正常
if [ $TomcatServiceCode -eq 200 ];then
echo "[info]返回码为$TomcatServiceCode,tomcat运行正常."
else
#系统运行异常
echo "[error]访问出错,状态码为$TomcatServiceCode,错误日志已输出到$GetPageInfo"
echo "[error]开始重启tomcat"
#杀掉相应的进程
kill -9 $TomcatID # 杀掉原tomcat进程
./email.sh
sleep 1
#清理work空间
rm -rf $TomcatCache # 清理tomcat缓存
#重启
$StartTomcat
fi
else
echo "[error]进程不存在!tomcat自动重启..."
echo "[info]$StartTomcat,请稍候......"
#rm -rf $TomcatCache
$StartTomcat
fi
echo "------------------------------"
}
Monitor>>$TomcatMonitorLog

脚本增加可执行权限

1
chmod +x monitor.sh

添加定时任务

1
2
3
4
crontab -e

#每 1 小时执行一次
0 0 */1 * * * /home/zhangsan/monitor.sh

定期删除日志文件

  1. 删除日志文件脚本delete_tomcat_logs.bat

    1
    del /f /s /q "C:\Tomcat8.0.53\logs\*"
  2. 定时任务脚本task_delete_tomcat_logs.bat,每月第一天执行删除日志脚本

    1
    schtasks /create /tn "task_delete_tomcat_logs" /tr "C:\Tomcat8.0.53\delete_tomcat_logs.bat" /sc monthly

定时备份项目

项目 xxx,路径D:\Tomcat8.0.53\webapps\xxx

  1. 备份脚本 bak_project_xxx.bat

    1
    2
    3
    4
    set sourcefolder=C:\Tomcat8.0.53\webapps\xxx
    set bakfolder=C:\Tomcat8.0.53\bak\%date:~0,4%%date:~5,2%%date:~8,2%\xxx
    if not exist %bakfolder% (mkdir %bakfolder%)
    xcopy %sourcefolder% %bakfolder% /e
  2. 定时任务脚本task_bak_project_xxx.bat,每月第一天执行

    1
    2
    rem 每月第一天2:00执行脚本
    schtasks /create /tn "task_bak_project_xxx" /tr C:\bak_project_xxx.bat /sc monthly /st 02:00:00

Tomcat 日志排查问题

  1. 项目日志文件: tomcat/bin/XXX.log XXX.log 日志文件名称在项目 log4j.properties 中配置

    项目运行过程中报 500 错误时,从该日志文件查找原因

  2. Tomcat 日志文件: tomcat/logs/catalina.out tomcat/logs/catalina.yyyy-mm-dd.log

    Tomcat 报错问题

  3. 查看方法

    • 日志文件较小时,10Mb 以内。windows 平台中直接打开查看,例如使用 notepad++等。Linux 平台中可以将文件拷贝至 windows 中查看,也可通过命令 less 文件名 查看文件,大写字母 G 快速跳转至文件尾部,Ctrl u 向上翻页,Ctrl d 向下翻页
    • 日志文件较大时,10Mb 以上。windows 平台中借助 LogViewer 工具查看。Linux 平台通过上述 less 等命令查看

tomcat 控制台中文乱码问题

  1. 打开 conf/logging.properties

  2. 添加语句

    1
    java.util.logging.ConsoleHandler.encoding = GBK
  3. 重启 tomcat

项目中 Http 获取的数据存在中文乱码

解决:在 tomcat 的 catalina.bat 文件中加上-Dfile.encoding=”UTF-8”

1
set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8"

Tomcat错误页面泄露服务器版本信息

  1. 进入到tomcat/lib目录下,直接解压catalina.jar 进入到\org\apache\catalina\util目录下

  2. 编辑ServerInfo.properties文件,编辑最后三行,去掉版本号等信息

    1
    2
    3
    server.info=Apache Tomcat
    server.number=0.0.0.0
    server.built=Nov 7 2016 20:05:27 UTC
  3. 将修改后的信息压缩回jar包

    1
    2
    cd  /tomcat/lib
    jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties
  4. 重启tomcat

APACHE TOMCAT 文件包含漏洞(CVE-2020-1938)

http://blog.nsfocus.net/cve-2020-1938/