Linux Jar包配置Systemd自启动实战:从排查到配置全流程


title: "Linux Jar包配置Systemd自启动实战:从排查到配置全流程"

tags:

  • Linux
  • systemd
  • Java
  • 运维
  • 自启动
    categories:
  • 运维
    description: "生产环境 Jar 包没有配置自启动?本文从实际排查经验出发,教你如何确认 Jar 是否自启、排查启动方式、编写 Systemd Service 配置开机自启动,包含 forking 和 simple 两种模式的实战配置。"

导读:前几天在生产服务器上发现两个 Java 服务跑了好几年,但从来没配过自启动------服务器一旦重启就完了。这篇文章把整个排查和配置过程记录下来,方便以后遇到类似情况直接照做。


一、事情是怎么发现的

事情起因很简单:线上有一台转码服务器,上面跑了两个 Java 服务。我上去检查的时候,习惯性地看了一眼自启动配置,结果发现------啥都没配

这台机器上次重启还是 2021 年 7 月,快 5 年没重启过了。jar 进程还在跑,纯粹是因为没重启过。万一哪天硬件故障或者需要重启,服务就起不来了。

这种事在生产环境其实挺常见的:部署的时候赶进度,手动 nohup java -jar xxx & 一把梭,服务跑起来就完事了。自启动?以后再说。然后就没有以后了。


二、排查过程

第一步:确认有哪些 Java 进程在跑

bash 复制代码
jps

输出:

复制代码
103856 Jps
64194 sdcs-dtc.jar
240473 tsingtao-server.jar

两个 jar 都在跑。

第二步:检查有没有 Systemd 服务

bash 复制代码
grep -r "sdcs-dtc" /etc/systemd/system/
grep -r "tsingtao-server" /etc/systemd/system/

没有任何输出,说明没有配置 systemd 服务

第三步:检查其他自启动方式

bash 复制代码
# rc.local
cat /etc/rc.local
# → 只有默认的 touch /var/lock/subsys/local,没有 jar 启动命令

# crontab
crontab -l | grep "@reboot"
# → 无输出

# supervisor
ls /etc/supervisord.d/
# → 目录不存在

全都没有。结论:这两个 jar 是手动启动的,开机不会自动运行。

第四步:查看进程详情

bash 复制代码
ps -ef | grep -E "sdcs-dtc|tsingtao-server"

关键信息:

  • 两个进程的 PPID 都是 1(父进程是 init/systemd)
  • sdcs-dtc.jar 从 2023 年跑到现在
  • tsingtao-server.jar 从 2025 年跑到现在

第五步:检查服务器重启历史

bash 复制代码
last reboot

输出显示最近一次重启是 2021 年 7 月 21 日。怪不得 jar 还在跑------服务器根本没重启过。

第六步:找到启动脚本

bash 复制代码
ls /data/conver/distribution/bin/
复制代码
shutdown.sh  startup.sh

原来有现成的启停脚本。看看脚本里怎么写的:

bash 复制代码
grep -E "nohup|&" /data/conver/distribution/bin/startup.sh
复制代码
echo "$JAVA ${JAVA_OPT}" > ${BASE_DIR}/logs/start.out 2>&1 &
nohup $JAVA ${JAVA_OPT} yxt.dtc >> ${BASE_DIR}/logs/start.out 2>&1 &

脚本用了 nohup ... & 后台启动,这个信息后面配置 systemd 时要用到。


三、编写 Systemd Service

有现成的启停脚本,service 配置就简单了。关键是要选对 Type

Type 适用场景
simple 进程前台运行,不 fork
forking 脚本里有 &nohup,进程后台运行

因为 startup.sh 里用了 nohup ... &,所以用 Type=forking

创建 service 文件

bash 复制代码
cat > /etc/systemd/system/conver.service << 'EOF'
[Unit]
Description=Conver Distribution Service
After=network.target

[Service]
Type=forking
User=root
ExecStart=/data/conver/distribution/bin/startup.sh
ExecStop=/data/conver/distribution/bin/shutdown.sh
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

参数说明:

参数 说明
Type forking startup.sh 用 nohup 后台启动
After network.target 网络就绪后再启动
ExecStart 启动脚本路径 用现成的 startup.sh
ExecStop 停止脚本路径 用现成的 shutdown.sh
Restart on-failure 异常退出时自动重启
RestartSec 10 重启前等 10 秒
WantedBy multi-user.target 开机自启到多用户模式

⚠️ 如果你的 jar 是直接 java -jar 前台运行的(没有 &),把 Type 改成 simpleExecStart 直接写完整的 java 命令。

如果没有启停脚本

如果项目没有现成的 startup.sh,可以直接把 java 命令写进去:

bash 复制代码
cat > /etc/systemd/system/conver.service << 'EOF'
[Unit]
Description=Conver Distribution Service
After=network.target

[Service]
Type=simple
User=root
ExecStart=/bin/java -server -Xms2g -Xmx2g \
  -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m \
  -jar /data/newconver/tsingtao-server/target/tsingtao-server.jar \
  --spring.config.location=file:/data/newconver/tsingtao-server/conf/application-config.yml
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

这种方式用 Type=simple,systemd 直接管理 java 进程,更干净。


四、启用自启动

bash 复制代码
# 1. 先停掉手动启动的旧进程
kill 64194 240473

# 2. 确认停干净了
jps

# 3. 重新加载 systemd 配置
systemctl daemon-reload

# 4. 设置开机自启
systemctl enable conver

# 5. 启动服务
systemctl start conver

# 6. 验证
systemctl status conver
systemctl is-enabled conver

is-enabled 输出 enabled 就说明配置成功了。


五、常用管理命令速查

操作 命令
启动服务 systemctl start conver
停止服务 systemctl stop conver
重启服务 systemctl restart conver
查看状态 systemctl status conver
查看是否自启 systemctl is-enabled conver
启用自启 systemctl enable conver
禁用自启 systemctl disable conver
查看日志 journalctl -u conver -f
重新加载配置 systemctl daemon-reload

💡 修改了 service 文件后,一定要执行 systemctl daemon-reload 重新加载,否则改了不生效。


六、常见问题

Q:Type=forking 和 Type=simple 怎么选?

看你的启动脚本。脚本里有 &nohup ... &,用 forking。如果 ExecStart 直接写 java -jar 命令(前台运行),用 simple。选错了的表现:simple 配了 forking 的脚本,systemd 会认为服务一直处于 activating 状态;反过来,forking 配了 simple 的命令,systemd 认为服务立即退出了。

Q:forking 模式下 systemd 怎么跟踪进程?

systemd 会跟踪 ExecStart 脚本 fork 出来的子进程。如果脚本 fork 了多个后台进程,可能需要加 PIDFile 指定 PID 文件路径,让 systemd 知道跟踪哪个。

Q:Restart=on-failure 和 Restart=always 有什么区别?

on-failure 只在异常退出(非 0 返回码)时重启,always 不管什么原因退出都重启(包括正常 stop)。生产环境建议用 on-failure,避免 systemctl stop 之后又被自动拉起来。

Q:怎么确认服务器重启后 jar 真的会自动起来?

最稳妥的办法:在测试环境配好后重启一次验证。生产环境不敢随便重启的话,至少确认 systemctl is-enabled 输出 enabled,并且 systemctl status 显示 active (running)

Q:日志怎么看?

bash 复制代码
# 实时看 systemd 日志
journalctl -u conver -f

# 看最近 100 行
journalctl -u conver -n 100

如果 jar 自己有日志输出(比如 Spring Boot 的 logback),那些日志在 jar 的 logs 目录下,不在 systemd 日志里。


参考链接


写了这么多,如果对你有帮助的话,给我点个赞 👍 收个藏 📌 吧~

如果你也遇到过生产环境 jar 没配自启动的坑,或者有更好的 systemd 配置方案,欢迎在评论区分享,我会一一回复。

相关推荐
不知名的老吴1 小时前
线程的生命周期之线程“插队“
java·开发语言·python
xsc6996752 小时前
从零搭建大模型与智能体平台 - 完整技术详解
python
bjzhang752 小时前
CentOS下安装MySQL详解
linux·mysql·centos
无风听海4 小时前
多租户系统中的 OIDC:Discovery 端点与联合登录的深度实践
后端·python·flask
Jason_chen4 小时前
Linux 6.2 音频机制深度解析:AI驱动的低延迟音频与零信任音频安全架构
linux
下午写HelloWorld4 小时前
Linux系统及Ubuntu常用指令
linux·ubuntu·操作系统
CTA终结者4 小时前
期货量化主力换月程序怎么移仓:天勤 underlying_symbol 与任务切换
python·区块链
马士兵教育4 小时前
Java还有前景吗?Java+AI大模型学习路线及项目?
java·人工智能·python·学习·机器学习
KaMeidebaby5 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习