在 Linux 服务器上跑应用,很多人习惯用 screen 或 nohup 保活。这种方式应应急可以,但系统一重启就得手动拉起,应用崩了也没人管,日志更是散落各处。正规的解法是把应用注册为 systemd 服务——systemd 是现代 Linux 发行版的初始化系统,负责启动和管理系统上的所有服务,开机自启、崩溃自动重启、日志统一收集,一次配置全部搞定。
一、创建 service 文件
以一个 Node.js 应用为例,新建服务配置文件:
sudo tee /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=我的 Node.js 应用
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/app.js
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
EOF
然后加载配置并启动:
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
三步之后,应用就已经作为系统服务运行,并且开机自动启动。
二、service 文件字段详解
1、[Unit] 段:描述和启动顺序
Description=服务描述 # 显示在 systemctl status 里
After=network.target # 在网络就绪后启动
After=mysql.service # 在 MySQL 启动后启动
Requires=mysql.service # 强依赖,MySQL 停了本服务也停
Wants=redis.service # 弱依赖,Redis 没启动也能继续
2、[Service] 段:怎么跑、挂了怎么办
Type=simple # 前台运行的进程
Type=forking # 以守护进程方式运行(会 fork)
Type=oneshot # 执行一次就退出
User=www-data # 运行用户
Group=www-data # 运行组
WorkingDirectory=/opt/myapp # 工作目录
ExecStart=/usr/bin/node app.js # 启动命令(必须是绝对路径)
ExecStop=/bin/kill -SIGTERM $MAINPID # 停止命令(可选)
ExecReload=/bin/kill -HUP $MAINPID # 重载命令(可选)
Restart=always # 总是自动重启
Restart=on-failure # 仅崩溃时重启(正常退出不重启)
Restart=no # 不自动重启
RestartSec=5 # 重启前等待 5 秒
Environment=KEY=VALUE # 环境变量
EnvironmentFile=/etc/myapp.env # 从文件加载环境变量
LimitNOFILE=65536 # 最大文件描述符数(高并发应用需要)
3、[Install] 段:何时启用
WantedBy=multi-user.target # 多数服务写这个,表示正常运行模式
日常服务用 Type=simple 加 Restart=on-failure 的组合就够了。注意 ExecStart 里的命令和脚本必须是绝对路径,写相对路径会直接启动失败。
三、常用管理命令
# 启动/停止/重启
sudo systemctl start myapp
sudo systemctl stop myapp
sudo systemctl restart myapp
# 重载配置(不完全重启)
sudo systemctl reload myapp
# 启用/禁用开机自启
sudo systemctl enable myapp
sudo systemctl disable myapp
# 查看状态
sudo systemctl status myapp
# 修改 service 文件后必须执行
sudo systemctl daemon-reload
# 列出所有服务
systemctl list-units --type=service
# 列出失败的服务
systemctl list-units --state=failed
最常忘记的一条是 daemon-reload——每次改完 service 文件都必须执行,否则修改不生效,排查问题时容易怀疑人生。
四、用 journalctl 查日志
systemd 把所有服务的输出统一收集到 journal,不用再去各个目录翻日志文件:
# 查看指定服务的日志
journalctl -u myapp
# 实时跟踪日志
journalctl -u myapp -f
# 查看最近 100 行
journalctl -u myapp -n 100
# 查看今天的日志
journalctl -u myapp --since today
# 查看某时间段的日志
journalctl -u myapp --since "2026-04-25 00:00" --until "2026-04-25 12:00"
# 查看所有服务的最近日志
journalctl -f
五、写在最后
把应用从 screen/nohup 迁移到 systemd,工作量只有写一个 service 文件,换来的却是开机自启、崩溃自动拉起、统一日志管理这三件生产环境的刚需。下次再部署应用,别再开 screen 了,花五分钟写个 service 文件,后面省的都是自己的时间。
相关阅读:
《Linux实时查看日志文件教程:tail、Multitail、Lnav等常用日志监控方法》
《Linux日志轮转机制详解:logrotate安装、配置、工作原理与排查方法》
-
广告合作
-
QQ群号:4114653



