tomcat 自启动 linux

服务器重启之后 Tomcat 没起来,自启业务方电话直接打过来——这种事我遇到过两次,自启第二次之后我就把所有生产机的自启 Tomcat 自启动配了个遍。Linux 下让 Tomcat 开机自启,自启路子有好几条,自启但每条都有坑,自启我把自己踩过的自启记录一下。

先搞清楚你的自启 Tomcat 是怎么装的

apt 或 yum 装的 Tomcat 和手动解压 tar.gz 的,自启动配法完全不一样。自启包管理器装的自启通常已经带了 systemd unit 或者 init 脚本,你只需要 systemctl enable tomcat 就行。自启但现实是自启大部分生产环境用的是手动解压的版本,目录在 /opt/tomcat 或者 /usr/local/tomcat,自启这种就得自己写。自启

先确认一下:systemctl status tomcat 有没有输出。自启如果没有,说明系统不认识这个服务,得从零配。

Systemd 方式(推荐)

新建一个 unit 文件:

vi /etc/systemd/system/tomcat.service

内容大概长这样:

[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/opt/tomcat/bin/shutdown.sh User=tomcat Group=tomcat RestartSec=10 Restart=on-failure [Install] WantedBy=multi-user.target

几个地方容易翻车。JAVA_HOME 必须写对,systemd 不读 /etc/profile,你在 shell 里 echo $JAVA_HOME 有值不代表 systemd 能看到。User 和 Group 别用 root,Tomcat 以 root 跑是个安全隐患,提前建好 tomcat 用户并 chown -R tomcat:tomcat /opt/tomcat。

Type=forking 配合 startup.sh 是标准搭配,因为 startup.sh 本身会 fork 出 Java 进程然后退出。如果你用 catalina.sh run 前台启动,那就改成 Type=simple,但这样日志会直接打到 journal 里,看日志的方式就变了。

配完执行:

systemctl daemon-reload systemctl start tomcat systemctl enable tomcat

daemon-reload 这步别省,改了 unit 文件不 reload 等于没改。

rc.local 方式(老系统或懒人方案)

CentOS 6 时代大家都往 /etc/rc.local 里塞启动命令。CentOS 7 之后 rc.local 默认没有执行权限,得先 chmod +x /etc/rc.d/rc.local。然后在里面加一行:

su - tomcat -c '/opt/tomcat/bin/startup.sh'

这种方式的问题是没有进程管理。Tomcat 崩了不会自动拉起来,关机时也不会优雅停止,systemd 的 ExecStop 那套东西全没有。临时用可以,生产环境还是老老实实写 unit 文件。

一个真实的坑

有台机器配完 systemd 之后 systemctl start tomcat 一直卡住不返回,等半分钟报 timeout。查了半天发现是 startup.sh 里调用了 catalina.sh,而 catalina.sh 在某些版本里会去读 /etc/profile 里的环境变量,systemd 环境下这个文件不存在导致脚本挂起。解决办法是在 unit 文件里显式传所有需要的环境变量,或者在 setenv.sh 里把配置写死。

还有个更隐蔽的:Tomcat 启动需要熵池有足够的随机数,某些虚拟机环境下 /dev/random 阻塞导致启动极慢。装个 haveged 或者加 -Djava.security.egd=file:/dev/./urandom 到 JAVA_OPTS 里能解决。

验证别忘了

systemctl enable tomcat 之后,最靠谱的验证方式是直接 reboot。别偷懒用 systemctl start 测试就完事,enable 只是创建了软链接,开机时能不能真正拉起来是另一回事。重启后 systemctl status tomcat 看状态,再 curl localhost:8080 确认端口通了。

配一次花十分钟,比半夜被电话叫醒强。