Ubuntu22.04利用systemd实现自定义服务开机自启动

Ubuntu22.04利用systemd实现自定义服务开机自启动 1. 为什么需要systemd管理开机服务在Ubuntu系统中传统的rc.local方式已经逐渐被systemd取代。我刚开始接触Ubuntu22.04时就踩过这个坑明明按照老教程配置了rc.local重启后发现脚本根本没执行。后来才发现从Ubuntu16.04开始systemd就成为了默认的初始化系统。systemd相比传统init系统有几个明显优势并行启动可以同时启动多个服务大幅缩短开机时间依赖管理自动处理服务间的依赖关系状态监控可以实时查看服务运行状态日志集成所有服务日志统一由journald管理实测下来用systemd配置的自启动服务确实更稳定。我有个Python爬虫脚本需要24小时运行之前用crontab定时检查经常出现重复启动的问题。改用systemd后通过Typeforking参数完美解决了这个问题。2. 准备你的自启动脚本在创建服务之前我们需要先准备好要自动运行的脚本。这里以我实际用到的/home/user/scripts/auto_start.sh为例#!/bin/bash # 这是一个简单的示例脚本 while true do echo $(date): 服务运行中... /var/log/my_service.log sleep 60 done关键注意事项脚本第一行必须指定解释器如#!/bin/bash要给脚本执行权限chmod x /path/to/script.sh脚本中的文件路径建议使用绝对路径长时间运行的脚本要有退出机制避免无限循环我遇到过脚本权限问题导致服务启动失败的坑。后来养成了习惯每次都会用ls -l确认脚本是否有x权限。3. 创建systemd服务单元文件服务单元文件通常放在/etc/systemd/system/目录下。我们创建一个名为my_custom_service.service的文件sudo vim /etc/systemd/system/my_custom_service.service文件内容模板如下[Unit] Description我的自定义服务 Afternetwork.target [Service] Typesimple Useruser Groupuser WorkingDirectory/home/user/scripts ExecStart/bin/bash /home/user/scripts/auto_start.sh Restartalways RestartSec10 [Install] WantedBymulti-user.target参数详解Afternetwork.target表示等网络就绪后再启动Typesimple适用于直接运行的脚本Restartalways确保脚本意外退出后自动重启User和Group指定运行身份建议不要用root我建议把WorkingDirectory设置成脚本所在目录这样脚本中的相对路径都能正确解析。4. 服务管理实战操作创建好服务文件后需要执行以下命令使配置生效# 重新加载systemd配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start my_custom_service # 设置开机自启 sudo systemctl enable my_custom_service # 查看服务状态 sudo systemctl status my_custom_service常见问题排查如果状态显示failed用journalctl -u my_custom_service -b查看详细日志权限问题常见于脚本或日志文件可以用sudo -u user /path/to/script.sh测试环境变量问题可以在服务文件中用EnvironmentKEYvalue指定我管理着十几台服务器发现最常出现的问题是环境变量缺失。后来养成了习惯在服务文件中显式声明所有需要的环境变量。5. 高级配置技巧对于更复杂的场景systemd还提供了许多实用功能资源限制[Service] MemoryLimit500M CPUQuota50%定时重启[Service] RuntimeMaxSec86400 # 24小时后重启多脚本顺序执行[Unit] Requiresother_service.service Afterother_service.service环境文件 创建一个/etc/my_service_env文件DB_HOSTlocalhost DB_PORT3306然后在服务文件中引用[Service] EnvironmentFile/etc/my_service_env我在生产环境用RuntimeMaxSec解决过内存泄漏问题每周自动重启一次服务比手动干预稳定多了。6. 替代方案对比虽然systemd是首选但了解其他方法也有必要crontab方式reboot /path/to/script.sh缺点是无法管理服务状态适合简单任务。upstart Ubuntu早期版本使用现在已弃用。rc.local 虽然可以手动启用但systemd对它的支持有限不推荐。实测对比发现systemd的服务管理功能最完善。特别是systemctl status能一眼看出服务是否正常这是其他方法做不到的。7. 实际应用案例分享一个我部署的监控服务配置[Unit] Description服务器监控服务 Afterredis.service mysql.service [Service] Typenotify Usermonitor Groupmonitor WorkingDirectory/opt/monitor ExecStart/usr/bin/python3 /opt/monitor/main.py EnvironmentFile/etc/monitor_env Restarton-failure RestartSec5 TimeoutStopSec30 NotifyAccessall [Install] WantedBymulti-user.target这个配置有几个亮点Typenotify让Python脚本能主动通知systemd启动完成明确依赖redis和mysql服务使用独立用户运行提高安全性超时设置避免停止时卡住运行一年多来只出过两次问题都是因为依赖的redis服务没启动。后来加了Afterredis.service就彻底解决了。