1. CentOS 7环境下Tomcat 8.5的安装部署
1.1 系统环境准备
在开始安装Tomcat之前,我们需要先准备好CentOS 7的基础环境。我建议使用最小化安装的CentOS 7系统,这样可以减少不必要的服务和资源占用。以下是基础环境配置步骤:
首先,我们需要创建标准的目录结构来存放软件和运行数据:
mkdir /software # 用于存放安装包 mkdir /data # 用于存放运行数据 mkdir /script # 用于存放维护脚本接下来,我们需要检查并清理系统中可能存在的旧版本Java:
rpm -qa | grep java rpm -e --nodeps java* # 强制卸载所有Java相关包1.2 JDK 8安装配置
Tomcat 8.5需要JDK 7或更高版本支持,这里我们选择JDK 8作为运行环境。以下是详细的安装步骤:
- 下载JDK 8安装包(建议使用Oracle JDK):
cd /software wget http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.tar.gz- 解压并安装JDK:
tar zxvf jdk-8u161-linux-x64.tar.gz mv jdk1.8.0_161 /data/jdk ln -s /data/jdk /usr/local/JAVA- 配置环境变量: 编辑/etc/profile文件,在末尾添加以下内容:
export JAVA_HOME=/usr/local/JAVA export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar- 使配置生效并验证安装:
source /etc/profile java -version1.3 Tomcat 8.5安装配置
完成JDK安装后,我们可以开始安装Tomcat 8.5:
- 下载Tomcat 8.5安装包:
cd /software wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.28/bin/apache-tomcat-8.5.28.tar.gz- 解压并安装Tomcat:
tar zxvf apache-tomcat-8.5.28.tar.gz cp -r apache-tomcat-8.5.28 /data/Tomcat-Pay- 配置Tomcat启动脚本:
# 启动Tomcat /data/Tomcat-Pay/bin/startup.sh # 停止Tomcat /data/Tomcat-Pay/bin/shutdown.sh # 查看版本信息 /data/Tomcat-Pay/bin/version.sh- 设置开机自启动:
chmod +x /etc/rc.d/rc.local echo '/data/Tomcat-Pay/bin/startup.sh' >> /etc/rc.d/rc.local2. APR安装与性能优化
2.1 APR简介与依赖安装
APR(Apache Portable Runtime)是一个高度可移植的库,能够显著提升Tomcat的性能。在生产环境中,使用APR模式可以带来以下优势:
- 更好的IO性能(支持sendfile、epoll等)
- 更高效的SSL处理(通过OpenSSL)
- 更优的本地进程处理能力
安装APR前需要先安装依赖包:
yum -y install gcc gcc-c++ libtool* autoconf automake expat-devel perl perl-devel2.2 APR组件安装步骤
- 下载并安装APR核心库:
cd /software wget http://mirror.bit.edu.cn/apache/apr/apr-1.6.2.tar.gz tar zxvf apr-1.6.2.tar.gz cd apr-1.6.2 ./configure --prefix=/usr/local/apr make && make install- 安装APR-iconv(字符集转换库):
wget http://mirror.bit.edu.cn/apache/apr/apr-iconv-1.2.2.tar.gz tar zxvf apr-iconv-1.2.2.tar.gz cd apr-iconv-1.2.2 ./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr make && make install- 安装APR-util(工具库):
wget http://mirror.bit.edu.cn/apache/apr/apr-util-1.6.0.tar.gz tar zxvf apr-util-1.6.0.tar.gz cd apr-util-1.6.0 ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv make && make install- 安装OpenSSL(加密支持):
wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz tar zxvf openssl-1.1.0f.tar.gz cd openssl-1.1.0f ./config --prefix=/usr/local/openssl make -j 4 && make install2.3 Tomcat-native安装与配置
- 安装tomcat-native:
cd /data/Tomcat-Pay/bin tar zxvf tomcat-native.tar.gz cd tomcat-native-1.2.12-src/native ./configure --with-ssl=/usr/local/openssl --with-apr=/usr/local/apr --with-java-home=/usr/local/JAVA make && make install- 配置环境变量:
echo 'export LD_LIBRARY_PATH=/usr/local/apr/lib:$LD_LIBRARY_PATH' > /etc/profile.d/apr.sh source /etc/profile.d/apr.sh- 修改Tomcat配置使用APR模式: 编辑/data/Tomcat-Pay/conf/server.xml文件,修改Connector配置:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" redirectPort="8443" />- 验证APR模式是否生效: 重启Tomcat后检查日志,应该能看到类似以下信息:
INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-apr-8080"]3. Tomcat生产环境调优
3.1 线程池优化配置
在生产环境中,合理的线程池配置对性能至关重要。以下是优化建议:
- 在server.xml中配置线程池:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1000" minSpareThreads="25" maxIdleTime="600000" acceptCount="500"/>参数说明:
- maxThreads:最大线程数,根据服务器CPU核心数设置(建议500-1000)
- minSpareThreads:最小空闲线程数,建议设置为maxThreads的5-10%
- maxIdleTime:线程空闲超时时间(毫秒)
- acceptCount:等待队列长度,当所有线程都在忙时,新请求会进入队列
- 在Connector中引用线程池:
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />3.2 连接器高级优化
对于生产环境,还需要对连接器进行更细致的优化:
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000" keepAliveTimeout="15000" maxKeepAliveRequests="1000" useURIValidationHack="false" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="8443"/>关键优化点:
- enableLookups="false":禁用DNS查询,减少延迟
- disableUploadTimeout="true":上传文件时不限制超时时间
- compression="on":启用GZIP压缩,减少网络传输量
- keepAliveTimeout:长连接超时时间
- maxKeepAliveRequests:单个长连接上允许的最大请求数
3.3 JVM内存优化配置
JVM参数优化对Tomcat性能影响极大。以下是针对生产环境的JVM配置建议:
在catalina.sh中添加:
export JAVA_OPTS="-server -Xms3072M -Xmx3072M -Xmn512M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSMaxAbortablePrecleanTime=5 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Djava.awt.headless=true"参数说明:
- -Xms和-Xmx:堆内存初始值和最大值,建议设置为相同值(物理内存的70-80%)
- -Xmn:新生代大小,建议为堆内存的1/4到1/3
- -XX:+UseConcMarkSweepGC:使用CMS垃圾收集器,减少停顿时间
- -XX:CMSInitiatingOccupancyFraction=70:老年代使用率达到70%时触发CMS GC
3.4 运行模式选择与对比
Tomcat支持三种运行模式,生产环境建议使用APR或NIO2模式:
- BIO(阻塞式IO):
- 默认模式
- 每个请求需要一个线程处理
- 并发性能较差
- NIO(非阻塞式IO):
- 使用Java NIO实现
- 适合中等并发场景
- 配置方式:protocol="org.apache.coyote.http11.Http11NioProtocol"
- APR(Apache Portable Runtime):
- 性能最优
- 需要额外安装native库
- 配置方式:protocol="org.apache.coyote.http11.Http11AprProtocol"
4. 生产环境安全加固
4.1 基础安全配置
- 禁用管理控制台:
rm -rf /data/Tomcat-Pay/webapps/*- 修改关闭端口和命令: 编辑server.xml,修改Server配置:
<Server port="-1" shutdown="SHUTDOWN">- 禁用自动部署:
<Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false" reloadable="false">4.2 隐藏版本信息
- 修改ServerInfo.properties文件:
cd /data/Tomcat-Pay/lib unzip catalina.jar cd org/apache/catalina/util vim ServerInfo.properties修改内容为:
server.info=Apache Tomcat server.number= server.built=- 重新打包:
jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties4.3 连接器安全优化
生产环境连接器建议配置:
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="60000" maxConnections="10000" redirectPort="8443" enableLookups="false" acceptCount="100" maxPostSize="10485760" maxHttpHeaderSize="8192" compression="on" disableUploadTimeout="true" compressionMinSize="2048" acceptorThreadCount="2" compressableMimeType="text/html,text/plain,text/css,application/javascript,application/json,application/x-font-ttf,application/x-font-otf,image/svg+xml,image/jpeg,image/png,image/gif,audio/mpeg,video/mp4" URIEncoding="utf-8" processorCache="20000" tcpNoDelay="true" connectionLinger="5" server="Server Version 11.0" />关键安全参数:
- maxPostSize:限制POST请求大小(10MB)
- maxHttpHeaderSize:限制HTTP头大小(8KB)
- server:隐藏Tomcat版本信息
- enableLookups:禁用DNS查询
4.4 文件系统权限控制
- 创建专用运行用户:
groupadd tomcat useradd -g tomcat -d /data/Tomcat-Pay -s /bin/false tomcat chown -R tomcat:tomcat /data/Tomcat-Pay- 目录权限设置:
chmod 750 /data/Tomcat-Pay chmod 750 /data/Tomcat-Pay/conf chmod 640 /data/Tomcat-Pay/conf/*- 日志目录权限:
chmod 750 /data/Tomcat-Pay/logs5. 监控与维护
5.1 日志配置与管理
- 配置日志轮转: 创建/etc/logrotate.d/tomcat文件:
/data/Tomcat-Pay/logs/catalina.out { copytruncate daily rotate 30 compress missingok size 100M }- 配置访问日志: 在server.xml中添加:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b %D" />5.2 JVM监控配置
- 启用GC日志: 在JAVA_OPTS中添加:
-Xloggc:/data/Tomcat-Pay/logs/gc.log -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDetails- 配置JMX远程监控:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false5.3 性能监控工具
- 使用jstat监控JVM状态:
jstat -gcutil <pid> 1000 10- 使用jstack分析线程状态:
jstack <pid> > /tmp/thread_dump.txt- 使用VisualVM进行图形化监控:
jvisualvm5.4 常见问题排查
- 内存泄漏排查步骤:
- 使用jmap生成堆转储文件
- 使用MAT工具分析内存占用
- 检查是否有未关闭的资源
- 线程阻塞排查:
- 使用jstack获取线程快照
- 查找BLOCKED状态的线程
- 分析锁竞争情况
- CPU过高排查:
- 使用top -H找出高CPU线程
- 使用jstack分析线程堆栈
- 定位热点代码
6. 高级调优技巧
6.1 内核参数优化
- 修改文件描述符限制:
echo "* soft nofile 65535" >> /etc/security/limits.conf echo "* hard nofile 65535" >> /etc/security/limits.conf- 调整TCP/IP参数:
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf echo "net.ipv4.tcp_tw_recycle = 1" >> /etc/sysctl.conf echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf sysctl -p6.2 会话持久化配置
- 配置JDBC会话存储:
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true" maxActiveSessions="-1" minIdleSwap="0" maxIdleSwap="30" maxIdleBackup="0"> <Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/tomcat_sessions?user=root&password=" sessionTable="tomcat_sessions" sessionIdCol="session_id" sessionDataCol="session_data" sessionValidCol="valid_session" sessionMaxInactiveCol="max_inactive" sessionLastAccessedCol="last_access"/> </Manager>6.3 集群配置
- 配置Tomcat集群:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>6.4 SSL/TLS配置
- 配置HTTPS连接器:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/path/to/keystore" keystorePass="changeit" ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_SHA256,TLS_ECDHE_RSA_WITH_AES_128_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_SHA,TLS_ECDHE_RSA_WITH_AES_256_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_SHA384,TLS_ECDHE_RSA_WITH_AES_256_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_128_SHA,TLS_DHE_DSS_WITH_AES_128_SHA256,TLS_DHE_RSA_WITH_AES_256_SHA256,TLS_DHE_DSS_WITH_AES_256_SHA,TLS_DHE_RSA_WITH_AES_256_SHA" />7. 实际应用中的经验分享
在生产环境中部署Tomcat多年,我总结了一些宝贵的经验:
内存配置不是越大越好:过大的堆内存会导致GC停顿时间变长,建议根据应用实际需求设置合理的堆大小。
线程池配置要结合实际:maxThreads设置过高会导致线程上下文切换开销增加,建议通过压力测试找到最佳值。
APR模式虽然性能好,但对系统环境要求较高,在容器化环境中可能不如NIO2稳定。
定期检查Tomcat日志和GC日志,可以提前发现潜在问题。
对于高并发应用,建议将静态资源交给Nginx处理,减轻Tomcat负担。
使用连接池管理数据库连接,避免频繁创建和销毁连接带来的性能开销。
对于Session数据较大的应用,建议使用外部存储(如Redis)来管理Session。
定期更新Tomcat版本,及时修复安全漏洞,但升级前务必在测试环境充分验证。