在Linux系统管理中,服务开机自启动是一个基础但至关重要的需求。最近我在Rocky Linux 10.0系统上为keepalived_web.sh脚本配置开机自启动时,经历了一番探索和尝试。本文将详细记录整个过程,包括两种主流方案的对比、具体实现步骤以及背后的技术原理。
系统环境:
核心需求:
提示:Rocky Linux作为RHEL的替代发行版,其系统管理与RHEL/CentOS基本一致。理解这一点有助于我们在其他类似系统上迁移配置。
在Linux系统中,实现开机自启动主要有以下几种方式:
经过评估,我重点考虑了前两种方案。systemd是当前的标准方案,功能强大但配置相对复杂;rc.local虽然"古老"但简单直接,特别适合单一脚本的启动需求。
首先尝试了systemd方案,创建了服务单元文件/etc/systemd/system/keepalived-web.service:
bash复制[Unit]
Description=Keepalived Web Service
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/paraview/esc/bin/keepalived_web.sh start
RemainAfterExit=yes
User=root
[Install]
WantedBy=multi-user.target
关键参数解析:
Type=oneshot:适用于执行一次性任务而非常驻服务RemainAfterExit=yes:即使命令执行完毕仍标记服务为activeAfter=network.target:确保网络就绪后再执行脚本bash复制sudo systemctl daemon-reload
bash复制sudo systemctl enable keepalived-web
bash复制sudo systemctl start keepalived-web
bash复制sudo systemctl status keepalived-web
在实际操作中,遇到了几个典型问题:
尝试过的解决方案包括:
经过多次调试,虽然服务能够运行,但始终存在一些不稳定因素。考虑到这是一个相对简单的启动需求,最终决定转向更传统的rc.local方案。
选择rc.local方案主要基于以下考虑:
注意:虽然rc.local在现代systemd系统中是通过服务实现的(rc-local.service),但其使用方式与传统一致,保持了良好的兼容性。
bash复制sudo vi /etc/rc.d/rc.local
文件内容示例:
bash复制#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
touch /var/lock/subsys/local
# ============================================
# 启动 keepalived_web 服务
# ============================================
sudo /opt/paraview/esc/bin/keepalived_web.sh start >> /var/log/rc.local.log 2>&1
exit 0
关键点说明:
>> /var/log/rc.local.log 2>&1:将标准输出和错误都重定向到日志文件exit 0:必须保留,表示脚本成功结束bash复制sudo chmod +x /etc/rc.d/rc.local
在某些系统上,可能需要手动启用rc-local服务:
bash复制sudo systemctl enable rc-local
sudo systemctl start rc-local
bash复制ls -l /etc/rc.d/rc.local
# 应有类似输出:-rwxr-xr-x. 1 root root 535 Jun 10 15:30 /etc/rc.d/rc.local
bash复制sudo /etc/rc.d/rc.local
bash复制tail -f /var/log/rc.local.log
bash复制/opt/paraview/esc/bin/keepalived_web.sh status
bash复制sudo reboot
| 特性 | systemd方案 | rc.local方案 |
|---|---|---|
| 复杂性 | 较高,需要了解unit文件语法 | 低,只需添加命令 |
| 灵活性 | 高,可精细控制依赖和参数 | 低,简单命令执行 |
| 启动顺序控制 | 精确,可通过After/Before指定 | 不精确,通常在启动后期执行 |
| 日志管理 | 完善,可通过journalctl查看 | 需手动重定向到文件 |
| 适用场景 | 复杂服务、需要精细控制的场景 | 简单脚本、快速解决方案 |
| 系统兼容性 | 仅限systemd系统 | 几乎所有Linux发行版 |
日志记录至关重要:
权限问题排查:
启动顺序考量:
bash复制while ! ping -c 1 example.com &>/dev/null; do sleep 1; done
备选方案考虑:
系统更新影响:
虽然本文最终选择了rc.local方案,但对于需要更复杂控制的场景,systemd仍有其优势。以下是几个优化方向:
服务依赖精确控制:
ini复制After=network-online.target
Wants=network-online.target
环境变量设置:
ini复制Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
资源限制:
ini复制LimitNOFILE=65536
LimitMEMLOCK=infinity
重启策略:
ini复制Restart=on-failure
RestartSec=5s
多命令执行与错误处理:
bash复制/path/to/script1 || echo "script1 failed" >> /var/log/rc.local.log
/path/to/script2 && echo "script2 succeeded" >> /var/log/rc.local.log
条件执行:
bash复制if [ -f /some/file ]; then
/path/to/script
fi
启动延迟:
bash复制sleep 10
/path/to/script
cron @reboot:
bash复制crontab -e
@reboot /path/to/script
systemd临时文件:
bash复制sudo systemd-tmpfiles --create /etc/tmpfiles.d/myscript.conf
用户级systemd服务:
bash复制systemctl --user enable myservice
在实际工作中,选择哪种方案取决于具体需求、系统环境以及维护团队的熟悉程度。对于简单的启动需求,rc.local提供了快速可靠的解决方案;而对于复杂的服务管理,systemd则展现出其强大而灵活的特性。