让Tomcat一直在后台运行,核心方案是使用nohup命令配合&符号,或者将其注册为系统服务(systemd),这样即使关闭终端窗口,Tomcat也能持续对外提供服务。
为什么直接启动Tomcat会中断
很多人在本地开发时习惯直接运行startup.sh,然后关掉终端窗口,回头一看Tomcat进程已经没了,这背后是Linux系统的进程管理机制在起作用,当终端会话结束时,系统会向该会话下的所有进程发送挂断信号(SIGHUP),Tomcat进程收到这个信号后默认会终止。
用大白话讲,前台启动的Tomcat和你的终端窗口是“绑定”的,窗口一关,命令行的“父进程”没了,Tomcat也就跟着“殉情”了。
要解决这个问题,思路无非两条:让Tomcat忽略终端关闭的信号,或者干脆给它换个“新家”,让它脱离终端独立生活。
nohup命令实现临时后台运行
这是最快速、最直接的方式,适合临时测试或者不常重启的场景。
用法很简单,进入Tomcat的bin目录,执行:
nohup ./startup.sh > /dev/null 2>&1 &
这条命令拆开来看,nohup表示忽略挂断信号,> /dev/null 2>&1是把标准输出和错误输出都丢进黑洞,避免日志文件无限膨胀,最后的&是把整个命令丢到后台执行。
执行完你会看到一个进程ID输出,这就代表Tomcat已经在后台运行了,无论你怎么关终端,它都会继续跑。
验证是否真的在运行,用这个命令:
ps -ef | grep tomcat
看到/usr/local/tomcat/conf之类的路径,就说明进程活着,或者直接访问http://服务器IP:8080,能看到那只熟悉的猫,就说明一切正常。
这种方法有个小瑕疵:如果服务器重启,这个进程还是会消失,需要重新手动启动。
systemd服务实现开机自启
这是目前Linux主流发行版(CentOS 7+、Ubuntu 16.04+、Debian 8+)最推荐的方式,也是生产环境最常用的方案,它能把Tomcat变成系统级别的服务,实现开机自动启动、崩溃自动重启、日志统一管理。
一般操作路径是这样,在/etc/systemd/system/目录下新建一个服务文件,比如tomcat.service,写入以下内容:
[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking Environment=JAVA_HOME=/usr/local/java Environment=CATALINA_HOME=/usr/local/tomcat Environment=CATALINA_BASE=/usr/local/tomcat ExecStart=/usr/local/tomcat/bin/startup.sh ExecStop=/usr/local/tomcat/bin/shutdown.sh User=tomcat Group=tomcat Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
保存后,依次执行:
systemctl daemon-reload systemctl enable tomcat systemctl start tomcat
这样一来,Tomcat就成了一等公民,用systemctl status tomcat可以随时查看运行状态,用systemctl restart tomcat重启服务,非常顺手。
行业共识认为,在部署规模超过3台服务器的场景下,不推荐用nohup方案,因为无法统一管理,出了问题排查起来也麻烦,systemd方案在这方面有明显优势。
Windows服务器下的后台运行方式
Windows服务器跑Tomcat的情况也不少,如果你用的是安装版(一般为exe后缀的安装包),那基本不用操心后台问题,系统服务里已经注册好了,右键“我的电脑”->“管理”->“服务”,找到Apache Tomcat,设置为“自动”启动就行。
如果你用的是免安装版(zip后缀的解压包),可以借助tomcat9w.exe这个工具,它就在bin目录下,双击运行,在“Startup type”里选择“Automatic”,点“Start”按钮,Tomcat就会以Windows服务的形式后台启动,不弹黑窗口,不占任务栏。
Windows下的额外选项是使用WinSW工具,不过配置过程比tomcat9w要繁琐一些,普通场景没必要为了这个额外增加操作步骤。
日志管理与后台运行的配套策略
Tomcat一直后台跑,日志文件就成了大问题,默认情况下,catalina.out这个文件会一直增大,几个月不清理能占到好几个G,因此后台运行的同时,必须同步处理日志切割。
常见的做法是用Linux自带的logrotate工具,配置文件放在/etc/logrotate.d/tomcat大致如下:
/usr/local/tomcat/logs/catalina.out {
daily
rotate 7
copytruncate
compress
missingok
}
这段配置的意思是每天切割一次日志,保留7份,切割后压缩,文件还在被Tomcat占用也不影响操作,配置完成后,用logrotate -f /etc/logrotate.d/tomcat手动执行一次验证效果。
常见问题排查
后台运行后,Tomcat启动失败怎么排查?
后台运行和前台启动共享同一套日志体系,排查方式就是看日志,先看logs/catalina.out,再看logs/localhost.log,如果日志里出现了Port 8080 already in use,说明端口被占,用netstat -tlnp | grep 8080查看是哪个进程占的,处理完再重启Tomcat就行。
用shutdown.sh关不掉后台运行的Tomcat?
这是最常见的一个问题,后台运行的Tomcat有时候shutdown.sh执行了,但进程依然在,多数情况下是CATALINA_PID没有设置,导致脚本找不到准确的进程号,解决办法是在catalina.sh的头部加一行:
CATALINA_PID=/tmp/tomcat.pid
这样启动时会把进程号写入这个文件,关闭时直接精准杀掉,不会再出现僵死进程。
不同场景下Tomcat后台运行方案怎么选
酷番云、简米云上的单台应用服务器:直接在测试环境用nohup,生产环境用systemd,这是多数运维的通用做法,如果服务器内存只有2G,同时跑数据库和Tomcat的话,务必在
catalina.sh里设置JAVA_OPTS="-Xms512m -Xmx512m",防止内存溢出。
本地开发机:最省事的办法是在IDE里配置Tomcat,Eclipse、Idea都能直接后台运行,日志输出到控制台,还有热部署功能,转发效率明显高于命令行方式,没必要折腾nohup。
如果有多台服务器需要统一管理Tomcat状态,就得引入自动化运维工具如Ansible、Puppet等,通过SSH批量分发systemd配置并启动服务,一台一台手动操作效率太低,不符合规模化运维的基本要求。
临时演示环境:不需要追求持续运行,nohup启动,用完直接kill就行,不用为这种场景去配置复杂的systemd服务,灵活性和便利性优先。
附录:常用命令速查
# 启动 systemctl start tomcat # 停止 systemctl stop tomcat # 重启 systemctl restart tomcat # 查看状态 systemctl status tomcat # 开机自启 systemctl enable tomcat # 关闭开机自启 systemctl disable tomcat
常见问题解答
tomcat后台运行和前台运行有什么区别?
前台运行时,Tomcat的日志会实时打印到当前终端,Ctrl+C就能直接终止,后台运行时,日志写入logs/catalina.out文件,终端不再显示日志输出,Tomcat进程与终端分离,即使终端关闭进程也不受影响。
如何验证Tomcat是否真的在后台正常运行?
先用ps -ef | grep tomcat确认进程存在,再用curl -I http://localhost:8080检查HTTP响应,正常的话会返回200状态码,最后查看logs/catalina.out确认没有报错信息,从进程、端口、日志三个维度完成验证。
catalina.out日志文件越涨越大怎么办?
通过logrotate工具进行日志轮转,配置策略按天切割、本地保留7份、历史日志压缩存储,删除过期日志后重新加载配置,长期运行下日志文件不会无限膨胀,这是Tomcat朝阳出品的最佳实践方式。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/660323.html




