systemctl 命令详解#

systemctl 是 Linux 系统中用于控制 systemd 系统和服务管理器的命令。它是现代 Linux 发行版(如 Ubuntu、CentOS、Fedora 等)中管理系统服务的主要工具,可以启动、停止、重启服务,管理系统状态,查看日志等。

入门#

基本用法#

# 启动服务
sudo systemctl start nginx

# 停止服务
sudo systemctl stop nginx

# 重启服务
sudo systemctl restart nginx

# 重新加载服务配置
sudo systemctl reload nginx

# 查看服务状态
systemctl status nginx

常用选项#

选项说明
start启动服务
stop停止服务
restart重启服务
reload重新加载配置
status查看服务状态
enable开机自启动
disable禁用开机自启动
is-enabled检查是否开机自启动
is-active检查服务是否运行

基本示例#

# 启动 Apache 服务
sudo systemctl start apache2

# 查看服务状态
systemctl status apache2

# 输出示例:
# ● apache2.service - The Apache HTTP Server
#      Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
#      Active: active (running) since Mon 2024-01-15 10:00:00 CST; 1h ago
#        Docs: https://httpd.apache.org/docs/2.4/
#    Main PID: 1234 (apache2)
#       Tasks: 55 (limit: 4915)
#      Memory: 15.2M
#         CPU: 123ms
#     CGroup: /system.slice/apache2.service
#             ├─1234 /usr/sbin/apache2 -k start
#             ├─1235 /usr/sbin/apache2 -k start
#             └─1236 /usr/sbin/apache2 -k start

中级#

服务管理#

# 设置开机自启动
sudo systemctl enable nginx

# 禁用开机自启动
sudo systemctl disable nginx

# 检查服务是否开机自启动
systemctl is-enabled nginx

# 检查服务是否运行
systemctl is-active nginx

# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 查看所有服务
systemctl list-units --type=service

# 查看所有已启用的服务
systemctl list-unit-files --type=service --state=enabled

服务状态查询#

# 查看服务详细状态
systemctl status nginx

# 查看服务属性
systemctl show nginx

# 查看服务启动时间
systemctl show nginx --property=ActiveEnterTimestamp

# 查看服务进程 ID
systemctl show nginx --property=MainPID

# 查看服务内存使用
systemctl show nginx --property=MemoryCurrent

# 查看服务 CPU 使用
systemctl show nginx --property=CPUUsageNSec

服务依赖关系#

# 查看服务依赖
systemctl list-dependencies nginx

# 查看反向依赖(哪些服务依赖此服务)
systemctl list-dependencies --reverse nginx

# 查看所有依赖(包括间接依赖)
systemctl list-dependencies --all nginx

# 查看服务启动顺序
systemctl show nginx --property=After
systemctl show nginx --property=Before

高级#

日志管理#

# 查看服务日志
journalctl -u nginx

# 实时查看服务日志
journalctl -u nginx -f

# 查看最近 100 条日志
journalctl -u nginx -n 100

# 查看特定时间段的日志
journalctl -u nginx --since "2024-01-15 10:00:00" --until "2024-01-15 11:00:00"

# 查看服务启动日志
journalctl -u nginx -b

# 查看上次启动的日志
journalctl -u nginx -b -1

服务配置#

# 查看服务配置文件
systemctl cat nginx

# 编辑服务配置文件
sudo systemctl edit nginx

# 编辑服务配置文件(完整)
sudo systemctl edit --full nginx

# 查看服务配置文件路径
systemctl show nginx --property=FragmentPath

# 重置服务配置
sudo systemctl revert nginx

系统管理#

# 关机
sudo systemctl poweroff

# 重启
sudo systemctl reboot

# 挂起
sudo systemctl suspend

# 休眠
sudo systemctl hibernate

# 查看系统运行级别
systemctl get-default

# 设置系统运行级别
sudo systemctl set-default multi-user.target

# 切换到图形界面
sudo systemctl isolate graphical.target

# 切换到多用户模式
sudo systemctl isolate multi-user.target

大师#

服务监控脚本#

#!/bin/bash
# 服务监控脚本

SERVICES=("nginx" "mysql" "redis" "docker")
LOG_FILE="service_monitor.log"
ALERT_EMAIL="admin@example.com"

# 监控服务状态
monitor_services() {
    while true; do
        TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
        
        for SERVICE in "${SERVICES[@]}"; do
            STATUS=$(systemctl is-active $SERVICE)
            
            if [ "$STATUS" != "active" ]; then
                echo "$TIMESTAMP - ALERT: $SERVICE is $STATUS" >> $LOG_FILE
                echo "Service $SERVICE is $STATUS, attempting to restart..."
                
                sudo systemctl restart $SERVICE
                
                if [ $? -eq 0 ]; then
                    echo "$TIMESTAMP - $SERVICE restarted successfully" >> $LOG_FILE
                else
                    echo "$TIMESTAMP - ERROR: Failed to restart $SERVICE" >> $LOG_FILE
                    echo "Service $SERVICE restart failed" | mail -s "Service Alert" $ALERT_EMAIL
                fi
            fi
        done
        
        sleep 300
    done
}

# 生成服务状态报告
generate_report() {
    local report_file="service_report_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "Service Status Report - $(date)" > $report_file
    echo "=============================" >> $report_file
    echo "" >> $report_file
    
    for SERVICE in "${SERVICES[@]}"; do
        echo "=== $SERVICE ===" >> $report_file
        systemctl status $SERVICE >> $report_file
        echo "" >> $report_file
    done
    
    echo "Report saved to: $report_file"
}

# 主函数
main() {
    case "$1" in
        monitor)
            monitor_services
            ;;
        report)
            generate_report
            ;;
        *)
            echo "Usage: $0 {monitor|report}"
            exit 1
            ;;
    esac
}

main "$@"

批量服务管理#

#!/bin/bash
# 批量服务管理脚本

# 批量启动服务
batch_start() {
    local services=("$@")
    
    for service in "${services[@]}"; do
        echo "Starting $service..."
        sudo systemctl start $service
        
        if [ $? -eq 0 ]; then
            echo "✓ $service started"
        else
            echo "✗ Failed to start $service"
        fi
    done
}

# 批量停止服务
batch_stop() {
    local services=("$@")
    
    for service in "${services[@]}"; do
        echo "Stopping $service..."
        sudo systemctl stop $service
        
        if [ $? -eq 0 ]; then
            echo "✓ $service stopped"
        else
            echo "✗ Failed to stop $service"
        fi
    done
}

# 批量重启服务
batch_restart() {
    local services=("$@")
    
    for service in "${services[@]}"; do
        echo "Restarting $service..."
        sudo systemctl restart $service
        
        if [ $? -eq 0 ]; then
            echo "✓ $service restarted"
        else
            echo "✗ Failed to restart $service"
        fi
    done
}

# 批量启用开机自启动
batch_enable() {
    local services=("$@")
    
    for service in "${services[@]}"; do
        echo "Enabling $service..."
        sudo systemctl enable $service
        
        if [ $? -eq 0 ]; then
            echo "✓ $service enabled"
        else
            echo "✗ Failed to enable $service"
        fi
    done
}

# 批量禁用开机自启动
batch_disable() {
    local services=("$@")
    
    for service in "${services[@]}"; do
        echo "Disabling $service..."
        sudo systemctl disable $service
        
        if [ $? -eq 0 ]; then
            echo "✓ $service disabled"
        else
            echo "✗ Failed to disable $service"
        fi
    done
}

# 主函数
main() {
    case "$1" in
        start)
            batch_start "${@:2}"
            ;;
        stop)
            batch_stop "${@:2}"
            ;;
        restart)
            batch_restart "${@:2}"
            ;;
        enable)
            batch_enable "${@:2}"
            ;;
        disable)
            batch_disable "${@:2}"
            ;;
        *)
            echo "Usage: $0 {start|stop|restart|enable|disable} [service1 service2 ...]"
            exit 1
            ;;
    esac
}

main "$@"

服务性能分析#

#!/bin/bash
# 服务性能分析脚本

SERVICE=$1
ANALYSIS_DURATION=60

# 收集服务性能数据
collect_performance_data() {
    local service=$1
    local duration=$2
    local output_file="performance_${service}_$(date +%Y%m%d_%H%M%S).csv"
    
    echo "timestamp,cpu_usage,memory_usage,active_connections" > $output_file
    
    for ((i=0; i<duration; i++)); do
        local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
        local cpu_usage=$(systemctl show $service --property=CPUUsageNSec | cut -d= -f2)
        local memory_usage=$(systemctl show $service --property=MemoryCurrent | cut -d= -f2)
        local active_connections=$(systemctl show $service --property=NConnections | cut -d= -f2)
        
        echo "$timestamp,$cpu_usage,$memory_usage,$active_connections" >> $output_file
        sleep 1
    done
    
    echo "Performance data collected: $output_file"
}

# 分析性能数据
analyze_performance() {
    local input_file=$1
    
    echo "=== Performance Analysis ==="
    echo ""
    
    # CPU 使用统计
    echo "CPU Usage:"
    awk -F, 'NR>1 {sum+=$2; count++} END {print "Average:", sum/count/1000000, "seconds"}' $input_file
    
    # 内存使用统计
    echo "Memory Usage:"
    awk -F, 'NR>1 {sum+=$3; count++} END {print "Average:", sum/count/1024/1024, "MB"}' $input_file
    
    # 连接数统计
    echo "Active Connections:"
    awk -F, 'NR>1 {sum+=$4; count++} END {print "Average:", sum/count}' $input_file
}

# 主函数
main() {
    if [ -z "$SERVICE" ]; then
        echo "Usage: $0 <service_name>"
        exit 1
    fi
    
    local output_file=$(collect_performance_data $SERVICE $ANALYSIS_DURATION)
    analyze_performance $output_file
}

main "$@"

无敌#

企业级服务管理系统#

#!/bin/bash
# 企业级服务管理系统

CONFIG_FILE="/etc/service_manager/config.conf"
LOG_DIR="/var/log/service_manager"
STATE_DIR="/var/run/service_manager"

mkdir -p $LOG_DIR $STATE_DIR

# 加载配置
source $CONFIG_FILE

# 初始化服务状态
init_service() {
    local service=$1
    local state_file="$STATE_DIR/${service}.state"
    
    if systemctl is-active $service > /dev/null 2>&1; then
        echo "active" > $state_file
        log_message "$service initialized as active"
    else
        echo "inactive" > $state_file
        log_message "$service initialized as inactive"
    fi
}

# 监控服务状态
monitor_service() {
    local service=$1
    local state_file="$STATE_DIR/${service}.state"
    
    while true; do
        local current_status=$(systemctl is-active $service 2>/dev/null)
        local saved_status=$(cat $state_file)
        
        if [ "$current_status" != "$saved_status" ]; then
            log_message "ALERT: $service status changed: $saved_status -> $current_status"
            
            if [ "$current_status" = "active" ]; then
                echo "active" > $state_file
            else
                echo "inactive" > $state_file
                
                # 尝试恢复服务
                if [ "$AUTO_RESTART" = "true" ]; then
                    log_message "Attempting to restart $service..."
                    systemctl restart $service
                    
                    if [ $? -eq 0 ]; then
                        log_message "$service restarted successfully"
                        echo "active" > $state_file
                    else
                        log_message "ERROR: Failed to restart $service"
                        send_alert "Service $service failed to restart"
                    fi
                fi
            fi
        fi
        
        sleep $MONITOR_INTERVAL
    done
}

# 记录日志
log_message() {
    local message=$1
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] $message" >> $LOG_DIR/manager.log
}

# 发送告警
send_alert() {
    local message=$1
    echo "$message" | mail -s "Service Manager Alert" $ALERT_EMAIL
}

# 生成服务报告
generate_service_report() {
    local report_file="$LOG_DIR/service_report_$(date +%Y%m%d).txt"
    
    echo "Service Manager Report - $(date +%Y-%m-%d)" > $report_file
    echo "=============================" >> $report_file
    echo "" >> $report_file
    
    for service in "${MANAGED_SERVICES[@]}"; do
        echo "=== $service ===" >> $report_file
        systemctl status $service >> $report_file
        echo "" >> $report_file
    done
    
    log_message "Service report generated: $report_file"
}

# 主程序
main() {
    log_message "Service Manager started"
    
    for service in "${MANAGED_SERVICES[@]}"; do
        init_service $service
        monitor_service $service &
    done
    
    while true; do
        if [ $(date +%H) -eq 0 ] && [ $(date +%M) -eq 0 ]; then
            generate_service_report
        fi
        
        sleep 60
    done
}

main

智能服务调度系统#

#!/bin/bash
# 智能服务调度系统

CONFIG_FILE="/etc/service_scheduler/config.conf"
LOG_FILE="/var/log/service_scheduler/scheduler.log"

mkdir -p $(dirname $LOG_FILE)

# 加载配置
source $CONFIG_FILE

# 检查系统负载
check_system_load() {
    local load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | cut -d',' -f1)
    local max_load=${MAX_LOAD:-2.0}
    
    if (( $(echo "$load < $max_load" | bc -l) )); then
        return 0
    else
        return 1
    fi
}

# 检查内存使用
check_memory_usage() {
    local memory_usage=$(free | awk '/Mem:/ {print $3/$2 * 100.0}')
    local max_memory=${MAX_MEMORY:-80}
    
    if (( $(echo "$memory_usage < $max_memory" | bc -l) )); then
        return 0
    else
        return 1
    fi
}

# 检查磁盘空间
check_disk_space() {
    local path=$1
    local min_space=${MIN_DISK_SPACE:-1073741824} # 1GB
    
    local available_space=$(df "$path" | awk 'NR==2 {print $4 * 1024}')
    
    if [ $available_space -gt $min_space ]; then
        return 0
    else
        return 1
    fi
}

# 检查时间窗口
check_time_window() {
    local current_hour=$(date +%H)
    local start_hour=${START_HOUR:-0}
    local end_hour=${END_HOUR:-6}
    
    if [ $current_hour -ge $start_hour ] && [ $current_hour -lt $end_hour ]; then
        return 0
    else
        return 1
    fi
}

# 调度服务操作
schedule_service_operation() {
    local service=$1
    local operation=$2
    
    log_message "Scheduling $operation for $service"
    
    # 检查系统条件
    if ! check_system_load; then
        log_message "System load too high, postponing $operation for $service"
        return 1
    fi
    
    if ! check_memory_usage; then
        log_message "Memory usage too high, postponing $operation for $service"
        return 1
    fi
    
    if ! check_time_window; then
        log_message "Outside allowed time window, postponing $operation for $service"
        return 1
    fi
    
    # 执行操作
    log_message "Executing $operation for $service"
    systemctl $operation $service
    
    if [ $? -eq 0 ]; then
        log_message "✓ $operation completed for $service"
        return 0
    else
        log_message "✗ $operation failed for $service"
        return 1
    fi
}

# 主调度循环
main_scheduler() {
    log_message "Service Scheduler started"
    
    while true; do
        # 从配置文件读取服务操作
        while IFS='|' read -r service operation; do
            if [ -n "$service" ] && [[ ! $service =~ ^# ]]; then
                schedule_service_operation "$service" "$operation"
            fi
        done < "$CONFIG_FILE"
        
        # 等待下次检查
        sleep $SCHEDULER_INTERVAL
    done
}

# 单次执行模式
single_run() {
    while IFS='|' read -r service operation; do
        if [ -n "$service" ] && [[ ! $service =~ ^# ]]; then
            schedule_service_operation "$service" "$operation"
        fi
    done < "$CONFIG_FILE"
}

# 记录日志
log_message() {
    local message=$1
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] $message" >> $LOG_FILE
}

# 主函数
main() {
    case "$1" in
        start)
            main_scheduler
            ;;
        run)
            single_run
            ;;
        *)
            echo "Usage: $0 {start|run}"
            exit 1
            ;;
    esac
}

main "$@"

服务健康检查系统#

#!/bin/bash
# 服务健康检查系统

CONFIG_FILE="/etc/health_check/config.conf"
LOG_FILE="/var/log/health_check/health.log"
HEALTH_DB="/var/lib/health_check/db"

mkdir -p $(dirname $LOG_FILE) $(dirname $HEALTH_DB)

# 加载配置
source $CONFIG_FILE

# 执行健康检查
perform_health_check() {
    local service=$1
    local check_type=$2
    
    case "$check_type" in
        "systemd")
            systemctl is-active $service > /dev/null 2>&1
            return $?
            ;;
        "http")
            local url=$3
            curl -f -s -o /dev/null "$url" > /dev/null 2>&1
            return $?
            ;;
        "tcp")
            local host=$3
            local port=$4
            nc -z -w 2 $host $port > /dev/null 2>&1
            return $?
            ;;
        "custom")
            local script=$3
            bash $script > /dev/null 2>&1
            return $?
            ;;
        *)
            return 1
            ;;
    esac
}

# 记录健康检查结果
record_health_result() {
    local service=$1
    local status=$2
    local timestamp=$(date +%s)
    
    echo "$timestamp,$status" >> "$HEALTH_DB/${service}.csv"
}

# 分析健康趋势
analyze_health_trend() {
    local service=$1
    local db_file="$HEALTH_DB/${service}.csv"
    
    if [ ! -f "$db_file" ]; then
        echo "No health data available for $service"
        return 1
    fi
    
    local total_checks=$(wc -l < $db_file)
    local failed_checks=$(awk -F, '$2 == "failed" {count++} END {print count+0}' $db_file)
    local success_rate=$(echo "scale=2; ($total_checks - $failed_checks) * 100 / $total_checks" | bc)
    
    echo "Health Trend for $service:"
    echo "Total checks: $total_checks"
    echo "Failed checks: $failed_checks"
    echo "Success rate: ${success_rate}%"
}

# 生成健康报告
generate_health_report() {
    local report_file="$LOG_DIR/health_report_$(date +%Y%m%d).txt"
    
    echo "Health Check Report - $(date +%Y-%m-%d)" > $report_file
    echo "=========================" >> $report_file
    echo "" >> $report_file
    
    for service in "${MONITORED_SERVICES[@]}"; do
        echo "=== $service ===" >> $report_file
        analyze_health_trend $service >> $report_file
        echo "" >> $report_file
    done
    
    log_message "Health report generated: $report_file"
}

# 主健康检查循环
main_health_check() {
    log_message "Health Check System started"
    
    while true; do
        for service in "${MONITORED_SERVICES[@]}"; do
            local check_type=$(eval echo \${${service}_check_type})
            local check_params=$(eval echo \${${service}_check_params})
            
            if perform_health_check $service $check_type $check_params; then
                record_health_result $service "success"
                log_message "Health check passed for $service"
            else
                record_health_result $service "failed"
                log_message "Health check failed for $service"
                
                if [ "$AUTO_RESTART" = "true" ]; then
                    log_message "Attempting to restart $service..."
                    systemctl restart $service
                fi
            fi
        done
        
        sleep $CHECK_INTERVAL
    done
}

# 记录日志
log_message() {
    local message=$1
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    echo "[$timestamp] $message" >> $LOG_FILE
}

# 主函数
main() {
    case "$1" in
        start)
            main_health_check
            ;;
        report)
            generate_health_report
            ;;
        analyze)
            analyze_health_trend "$2"
            ;;
        *)
            echo "Usage: $0 {start|report|analyze}"
            exit 1
            ;;
    esac
}

main "$@"

最佳实践#

  1. 使用 enable/disable 管理开机自启动:合理设置服务的开机自启动状态
  2. 定期检查服务状态:使用 systemctl status 定期检查关键服务状态
  3. 使用 journalctl 查看日志:结合 journalctl 查看服务日志
  4. 理解服务依赖关系:了解服务之间的依赖关系,避免启动顺序问题
  5. 备份服务配置:在修改服务配置前备份原始配置
  6. 使用 daemon-reload:修改服务配置后执行 daemon-reload 重新加载
  7. 监控服务性能:定期监控服务的 CPU、内存使用情况
  8. 设置合理的重启策略:在服务配置中设置合理的重启策略

注意事项#

  • systemctl 需要 root 权限来管理服务
  • 修改系统级服务配置时要格外小心
  • 某些服务可能不支持 reload 操作
  • 服务重启可能导致短暂的服务中断
  • 在生产环境中操作前先在测试环境验证
  • 注意服务的依赖关系,避免启动失败
  • 不同 Linux 发行版的 systemd 配置可能有所不同
  • 对于关键服务,建议配置自动重启策略