云计算百科
云计算领域专业知识百科平台

systemd的使用和编写

一、先跑起来

  • 任意脚本做成系统服务(以每 60 秒打印日期为例)
  • # 1. 准备脚本
    sudo tee /usr/local/bin/date_demo.sh <<'EOF'
    #!/bin/bash
    while :; do echo "[$(date)] Hello systemd" >>/var/log/date_demo.log; sleep 60; done
    EOF

    sudo chmod +x /usr/local/bin/date_demo.sh

    # 2. 写最简 .service
    sudo tee /etc/systemd/system/date_demo.service <<'EOF'
    [Unit]
    Description=Date demo service
    After=network.target

    [Service]
    Type=simple
    ExecStart=/usr/local/bin/date_demo.sh
    Restart=always
    RestartSec=5s

    [Install]
    WantedBy=multi-user.target
    EOF

    # 3. 加载 + 启动 + 开机自启
    sudo systemctl daemon-reload
    sudo systemctl enable –now date_demo
    sudo systemctl status date_demo
    # 看日志
    sudo journalctl -u date_demo -f

    至此,你已经掌握了“脚本→服务→自启→日志”完整闭环 。


    二、编写单元文件必知必会

  • 三大部分记忆口诀
    • [Unit] 管“依赖、启动顺序”
    • [Service] 管“怎么跑、跑谁、跑挂了怎么办”
    • [Install] 管“开机要不要带出来”
  • 最常用的 10 条字段(背下来够用 90% 场景)
  • 字段作用示例
    Description= 一句话说明 My Web API
    After= / Before= 顺序 After=network-online.target mysql.service
    Wants= / Requires= 弱/强依赖 Wants=redis
    Type= 启动方式 simple(默认) forking(旧守护) oneshot(一次性)
    ExecStart= 主进程 /usr/local/bin/api.sh
    ExecReload= 平滑重载 /bin/kill -HUP $MAINPID
    Restart= 自动重启策略 always on-failure no
    RestartSec= 重启间隔 10s
    User= / Group= 降权运行 User=app
    WantedBy= 开机自启目标 multi-user.target
  • 字段坑位提醒
    • forking 类型必须配 PIDFile=,否则 systemd 找不到“主进程” 。
    • oneshot 类型搭配 RemainAfterExit=yes 才能实现“一次性但保持 active”状态 。
    • 降权运行时,工作目录 / 缓存目录要提前赋权,否则频繁报 Permission denied。

    三、高频场景模板(直接改路径即可)

  • 绿色二进制(如 frps、nps)
  • [Unit]
    Description=Frp Server
    After=network-online.target
    Wants=network-online.target

    [Service]
    Type=simple
    ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.toml
    Restart=always
    RestartSec=5s

    [Install]
    WantedBy=multi-user.target

  • Python 虚拟环境项目
  • [Unit]
    Description=My Flask API
    After=network-online.target

    [Service]
    Type=simple
    User=app
    WorkingDirectory=/opt/myapp
    ExecStart=/opt/venv/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=20s
    Environment="PATH=/opt/venv/bin"

    [Install]
    WantedBy=multi-user.target

  • 一次性备份 + 定时器(替代 cron)
    rsync-to-win.service
  • [Unit]
    Description=Backup to Windows share
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/rsync_to_win.sh

    rsync-to-win.timer

    [Unit]
    Description=Run backup every 10 min
    [Timer]
    OnCalendar=*:0/10
    Persistent=true
    [Install]
    WantedBy=timers.target

    启用:

    sudo systemctl daemon-reload
    sudo systemctl enable –now rsync-to-win.timer
    # 查看下次执行时间
    systemctl list-timers


    四、日常运维 6 命令

    任务命令
    修改完 .service 文件 sudo systemctl daemon-reload
    启动/停止/重启 sudo systemctl start|stop|restart 单元名
    开机自启 / 关闭 sudo systemctl enable|disable 单元名
    看实时日志 sudo journalctl -u 单元名 -f
    看历史启动耗时 systemd-analyze blame
    看单元依赖图 systemctl dot | dot -Tsvg > /tmp/tree.svg

    五、排错 3 板斧

  • 状态高亮法
    systemctl status 单元名 ➜ 红色关键字 failed / exit-code / signal 直接定位。

  • 日志级别法
    sudo journalctl -u 单元名 -o cat -p err..alert 只看错误与告警。

  • 手动跑一遍法
    把 ExecStart= 命令原样复制到终端执行,90% 路径/权限/环境变量错误会立即现形。


  • 六、进阶路线(用到再查)

    • 资源限制:MemoryMax=、TasksMax=、LimitNOFILE=
    • 平滑启动:ExecStartPre=、ExecStartPost=、TimeoutStartSec=
    • 多实例模板:@.service 模板 + 实例名
    • 用户级服务:systemctl –user enable 单元名(无需 root)
    • 网络依赖:systemd-networkd-wait-online.service 与 network-online.target 的区别

    七、一句话总结

    “写单元文件就是填空题:描述→依赖→怎么跑→跑挂怎么办→要不要自启;
    日常运维就是 6 个命令:reload、start、enable、status、journalctl、list-timers。”
    掌握以上套路后,任何脚本、二进制、Python 项目、定时任务都能 5 分钟接入 systemd。祝玩得开心!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » systemd的使用和编写
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!