如何编写正确的systemd服务以通过start.sh启动并监控Java Jar应用
如何编写正确的systemd服务以通过start.sh启动并监控Java Jar应用
嘿,我来帮你梳理下怎么配置这个systemd服务,既能用你的start.sh启动Java应用,又能让systemd正常监控它的状态。咱们一步步来:
一、优化后的systemd服务文件
你的基础配置已经有模有样了,我补充了几个关键细节,确保服务监控和进程管理更可靠:
[Unit] Description=Some service After=syslog.target network.target # 如果你的应用依赖网络,加上network.target更稳妥 [Service] User=userXService Restart=always RestartSec=300s WorkingDirectory=/opt/test/target ExecStart=/opt/test/start.sh SuccessExitStatus=143 # 143对应Java收到SIGTERM后的正常退出码,这个配置没问题 KillMode=control-group # 停止服务时确保杀掉所有相关进程,避免残留 Type=simple # 明确告诉systemd:ExecStart启动的就是要监控的主进程 [Install] WantedBy=multi-user.target
二、修正start.sh脚本的核心问题
你的脚本参数配置都没问题,但有个致命错误:最后一行的&会让Java进程后台运行,导致systemd认为start.sh执行完成,彻底失去对Java进程的监控。必须去掉这个&,让Java进程在前台运行。修改后的脚本如下:
#!/bin/bash # 定义JVM启动参数 MEMORY="-Xms640m -Xmx640m" HEAP_DUMP="-XX:+HeapDumpOnOutOfMemoryError" SECURITY_RANDOM="-Djava.security.egd=file:/dev/./urandom" REMOTE_JMX="-Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.rmi.port=16078 -Dcom.sun.management.jmxremote.port=16078 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" # 获取脚本所在目录,避免路径依赖问题 DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" # 切换到target目录,切换失败直接退出,避免后续错误 cd "$DIRECTORY/target" || exit 1 # 启动Java应用,去掉最后的&,让进程前台运行 java $HEAP_DUMP $MEMORY $SECURITY_RANDOM $REMOTE_JMX -jar test-application.jar --spring.profiles.active=database >> ../test-application.log 2>&1
三、关键配置说明
- 去掉
&:这是核心!systemd只能监控前台运行的进程,后台进程会脱离它的管理范围,导致重启机制失效、服务状态显示异常。 cd "$DIRECTORY/target" || exit 1:增加目录切换失败的容错逻辑,避免在错误路径下执行Java命令。KillMode=control-group:确保停止服务时,所有和该服务相关的子进程都会被清理,不会残留僵尸Java进程。
四、部署与测试步骤
- 将服务文件保存到
/etc/systemd/system/test-application.service - 给脚本添加执行权限:
chmod +x /opt/test/start.sh - 重新加载systemd配置:
systemctl daemon-reload - 启动服务:
systemctl start test-application.service - 查看服务状态:
systemctl status test-application.service - 设置开机自启:
systemctl enable test-application.service
验证效果:如果Java进程意外崩溃,systemd会在300秒后自动重启它;你可以用systemctl restart/stop控制服务,用journalctl -u test-application.service或自定义的test-application.log查看运行日志。
备注:内容来源于stack exchange,提问作者Dafik
相关产品推荐
相关产品推荐

