Linux---systemd自启动
一、自启动脚本的基本概念
在 Linux 系统中,自启动脚本是指在系统启动时自动执行的程序或脚本。systemd 通过服务单元(.service 文件)来管理这类脚本,实现精细化控制(如启动顺序、依赖关系、资源限制等)。
二、服务单元文件的基本结构
一个完整的服务单元文件分为三个核心部分:
[Unit]
Description=My Service
After=network.target[Service]
Type=simple
ExecStart=/path/to/script.sh
Restart=on-failure[Install]
WantedBy=multi-user.target
三、[Unit] 段配置详解
此段定义服务的通用属性和依赖关系:
[Unit]
Description=My Custom Service
Documentation=man:systemd.service(5)
After=network.target # 在网络服务后启动
Wants=other-service.service # 弱依赖,不影响本服务启动
Requires=db.service # 强依赖,依赖服务失败则本服务失败
Conflicts=legacy-service.service # 冲突服务,不能同时运行
四、[Service] 段配置详解
此段定义服务的核心运行参数:
[Service]
Type=simple # 简单模式(默认)
ExecStart=/usr/bin/myapp # 启动命令
ExecStartPre=/bin/prepare.sh # 启动前执行的命令
ExecStop=/usr/bin/myapp stop # 停止命令
ExecReload=/usr/bin/myapp reload # 重载命令
Restart=always # 总是重启(on-failure、on-success 等)
RestartSec=5s # 重启前等待时间
User=myuser # 运行用户
Group=mygroup # 运行组
WorkingDirectory=/opt/myapp # 工作目录
Environment=VAR1=value1 # 设置环境变量
EnvironmentFile=/etc/default/myapp # 从文件加载环境变量
KillMode=process # 终止模式(process、control-group 等)
TimeoutStartSec=30 # 启动超时时间
TimeoutStopSec=60 # 停止超时时间
五、[Install] 段配置详解
此段定义服务的安装和激活方式:
[Install]
WantedBy=multi-user.target # 加入多用户目标(开机自启)
RequiredBy=app.target # 强依赖目标
Alias=myapp.service # 服务别名
Also=other-service.service # 同时激活的其他服务
六、服务类型(Type=)详解
systemd 支持多种服务启动类型:
类型 | 说明 |
---|---|
simple | 默认值,ExecStart 为主进程,适合直接启动的程序。 |
forking | 程序通过 fork() 创建子进程,需配合 PIDFile 使用(如传统守护进程)。 |
oneshot | 一次性任务,执行完毕后退出,需设置 RemainAfterExit=yes 保持活跃。 |
dbus | 通过 D-Bus 通信的服务,需设置 BusName=。 |
notify | 通过 sd_notify() 通知启动完成的服务。 |
idle | 所有其他任务完成后才执行的服务。 |
七、环境变量配置
通过以下方式设置服务运行环境:
[Service]
# 直接设置
Environment="VAR1=value1" "VAR2=value2"# 从文件读取
EnvironmentFile=/etc/sysconfig/myapp
EnvironmentFile=-/etc/default/myapp # "-" 表示文件不存在时忽略# 特殊变量
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
八、资源限制配置
使用 systemd 的资源控制功能限制服务资源使用:
[Service]
CPUQuota=50% # 限制 CPU 使用率
MemoryLimit=100M # 限制内存使用
LimitNOFILE=10240 # 最大文件描述符数
TasksMax=1000 # 最大进程数
IPAddressDeny=any # 拒绝所有网络连接
IPAddressAllow=192.168.1.0/24 # 仅允许特定网络
九、日志与监控配置
配置服务的日志记录和监控机制:
[Service]
StandardOutput=journal # 输出到系统日志
StandardError=journal # 错误输出到系统日志
SyslogIdentifier=myapp # 日志标识符
WatchdogSec=30 # 启用看门狗,30秒内无响应则重启
SuccessExitStatus=0 1 2 # 定义哪些退出码视为成功
十、安装与管理自启动脚本
完成服务文件编写后,通过以下步骤安装和管理:
-
创建服务文件:
sudo nano /etc/systemd/system/myapp.service
-
重载 systemd 配置:
sudo systemctl daemon-reload
-
启动服务:
sudo systemctl start myapp.service
-
设置开机自启:
sudo systemctl enable myapp.service
-
检查服务状态:
sudo systemctl status myapp.service
-
查看服务日志:
journalctl -u myapp.service -f
十一、高级技巧与最佳实践
-
使用套接字激活:
# myapp.socket [Socket] ListenStream=8080[Install] WantedBy=sockets.target
-
创建服务依赖链:
[Unit] After=network.target db.service Requires=db.service
-
条件启动:
[Unit] ConditionPathExists=/etc/myapp.conf ConditionKernelCommandLine=!debug
-
配置文件覆盖:
sudo systemctl edit myapp.service
此命令会创建一个覆盖文件,避免直接修改原始服务文件。
十二、故障排查指南
-
检查服务状态:
sudo systemctl status myapp.service
-
查看详细日志:
journalctl -u myapp.service --no-pager journalctl -u myapp.service -xe # 显示详细错误
-
分析启动时间:
systemd-analyze blame systemd-analyze critical-chain myapp.service
-
测试服务手动启动:
/usr/bin/myapp # 直接执行服务命令,检查输出
十三、示例:创建一个 Node.js 应用自启动服务
[Unit]
Description=ROS2 Vision Launch Service
After=network.target[Service]
Type=simple
User=kyleExecStartPre=/bin/sleep 5
ExecStart=/bin/bash -c 'cd /home/kyle/RM/Observation_of_whole_robot && source install/setup.bash && ros2 launch rm_vision_bringup vision_bringup.launch.py'Restart=always
RestartSec=5
# 防止服务重启过快导致资源耗尽
StartLimitInterval=60s
StartLimitBurst=3[Install]
WantedBy=multi-user.target
十四、关键注意事项
-
文件权限:
- 服务文件权限应为
644
- 执行脚本权限应为
755
- 服务文件权限应为
-
避免无限重启:
[Unit] StartLimitIntervalSec=60 StartLimitBurst=3
-
正确处理依赖关系:
- 使用
After=
而非Requires=
避免不必要的强依赖 - 优先使用
Wants=
而非Requires=
- 使用
-
安全最佳实践:
[Service] PrivateTmp=true ProtectSystem=full NoNewPrivileges=true
十五、总结
通过合理设计 systemd 服务单元文件,可以实现:
- 精确控制服务启动顺序与依赖关系
- 资源使用的精细化管理
- 可靠的服务监控与自动恢复
- 标准化的服务部署与维护