作為 JEESZ 分布式框架的基礎組件,Tomcat 在 Linux 上的標準化部署直接關係到系統穩定性。本文記錄從上傳安裝包到防火牆放行、日誌分析的全流程操作,並補充生產級調優建議。
# 1. 上傳安裝包至 /usr/local scp apache-tomcat-7.0.61.tar.gz root@server:/usr/local/ # 2. 解壓並重命名(建議軟鏈接管理版本) cd /usr/local tar -zxvf apache-tomcat-7.0.61.tar.gz mv apache-tomcat-7.0.61 tomcat-7.0.61 ln -s tomcat-7.0.61 tomcat # 當前版本指向 # 3. 目錄結構速覽 tomcat/ ├── bin/ # 啟停腳本、環境變量 ├── conf/ # server.xml, web.xml, tomcat-users.xml ├── lib/ # 共享類庫 ├── logs/ # catalina.out, localhost_access_log... ├── webapps/ # 應用部署目錄 ├── work/ # JSP 編譯臨時文件 └── temp/ # 臨時文件
bin/setenv.sh#!/bin/bash # 建議創建而非修改 catalina.sh export JAVA_HOME=/usr/java/jdk1.8.0_202 export CATALINA_HOME=/usr/local/tomcat export CATALINA_BASE=/usr/local/tomcat # JVM 核心參數(按 4G 內存機器示例) export CATALINA_OPTS=" -server -Xms2g -Xmx2g -Xmn1g -MetaspaceSize=256m -MaxMetaspaceSize=512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/tomcat/heapdump.hprof -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom " # JMX 監控端口(生產需加認證/SSL) export JMX_OPTS=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=10.0.0.10 " export CATALINA_OPTS="$CATALINA_OPTS $JMX_OPTS"
關鍵點:
setenv.sh 不會被 Tomcat 覆蓋,升級版本時無需重複修改;-Xms -Xmx 設為物理內存 50%-60%,預留 OS Cache;-Djava.security.egd 解決熵源阻塞導致啟動慢。conf/server.xml 精簡版<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>
<Service name="Catalina">
<!-- HTTP 連接器(生產建議啟用 NIO2)-->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
maxThreads="200" minSpareThreads="20"
acceptCount="100" connectionTimeout="20000"
compression="on" compressableMimeType="text/html,text/xml,text/plain,text/css,application/json"
URIEncoding="UTF-8"/>
<!-- AJP 連接器(前置 Nginx 時使用)-->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
<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="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b %D" resolveHosts="false"/>
</Host>
</Engine>
</Service>
</Server>
調優亮點:
autoDeploy="false":生產禁用熱部署,防止誤操作導致服務抖動;compression="on":開啟 GZIP 壓縮,減少 70%+ 傳輸體積;protocol="Http11Nio2Protocol":非阻塞 I/O,高併發下吞吐更高;%D 記錄請求處理毫秒數,便於性能分析。# firewalld (CentOS 7 默認) firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --permanent --add-port=8009/tcp # AJP firewall-cmd --reload # 或 iptables 傳統方式 iptables -A INPUT -p tcp --dport 8080 -j ACCEPT service iptables save # 限制 Tomcat 進程用戶(不可 root 啟動) useradd -r -s /sbin/nologin tomcat chown -R tomcat:tomcat /usr/local/tomcat # systemd 服務文件 /etc/systemd/system/tomcat.service 以 tomcat 用戶啟動
# 啟動 systemctl start tomcat # 或 /usr/local/tomcat/bin/startup.sh tail -f /usr/local/tomcat/logs/catalina.out # 關鍵啟動成功標誌: # "Server startup in 3456 ms" # 停止 systemctl stop tomcat # 或 shutdown.sh # 強制殺進程最後手段 kill -9 $(pgrep -f tomcat) # 關鍵日誌文件 logs/ ├── catalina.out # 標準輸出/錯誤,首選排查入口 ├── localhost.YYYY-MM-DD.log # 容器級異常 ├── manager.YYYY-MM-DD.log # 管理應用日誌 └── access_log.YYYY-MM-DD.txt # 訪問日誌(配置了 AccessLogValve)
| 現象 | 排查方向 |
|---|---|
| 啟動卡住 "SecureRandom" | 配置 -Djava.security.egd=file:/dev/./urandom |
| 端口被佔用 | netstat -ntlp | grep 8080 找 PID kill 或改端口 |
| 中文亂碼 | Connector 加 URIEncoding="UTF-8",JVM 加 -Dfile.encoding=UTF-8 |
| OOM / GC 頻繁 | 分析 HeapDump,調大堆或排查內存洩漏(如 ThreadLocal、靜態集合) |
| Session 丟失 | 集群需配置 Session 複製或 Redis 共享,單機檢查 context.xml Manager 配置 |
「標準化部署是穩定性的基石,每一個參數都要經得起壓測推敲。把運維經驗固化成腳本和文檔,才能讓團隊在凌晨三點也能從容應對故障。」