告别 nohup & screen!不用 Docker 也能实现开机自启、崩溃重启、统一日志
适合人群:Linux 新手、Java 开发、运维初学者、学生党


❗ 先破除最大误区:.service 不是脚本!

很多新手以为:

“我把 xxx.service 写好,然后 sh xxx.service 就能启动服务”

这是完全错误的!

✅ 正确认知:

  • .service 是一个配置文件,不是可执行脚本
  • 不能用 shbash./ 运行它
  • 它的作用是:告诉 systemd(Linux 的管家):“以后有人让你启动这个服务,请按我说的做”

💡 类比:
就像你给物业留了一份《空调维修指南》——
你不是让物业“运行”这份指南,而是说:“以后空调坏了,你就按这个流程修”。
.service 就是这份指南,systemd 就是物业。


🔍 一、为什么你需要 systemctl?和 Docker 有啥区别?

能力 nohup / & Docker systemctl(本文主角)
开机自启 ✅(需 --restart=always ✅(enable 即可)
崩溃自动重启
日志集中查看 ❌(分散在 nohup.out) ✅(docker logs ✅(journalctl -u
资源隔离 ❌(直接跑主机,更轻量)
学习成本 极低(只需一个配置文件)

💡 结论
如果你只是想让一个 Java 程序、Elasticsearch、Python 脚本长期稳定运行在服务器上,不需要容器隔离,那么 systemctl 比 Docker 更简单、更高效!


📁 二、.service 文件必须放哪里?(关键!)

唯一正确位置

/etc/systemd/system/your-service-name.service

常见错误位置(会导致服务无效!):

  • 和 JAR 放在一起:/opt/myapp/your-service.service
  • 用户家目录:~/your-service.service
  • 任意其他目录

🔑 记住
所有自定义服务.service 文件,必须放在 /etc/systemd/system/ 目录下
systemd 只会从这里读取用户自定义服务。


🧱 三、完整操作流程(以 Java 应用为例)

假设你的 Spring Boot 应用:

  • JAR 路径:/opt/java-server/java-server.jar
  • 运行用户:appuser(非 root!)

步骤 1️⃣:确认 Java 和 JAR 的绝对路径

# 查 Java 路径(通常是 /usr/bin/java)
which java

# 确认 JAR 存在
ls -l /opt/java-server/java-server.jar

步骤 2️⃣:创建专用用户(安全必须!)

sudo useradd -r -s /sbin/nologin appuser
sudo chown -R appuser:appuser /opt/java-server

步骤 3️⃣:在正确位置创建 .service 文件

# 注意:是在 /etc/systemd/system/ 下创建!
sudo vim /etc/systemd/system/java-server.service

填入以下内容(逐行详解):

[Unit]
Description=NSD Flow Server (Java Application)
After=network.target              # 等基础网络就绪
Wants=network-online.target       # 等网络完全可用(推荐)

[Service]
Type=simple                       # Java/ES/Redis 用 simple
User=appuser                      # 必须是非 root!
WorkingDirectory=/opt/java-server

# ✅ 正确写法:绝对路径 + 无 & + 无重定向
ExecStart=/usr/bin/java -jar /opt/java-server/java-server.jar

# ❌ 错误写法(会导致 systemd 失效):
# ExecStart=java -jar app.jar          → java 可能找不到
# ExecStart=... &                      → & 会让进程后台化
# ExecStart=nohup ... &                → 完全破坏管理
# ExecStart=... >> log.txt             → 重定向导致日志丢失

Restart=on-failure                # 仅异常退出时重启
RestartSec=10                     # 重启前等待 10 秒(单位:秒)

# LimitNOFILE=65536
#   - 单位:个(文件描述符数量)
#   - 作用:允许同时打开 65536 个连接
#   - 不加会怎样?高并发时报 "Too many open files"
LimitNOFILE=65536

TimeoutStopSec=120                # stop 时最多等 120 秒(单位:秒)

StandardOutput=journal            # stdout → journal
StandardError=journal             # stderr → journal
SyslogIdentifier=java-server  # 日志前缀名

[Install]
WantedBy=multi-user.target        # 开机启动级别

保存退出(:wq)。


步骤 4️⃣:重载配置(关键!)

# 告诉 systemd:“去 /etc/systemd/system/ 看看,有没有新服务”
sudo systemctl daemon-reload

⚠️ 每次修改 .service 文件后,都必须执行这一步!


步骤 5️⃣:使用 systemctl 控制服务(这才是“使用”方式!)

# 启动服务
sudo systemctl start java-server

# 停止服务
sudo systemctl stop java-server

# 查看状态
sudo systemctl status java-server

# 设置开机自启
sudo systemctl enable java-server

# 查看日志(你会看到 Spring Boot 启动日志!)
sudo journalctl -u java-server -f

✅ 服务名 = .service 文件名去掉 .service 后缀


🗂️ 四、目录结构示意图

/
├── etc/
│   └── systemd/
│       └── system/
│           └── java-server.service   ← ✅ 配置文件(必须在这里!)
│
├── opt/
│   └── java-server/
│       ├── java-server.jar           ← 你的程序
│       └── config/
│
└── usr/
    └── bin/
        └── java                          ← Java 可执行文件

💡 .service 和 JAR 可以不在同一个目录!
只要在配置中用绝对路径指明即可。


🛠️ 五、高频问题 & 排错指南

❌ 问题1:systemctl status 显示 active,但看不到应用日志

  • 原因ExecStart 用了 >> app.log&
  • 解决:去掉重定向和后台符号,确保前台运行

❌ 问题2:启动失败,status=1/FAILURE

  • 排查命令
    sudo journalctl -u java-server --since "5 minutes ago"
    
  • 常见原因
    • java 路径错误 → 用 which java 确认
    • JAR 路径错误 → ls -l 检查
    • 端口被占用 → 日志报 Address already in use

❌ 问题3:Permission denied

  • 解决
    sudo chown -R appuser:appuser /opt/java-server
    

✅ 六、通用模板(替换 YOUR_APP 即可)

[Unit]
Description=YOUR_APP
After=network.target

[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/app
ExecStart=/usr/bin/java -jar /path/to/app/your-app.jar
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

🔚 七、总结:给新人的 checklist

  1. .service 文件是否放在 /etc/systemd/system/
  2. ExecStart 是否用绝对路径?是否包含 &>>
  3. 是否创建了非 root 用户并授权目录?
  4. 修改配置后是否执行 systemctl daemon-reload
  5. 是否用 journalctl -u 服务名 -f 查日志?

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐