1. Systemd 基础概念
什么是 Systemd?
Systemd 是 Linux 系统的现代初始化系统和服务管理器,取代了传统的 SysVinit。它提供:
更快的启动时间
更好的并行处理
高级服务管理功能
依赖关系管理
2. Systemd 核心组件
单元(Units)
Systemd 通过单元管理各种系统资源:
单元类型 | 文件扩展名 | 用途 |
|---|---|---|
Service |
| 管理系统服务(如 Apache、MySQL) |
Socket |
| 管理网络/IPC 套接字 |
Target |
| 分组其他单元(类似运行级别) |
Timer |
| 定时任务管理 |
Mount |
| 文件系统挂载点 |
3. 常用 Systemd 命令
服务管理命令
# 启动服务 sudo systemctl start service_name.service # 停止服务 sudo systemctl stop service_name.service # 重启服务 sudo systemctl restart service_name.service # 重新加载配置(不重启) sudo systemctl reload service_name.service # 查看服务状态 sudo systemctl status service_name.service # 启用开机自启 sudo systemctl enable service_name.service # 禁用开机自启 sudo systemctl disable service_name.service # 检查是否启用 sudo systemctl is-enabled service_name.service系统状态查看
# 列出所有已加载的单元 systemctl list-units # 仅列出服务单元 systemctl list-units --type=service # 查看失败的服务 systemctl --failed # 查看系统启动时间 systemd-analyze time # 分析启动过程各服务耗时 systemd-analyze blame目标(Target)管理
# 查看当前目标 systemctl get-default # 设置默认目标 sudo systemctl set-default multi-user.target # 切换到救援模式 sudo systemctl isolate rescue.target # 切换到图形界面 sudo systemctl isolate graphical.target # 紧急模式 sudo systemctl emergency4. 创建自定义 Systemd 服务
基本服务文件结构
创建/etc/systemd/system/my-service.service:
[Unit] Description=我的自定义服务描述 Documentation=https://example.com/docs After=network.target Wants=network.target [Service] Type=simple User=myuser Group=mygroup ExecStart=/usr/local/bin/my-service ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=10s StandardOutput=journal StandardError=journal Environment="APP_ENV=production" WorkingDirectory=/var/lib/my-service [Install] WantedBy=multi-user.target服务类型说明
# Type=simple(默认)- 主进程不会 fork Type=simple # Type=forking - 主进程会 fork 子进程 Type=forking PIDFile=/var/run/my-service.pid # Type=oneshot - 执行一次就退出 Type=oneshot RemainAfterExit=yes # Type=notify - 服务就绪时通知 systemd Type=notify重启策略配置
# 从不重启 Restart=no # 只在失败时重启 Restart=on-failure # 总是重启(即使正常退出) Restart=always # 除非被手动停止,否则总是重启 Restart=on-abnormal5. 实际应用示例
示例1:Python 应用服务
[Unit] Description=Python Web 应用 After=network.target mysql.service Requires=mysql.service [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/opt/myapp ExecStart=/usr/bin/python3 app.py ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=5 Environment=PYTHONPATH=/opt/myapp Environment=DATABASE_URL=mysql://user:pass@localhost/db [Install] WantedBy=multi-user.target示例2:Node.js 应用服务
[Unit] Description=Node.js API 服务器 After=network.target redis.service Wants=redis.service [Service] Type=simple User=nodeapp Group=nodeapp WorkingDirectory=/srv/nodeapp ExecStart=/usr/bin/node index.js ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal Environment=NODE_ENV=production Environment=PORT=3000 # 资源限制 LimitNOFILE=65536 LimitNPROC=4096 [Install] WantedBy=multi-user.target示例3:Java 应用服务
[Unit] Description=Java 企业应用 After=network.target [Service] Type=simple User=javaapp Group=javaapp WorkingDirectory=/opt/javaapp ExecStart=/usr/bin/java -jar app.jar ExecStop=/bin/kill -TERM $MAINPID Restart=on-failure RestartSec=30 # JVM 参数 Environment=JAVA_OPTS="-Xmx2g -Xms1g -Dspring.profiles.active=prod" # 安全设置 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ReadWritePaths=/var/lib/javaapp /var/log/javaapp [Install] WantedBy=multi-user.target6. 高级功能
定时任务(Timer)
创建/etc/systemd/system/backup.timer:
[Unit] Description=每日备份任务 Requires=backup.service [Timer] OnCalendar=daily Persistent=true RandomizedDelaySec=300 [Install] WantedBy=timers.target对应的服务文件/etc/systemd/system/backup.service:
[Unit] Description=系统备份服务 [Service] Type=oneshot User=backup ExecStart=/usr/local/bin/backup-script.sh套接字激活(Socket Activation)
创建/etc/systemd/system/my-service.socket:
[Unit] Description=My Service Socket [Socket] ListenStream=8080 Accept=yes [Install] WantedBy=sockets.target对应的服务文件会自动为每个连接启动实例。
7. 日志管理
使用 Journalctl 查看日志
# 查看特定服务的日志 journalctl -u my-service.service # 实时跟踪日志 journalctl -u my-service.service -f # 查看指定时间范围的日志 journalctl -u my-service.service --since="2025-01-01 00:00:00" --until="2025-01-01 23:59:59" # 查看最近日志(最新100行) journalctl -u my-service.service -n 100 # 按优先级过滤 journalctl -u my-service.service -p err # 查看内核日志 journalctl -k # 查看系统启动日志 journalctl -b日志轮转配置
创建/etc/systemd/journald.conf.d/custom.conf:
[Journal] SystemMaxUse=1G SystemMaxFileSize=100M SystemMaxFiles=10 MaxRetentionSec=1month8. 故障排除和调试
服务诊断
# 检查服务状态详情 systemctl status my-service.service -l # 查看服务依赖关系 systemctl list-dependencies my-service.service # 验证服务文件语法 systemd-analyze verify /etc/systemd/system/my-service.service # 测试服务启动(不实际启动) systemctl --dry-run start my-service.service调试模式启动
# 在前台运行服务进行调试 systemctl edit my-service.service添加:
[Service] Environment=DEBUG=1 StandardOutput=console StandardError=console9. 安全最佳实践
服务安全加固
[Service] # 使用专用用户 User=service-user Group=service-group # 文件系统保护 ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/lib/myservice NoNewPrivileges=true # 网络安全 PrivateNetwork=false RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 # 资源限制 LimitNOFILE=65536 MemoryMax=512M CPUQuota=80%创建专用系统用户
# 创建无登录权限的系统用户 sudo useradd -r -s /bin/false -d /var/lib/myapp myapp-user sudo mkdir -p /var/lib/myapp sudo chown myapp-user:myapp-user /var/lib/myapp10. 实用脚本和工具
服务监控脚本
#!/bin/bash # monitor-service.sh SERVICE_NAME="my-service.service" MAX_RESTARTS=3 CHECK_INTERVAL=30 monitor_service() { local restarts=0 while true; do if ! systemctl is-active --quiet "$SERVICE_NAME"; then echo "$(date): 服务 $SERVICE_NAME 未运行,尝试重启..." systemctl restart "$SERVICE_NAME" ((restarts++)) if [ $restarts -ge $MAX_RESTARTS ]; then echo "$(date): 错误: 服务重启次数超过限制" exit 1 fi else restarts=0 fi sleep $CHECK_INTERVAL done } monitor_service批量服务管理
#!/bin/bash # manage-services.sh SERVICES=("nginx" "mysql" "redis") case "$1" in start) for service in "${SERVICES[@]}"; do echo "启动 $service..." sudo systemctl start "$service" done ;; stop) for service in "${SERVICES[@]}"; do echo "停止 $service..." sudo systemctl stop "$service" done ;; status) for service in "${SERVICES[@]}"; do echo "=== $service 状态 ===" systemctl status "$service" --no-pager -l echo done ;; *) echo "用法: $0 {start|stop|status}" exit 1 ;; esac11. 实际部署流程
完整部署示例
# 1. 创建服务文件 sudo nano /etc/systemd/system/myapp.service # 2. 重新加载 systemd 配置 sudo systemctl daemon-reload # 3. 测试服务语法 systemd-analyze verify /etc/systemd/system/myapp.service # 4. 启动服务测试 sudo systemctl start myapp.service # 5. 检查状态和日志 sudo systemctl status myapp.service journalctl -u myapp.service -f # 6. 启用开机自启 sudo systemctl enable myapp.service # 7. 测试重启后是否正常 sudo systemctl reboot这个全面的 Systemd 使用指南涵盖了从基础概念到高级用法的所有方面,可以帮助您有效地管理系统服务。
参考:Mastering Systemd in Linux: A Comprehensive Guide — linuxvox.com