linux 如何添加服务
- Linux
- 2025-08-16
- 4
/etc/systemd/system/
下的
.service
文件定义服务,然后用
systemctl enable
设为开机启动,`systemctl start
在 Linux 系统中添加服务的核心目标是实现自动化启动与持续运行,确保服务随系统开机自动加载,并在意外终止时能够自动重启,以下是主流的实现方式及完整操作指南,涵盖从基础到进阶的多种场景。
基于 Systemd 的服务管理(推荐)
Systemd 是当前绝大多数 Linux 发行版(如 Ubuntu 16.04+、CentOS 7+、Debian 9+)默认的初始化系统,通过统一的 .service
文件定义服务行为。
创建标准 Systemd 服务单元文件
适用场景:长期稳定运行的业务程序、自定义应用
操作步骤:
| 序号 | 操作命令/动作 | 说明 |
|——|——————————|——————————————————————–|
| ① | sudo nano /etc/systemd/system/myapp.service
| 创建新服务的配置文件(路径固定为 /etc/systemd/system/
) |
| ② | 填写以下基础模板 | 根据实际需求修改参数 |
| | [Unit] | 元数据描述 |
| | Description=My Custom Application | 服务名称 |
| | After=network.target | 依赖网络服务完成后启动 |
| [Service] | 核心控制段 |
| | Type=simple | 简单模式(默认),适合短时间任务;可选 notify
/forking
等类型 |
| | User=nobody | 以非特权用户运行(安全最佳实践) |
| | Group=nogroup | 同上 |
| | WorkingDirectory=/opt/myapp | 指定程序工作目录 |
| | ExecStart=/usr/bin/python3 /opt/myapp/main.py –daemonize | 启动命令(需绝对路径) |
| | Restart=always | 无论退出状态如何均重启(推荐生产环境) |
| | RestartSec=5 | 重启前等待 5 秒 |
| [Install] | 安装配置 |
| | WantedBy=multi-user.target | 多用户模式下自动启动 |
| ③ | sudo systemctl daemon-reload
| 通知 systemd 重新加载新服务文件 |
| ④ | sudo systemctl enable myapp
| 启用服务(创建符号链接至启动目录) |
| ⑤ | sudo systemctl start myapp
| 立即启动服务 |
| ⑥ | sudo systemctl status myapp
| 查看服务状态(活跃/休眠/失败) |
️ 关键参数解析:
Type
:若程序会脱离终端运行(如后台进程),应设为simple
;若需等待子进程结束,可用oneshot
。Restart
:on-failure
仅在异常退出时重启,always
适用于不稳定但需保活的场景。User/Group
:强烈建议降权运行,避免使用root
执行非必要程序。
调试技巧
- 查看日志:
journalctl -u myapp.service -f
(实时跟踪输出) - 测试运行:
systemctl start myapp
→ 手动停止后观察是否按策略重启。 - 临时禁用:
systemctl mask myapp
(阻止启用但不删除文件)。
传统 SysVinit 脚本(兼容旧系统)
部分老旧系统仍使用 /etc/init.d/
目录存放 LSB Init Scripts,虽逐渐被淘汰,但在特定环境中仍需掌握。
编写 Init 脚本模板
#!/bin/sh BEGIN INIT INFO # Provides: myapp # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Should-Start: mysql # Should-Stop: mysql # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start/stop my custom app END INIT INFO case "$1" in start) echo "Starting myapp..." /usr/bin/python3 /opt/myapp/main.py & ;; stop) pkill -f /opt/myapp/main.py ;; restart|force-reload) $0 stop sleep 2 $0 start ;; ) echo "Usage: service myapp {start|stop|restart}" exit 1 ;; esac
保存路径:/etc/init.d/myapp
赋权:sudo chmod +x /etc/init.d/myapp
注册启动项:sudo update-rc.d myapp defaults
(添加到 runlevel 2-5)
️ 注意:SysVinit 已被大多数现代发行版弃用,仅用于维护遗留系统。
高级方案:Supervisor 进程管理器
当需要同时管理多个相互依赖的服务,或对进程进行细粒度控制时,Supervisor 是更优选择。
安装与配置
# Ubuntu/Debian sudo apt install supervisor # CentOS/RHEL sudo yum install epel-release && sudo yum install supervisor
创建配置文件 /etc/supervisor/conf.d/myapp.conf
:
[program:myapp] command=/usr/bin/python3 /opt/myapp/main.py directory=/opt/myapp user=nobody autostart=true autorestart=true startsecs=5 stopasgroup=true killasgroup=true stdout_logfile=/var/log/supervisor/myapp.out.log stderr_logfile=/var/log/supervisor/myapp.err.log
重启 Supervisor 使配置生效:sudo supervisorctl reload
优势对比
特性 | Systemd | Supervisor |
---|---|---|
进程监控 | ||
日志切割 | 需自行配置 | 内置日志轮转 |
网页管理界面 | 无 | (http://localhost:9001 ) |
多进程协同 | 有限支持 | 擅长管理进程组 |
跨发行版兼容性 | 高 | 中等 |
容器化部署(Docker)
对于云原生应用,可将服务打包为 Docker 容器,通过 Compose 或 Kubernete 编排。
基础示例
创建 Dockerfile
:
FROM python:3.8-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "main.py"]
构建镜像并运行:
docker build -t myapp . docker run -d --name myapp-container -p 8080:8080 myapp
若要后台持久化运行,可结合 docker-compose up -d
。
通用注意事项
风险点 | 解决方案 |
---|---|
端口占用冲突 | 启动前用 netstat -tulnp | grep <port> 检查,或修改应用监听端口 |
文件权限不足 | 确保执行用户对二进制文件和数据目录有读写权限 |
环境变量缺失 | 在 Systemd 文件中添加 Environment="KEY=VALUE" |
僵尸进程堆积 | 在 Supervisor 中设置 startretries=3 限制重试次数 |
SELinux 拦截 | 临时禁用验证:getenforce → permissive ,永久修复需添加 selinux 策略 |
常见问题解答(FAQ)
Q1: 同一个服务能否同时存在多个实例?
A: 不建议直接启动多个相同服务的实例,可能导致端口冲突或资源竞争,若需横向扩展,可采用以下任一方案:
- 负载均衡模式:通过 Nginx/HAProxy 反向代理分发请求到不同端口实例。
- 集群化改造:修改应用使其支持分布式 ID(如Redis)、共享存储(NFS/GlusterFS)。
- 命名空间隔离:使用 Docker/Podman 创建独立容器实例。
Q2: 服务启动后立即崩溃怎么办?
排查步骤:
- 查看详细错误日志:
journalctl -u myapp.service -b -1
(显示上次启动以来的日志) - 手动执行启动命令:以相同用户身份在终端运行
ExecStart
指定的命令,观察报错信息。 - 检查依赖项:确认数据库连接、配置文件路径、环境变量是否正确。
- 调整 Type 类型:若程序需要前台交互,尝试将
Type=simple
改为Type=forking
。 - 延长启动超时:在
[Service]
段添加TimeoutStartSec=30
(默认 90 秒)。
通过以上方法,可根据实际需求选择合适的服务管理方案,对于新项目,优先采用 Systemd;若涉及复杂进程管理,推荐 Supervisor;微服务架构则更适合容器化