在同一台服务器上部署两个Tomcat的核心方案是通过修改环境变量区分端口,具体操作为复制Tomcat目录并分别配置server.xml中的Connector端口及catalina.sh中的CATALINA_HOME路径,从而实现多实例并行运行且互不干扰。
对于运维人员或开发者而言,单机多实例部署是提升资源利用率、隔离不同业务场景的常见手段,无论是测试环境的多版本对比,还是生产环境中小微业务的独立隔离,这种方案都能有效避免“单点故障”波及所有服务,业内专家指出,合理的端口规划是避免冲突的关键,而环境变量隔离则是确保进程独立性的基石,我们将深入拆解这一实操过程,确保每一步都清晰可验证。
部署前的核心准备与资源评估
在动手修改配置文件之前,明确服务器资源状况和软件版本一致性是避免后续踩坑的前提,多数情况下,初学者容易忽略内存分配差异,导致一个Tomcat启动成功,另一个却因OOM(内存溢出)而崩溃。
确认服务器硬件余量
单机部署两个Tomcat,意味着JVM堆内存、Metaspace以及直接内存都将叠加,据统计,中小规模应用每个Tomcat实例至少需要预留512MB至1GB的堆内存空间,如果你的服务器内存仅为2GB,强行部署两个默认配置的Tomcat极大概率会导致系统Swap交换频繁,进而引发服务响应超时。
- 检查内存命令:使用
free -h查看可用内存。 - 内存规划建议:若总内存为4GB,建议每个Tomcat的
-Xmx(最大堆内存)设置为512M或768M,预留系统及其他进程空间。
选择同版本或兼容版本
虽然技术上允许不同版本的Tomcat共存,但为了降低维护成本,建议两个实例使用相同的Tomcat版本,同时使用Tomcat 9或Tomcat 10,版本混用可能导致Jar包冲突或日志格式差异,增加排查难度。
具体实施步骤:从复制配置到端口隔离
这是整个部署过程中最核心的环节,我们将以Linux环境为例,演示如何从零开始创建第二个Tomcat实例,整个过程分为目录复制、端口修改、环境变量配置三个关键步骤。

第一步:复制Tomcat安装目录
不要直接在原目录上修改,而是通过复制创建独立的工作目录,假设原Tomcat安装在/opt/tomcat,我们需要创建一个新的实例目录。
# 复制整个Tomcat目录并重命名为tomcat2 sudo cp -r /opt/tomcat /opt/tomcat2
复制完成后,确保新目录拥有正确的权限,避免后续启动时因权限不足报错:
sudo chown -R tomcat:tomcat /opt/tomcat2 sudo chmod -R 755 /opt/tomcat2
第二步:修改关键端口避免冲突
Tomcat默认使用三个关键端口:8080(HTTP连接器)、8005(Shutdown端口)和8009(AJP连接器),如果两个实例使用相同端口,操作系统将拒绝绑定,导致启动失败。
我们需要编辑/opt/tomcat2/conf/server.xml文件,找到<Server>、<Connector>和<Listener>标签,修改端口号。
- Shutdown端口:原为8005,建议改为8006。
- HTTP连接器:原为8080,建议改为8081。
- AJP连接器:原为8009,建议改为8010。
修改后的代码片段示例如下:
<!-- 修改Shutdown端口 -->
<Server port="8006" shutdown="SHUTDOWN">
...
<!-- 修改HTTP连接器端口 -->
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
...
<!-- 修改AJP连接器端口 -->
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
</Server>
第三步:配置环境变量实现进程隔离
这是容易被忽视但至关重要的一步,Tomcat的启动脚本catalina.sh依赖CATALINA_HOME和CATALINA_BASE变量来确定配置文件和日志路径,如果不区分这两个变量,两个Tomcat可能会共享同一份配置或日志,导致管理混乱。

编辑/opt/tomcat2/bin/setenv.sh文件(若不存在则新建),添加以下环境变量:
export CATALINA_HOME=/opt/tomcat export CATALINA_BASE=/opt/tomcat2 export CATALINA_TMPDIR=/opt/tomcat2/temp
这里有一个关键区别:CATALINA_HOME指向Tomcat的安装根目录(即共享的lib、bin等文件),而CATALINA_BASE指向当前实例的工作目录(即包含conf、webapps、logs等独立文件的目录),这种设计允许两个实例共享相同的Tomcat核心代码,但拥有独立的配置和数据。
启动验证与常见问题排查
配置完成后,启动第二个Tomcat并验证其独立性。
启动与状态检查
进入新实例的bin目录并启动:
cd /opt/tomcat2/bin ./startup.sh
启动后,通过查看日志确认是否成功绑定新端口:
tail -f /opt/tomcat2/logs/catalina.out
如果看到类似Server startup in [xxxx] ms且无端口绑定错误,说明启动成功,访问http://服务器IP:8081应能看到Tomcat默认欢迎页面,而http://服务器IP:8080则对应第一个实例。
常见错误与解决方案
- Address already in use:这通常意味着端口冲突,请再次检查
server.xml中的端口是否被其他进程占用,可使用netstat -tlnp | grep 8081命令排查。 - Permission denied:权限问题,确保
tomcat2目录及其子目录对运行Tomcat的用户(如tomcat用户)具有读写执行权限。 - Java版本不一致:如果两个Tomcat依赖不同的JDK版本,需在各自的
setenv.sh中显式指定JAVA_HOME路径,避免环境变量覆盖。
长期维护与性能优化建议
部署完成只是开始,长期的稳定运行需要持续的监控和优化。
日志分离管理
由于两个实例日志分离,建议配置独立的日志切割策略,可以使用Logback或Log4j2,在各自的

logging.properties或logback.xml中指定日志文件路径,避免日志文件过大影响磁盘IO。
健康检查与自动化重启
对于生产环境,建议配置Systemd服务或Supervisor来管理Tomcat进程,这样可以实现开机自启、崩溃自动重启以及统一的状态监控,在Systemd中定义两个.service文件,分别指向不同的CATALINA_BASE,实现进程级的隔离管理。
安全加固
不同实例可能承载不同敏感度的业务,建议对高敏感实例启用HTTPS,并严格限制server.xml中的server.info信息,防止版本信息泄露,定期清理temp目录下的临时文件,防止磁盘空间被无用数据占满。
关于同一台服务器部署两个Tomcat的常见问题
同一台服务器部署两个Tomcat会影响性能吗?
只要服务器资源充足,影响微乎其微,Tomcat本身是轻量级容器,其性能瓶颈通常在于JVM堆内存设置和并发连接数,若两个实例合理分配内存,且业务负载未超过硬件上限,性能表现与独立服务器无异,反之,若资源争抢严重,则需考虑扩容或分离部署。
同一台服务器部署两个Tomcat可以配置不同的JDK版本吗?
可以,通过在各自的setenv.sh或启动脚本中显式设置JAVA_HOME环境变量,可以指定不同的JDK路径,Tomcat 1使用JDK 8,Tomcat 2使用JDK 11,但需注意,确保两个JDK版本均符合Tomcat版本的最低要求,并避免系统全局环境变量冲突。
同一台服务器部署两个Tomcat如何配置不同的域名解析?
这主要依赖于Nginx或Apache等反向代理服务器,在Nginx中,可以配置两个server块,分别监听80端口,并通过server_name区分域名。www.a.com代理到0.0.1:8080,www.b.com代理到0.0.1:8081,这种方式不仅实现了域名隔离,还能提供负载均衡、SSL终止等高级功能,是生产环境的标准做法。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/399139.html
