当前位置:首页 > Linux > 正文

linux 如何添加服务

在 Linux 中,可通过创建 /etc/systemd/system/ 下的 .service 文件定义服务,然后用 systemctl enable 设为开机启动,`systemctl start

Linux 系统中添加服务的核心目标是实现自动化启动持续运行,确保服务随系统开机自动加载,并在意外终止时能够自动重启,以下是主流的实现方式及完整操作指南,涵盖从基础到进阶的多种场景。

linux 如何添加服务  第1张


基于 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
  • Restarton-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: 服务启动后立即崩溃怎么办?

排查步骤

  1. 查看详细错误日志journalctl -u myapp.service -b -1(显示上次启动以来的日志)
  2. 手动执行启动命令:以相同用户身份在终端运行 ExecStart 指定的命令,观察报错信息。
  3. 检查依赖项:确认数据库连接、配置文件路径、环境变量是否正确。
  4. 调整 Type 类型:若程序需要前台交互,尝试将 Type=simple 改为 Type=forking
  5. 延长启动超时:在 [Service] 段添加 TimeoutStartSec=30(默认 90 秒)。

通过以上方法,可根据实际需求选择合适的服务管理方案,对于新项目,优先采用 Systemd;若涉及复杂进程管理,推荐 Supervisor;微服务架构则更适合容器化

0