跳转至

01 - Linux系统深入

目标: 深入理解Linux系统,掌握系统调优和Shell编程

时间: 2-3周

核心原则: Linux是后端开发的基础,必须熟练掌握


🎯 为什么要深入Linux?

实际应用场景

Text Only
1. 服务器运维
   - 系统监控和故障排查
   - 性能调优
   - 安全管理

2. 开发环境
   - 容器技术基于Linux
   - 大多数服务器运行Linux
   - 开发工具链在Linux上更完善

3. 性能优化
   - 理解系统调用
   - IO优化
   - 网络优化

📚 核心内容

1. Linux文件系统

文件系统层次

Text Only
/
├── /bin          # 基本命令(ls, cat, mkdir等)
├── /boot         # 启动文件
├── /dev          # 设备文件
├── /etc          # 配置文件
├── /home         # 用户目录
├── /lib          # 共享库
├── /mnt          # 挂载点
├── /opt          # 可选软件包
├── /proc         # 进程信息(虚拟文件系统)
├── /root         # root用户目录
├── /tmp          # 临时文件
├── /usr          # 用户程序
├── /var          # 可变数据(日志等)
└── /sys          # 系统信息

文件权限

Bash
# 权限表示
# -rwxr-xr-x 1 user group 1234 Jan 1 12:00 file.txt
#  |  |  |
#  |  |  └── 其他用户权限
#  |  └───── 组用户权限
#  └──────── 所有者权限

# 权限数字表示
# r=4, w=2, x=1
# rwx = 7, rw- = 6, r-x = 5

# 修改权限
chmod 755 file.txt      # -rwxr-xr-x
chmod u+x script.sh     # 给所有者添加执行权限
chmod go-w file.txt     # 移除组和其他用户的写权限

# 修改所有者
chown user:group file.txt

# 特殊权限
chmod u+s binary        # SUID - 以所有者权限运行
chmod g+s directory     # SGID - 新文件继承组
chmod +t directory      # Sticky - 只能删除自己的文件

2. 进程管理

Bash
# 查看进程
ps aux                  # 所有进程详细信息
ps -ef | grep python    # 查找Python进程
top                     # 实时进程监控
htop                    # 增强版top

# 进程控制
kill PID                # 终止进程
kill -9 PID             # 强制终止
kill -15 PID            # 优雅终止(默认)
pkill process_name      # 按名称终止

# 后台运行
command &               # 后台运行
nohup command &         # 脱离终端运行
ctrl+z                  # 暂停进程
bg                      # 后台继续运行
fg                      # 前台继续运行

# 进程优先级
nice -n 10 command      # 以较低优先级运行
renice -n 5 -p PID      # 修改运行中进程的优先级

3. 网络管理

Bash
# 查看网络配置
ip addr                 # 查看IP地址
ip link                 # 查看网络接口
ip route                # 查看路由表
netstat -tuln           # 查看监听端口
ss -tuln                # 新版netstat

# 网络诊断
ping host               # 测试连通性
traceroute host         # 路由跟踪
mtr host                # 网络质量检测
dig domain              # DNS查询
nslookup domain         # DNS查询

# 抓包分析
tcpdump -i eth0         # 抓取eth0网卡数据
tcpdump -i eth0 port 80 # 抓取80端口数据
tcpdump -w capture.pcap # 保存到文件

# 防火墙
iptables -L             # 查看规则
iptables -A INPUT -p tcp --dport 80 -j ACCEPT  # 允许80端口
ufw status              # Ubuntu防火墙状态
ufw allow 80/tcp        # 允许80端口

4. Shell编程

基础脚本

Bash
#!/bin/bash

# 变量
NAME="World"
echo "Hello, $NAME"

# 特殊变量
$0      # 脚本名
$1-$9   # 位置参数
$#      # 参数个数
$@      # 所有参数
$?      # 上一个命令的退出状态
$$      # 当前进程ID

# 条件判断
if [ "$1" = "start" ]; then
    echo "Starting..."
elif [ "$1" = "stop" ]; then
    echo "Stopping..."
else
    echo "Usage: $0 {start|stop}"
fi

# 循环
for i in 1 2 3 4 5; do
    echo $i
done

for file in *.txt; do
    echo "Processing: $file"
done

while [ $count -lt 10 ]; do
    echo $count
    ((count++))
done

# 函数
function greet() {
    local name=$1  # local变量
    echo "Hello, $name"
}

greet "Alice"

# 数组
fruits=("apple" "banana" "cherry")
echo ${fruits[0]}       # 第一个元素
echo ${fruits[@]}       # 所有元素
echo ${#fruits[@]}      # 数组长度

高级脚本

Bash
#!/bin/bash

# 日志函数
log() {
    local level=$1
    shift
    local message="$@"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message"
}

log INFO "Starting deployment..."
log ERROR "Failed to connect to database"

# 错误处理
set -e                  # 遇到错误立即退出
set -u                  # 使用未定义变量时报错
set -o pipefail         # 管道中任何一个命令失败都报错

# 清理函数
cleanup() {
    echo "Cleaning up..."
    rm -f /tmp/temp_*.txt
}
trap cleanup EXIT       # 退出时执行清理

# 并行处理
process_file() {
    local file=$1
    # 处理逻辑
    echo "Processing $file"
}

export -f process_file

# 使用xargs并行处理
find . -name "*.log" -print0 | xargs -0 -P 4 -I {} bash -c 'process_file "$@"' _ {}

# 或者使用GNU parallel
# find . -name "*.log" | parallel process_file

5. 性能监控

Bash
# CPU监控
top -bn1 | grep "Cpu(s)"
mpstat -P ALL 1         # 每个CPU核心统计

# 内存监控
free -h                 # 内存使用情况
vmstat 1 10             # 虚拟内存统计

# 磁盘IO
iostat -x 1             # IO统计
iotop                   # IO实时监控

# 网络监控
iftop                   # 网络流量监控
nethogs                 # 按进程显示网络流量

# 综合监控
sar -u 1 10             # CPU使用历史
sar -r 1 10             # 内存使用历史

6. 系统调优

Bash
# 文件描述符限制
ulimit -n               # 查看当前限制
ulimit -n 65535         # 临时修改
# /etc/security/limits.conf 永久修改
# * soft nofile 65535
# * hard nofile 65535

# 内核参数调优
# /etc/sysctl.conf

# 网络优化
net.core.somaxconn = 65535          # TCP连接队列
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535

# 内存优化
vm.swappiness = 10                  # 减少swap使用
vm.dirty_ratio = 40

# 应用配置
sysctl -p               # 重新加载配置

# 磁盘调度算法
cat /sys/block/sda/queue/scheduler
echo noop > /sys/block/sda/queue/scheduler  # SSD推荐

🛠️ 实践练习

练习1: 系统监控脚本

Bash
#!/bin/bash

# system_monitor.sh - 系统监控脚本

LOG_FILE="/var/log/system_monitor.log"
ALERT_CPU=80
ALERT_MEM=80
ALERT_DISK=90

log_message() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a $LOG_FILE
}

check_cpu() {
    local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)  # awk文本处理:按列提取和格式化数据
    cpu_usage=${cpu_usage%.*}  # 取整数部分

    if [ "$cpu_usage" -gt "$ALERT_CPU" ]; then
        log_message "WARNING" "High CPU usage: ${cpu_usage}%"
    fi
}

check_memory() {
    local mem_info=$(free | grep Mem)  # grep文本搜索:按模式匹配行
    local total=$(echo $mem_info | awk '{print $2}')
    local used=$(echo $mem_info | awk '{print $3}')
    local usage=$((used * 100 / total))

    if [ "$usage" -gt "$ALERT_MEM" ]; then
        log_message "WARNING" "High Memory usage: ${usage}%"
    fi
}

check_disk() {
    local disk_usage=$(df / | tail -1 | awk '{print $5}' | cut -d'%' -f1)

    if [ "$disk_usage" -gt "$ALERT_DISK" ]; then
        log_message "WARNING" "High Disk usage: ${disk_usage}%"
    fi
}

check_services() {
    local services=("nginx" "mysql" "redis")

    for service in "${services[@]}"; do  # Shell for循环
        if ! systemctl is-active --quiet $service; then
            log_message "ERROR" "Service $service is not running"
        fi
    done
}

# 主循环
while true; do
    check_cpu
    check_memory
    check_disk
    check_services

    sleep 60
done

练习2: 自动化部署脚本

Bash
#!/bin/bash

# deploy.sh - 自动化部署脚本

set -e

APP_NAME="myapp"
DEPLOY_DIR="/opt/$APP_NAME"
BACKUP_DIR="/opt/backups"
LOG_FILE="/var/log/deploy.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE  # $()命令替换:执行命令并获取输出
}

error_exit() {
    log "ERROR: $1"
    exit 1
}

# 备份当前版本
backup() {
    log "Creating backup..."
    if [ -d "$DEPLOY_DIR" ]; then  # 条件测试:-f文件存在 -d目录存在 -z空字符串
        local backup_name="${APP_NAME}_$(date +%Y%m%d_%H%M%S)"
        tar -czf "$BACKUP_DIR/$backup_name.tar.gz" -C "$DEPLOY_DIR" .
        log "Backup created: $backup_name"
    fi
}

# 部署新版本
deploy() {
    log "Starting deployment..."

    # 下载/复制新版本
    local version=$1
    local source="/tmp/${APP_NAME}-${version}.tar.gz"

    if [ ! -f "$source" ]; then
        error_exit "Source file not found: $source"
    fi

    # 停止服务
    log "Stopping service..."
    systemctl stop $APP_NAME || true  # &&前一个成功才执行后一个;||前一个失败才执行

    # 部署代码
    log "Deploying code..."
    rm -rf "$DEPLOY_DIR"
    mkdir -p "$DEPLOY_DIR"
    tar -xzf "$source" -C "$DEPLOY_DIR"

    # 安装依赖
    log "Installing dependencies..."
    cd "$DEPLOY_DIR"
    pip install -r requirements.txt

    # 数据库迁移
    log "Running database migrations..."
    python manage.py migrate

    # 收集静态文件
    log "Collecting static files..."
    python manage.py collectstatic --noinput

    # 启动服务
    log "Starting service..."
    systemctl start $APP_NAME

    # 健康检查
    log "Health check..."
    sleep 5
    if ! curl -f http://localhost:8000/health > /dev/null 2>&1; then
        error_exit "Health check failed"
    fi

    log "Deployment completed successfully"
}

# 回滚
rollback() {
    log "Starting rollback..."

    # 找到最新的备份
    local latest_backup=$(ls -t $BACKUP_DIR/${APP_NAME}_*.tar.gz 2>/dev/null | head -1)  # |管道:将前一命令的输出作为后一命令的输入

    if [ -z "$latest_backup" ]; then
        error_exit "No backup found"
    fi

    log "Restoring from: $latest_backup"

    systemctl stop $APP_NAME || true
    rm -rf "$DEPLOY_DIR"
    mkdir -p "$DEPLOY_DIR"
    tar -xzf "$latest_backup" -C "$DEPLOY_DIR"
    systemctl start $APP_NAME

    log "Rollback completed"
}

# 主逻辑
case "$1" in
    deploy)
        backup
        deploy "$2"
        ;;
    rollback)
        rollback
        ;;
    *)
        echo "Usage: $0 {deploy <version>|rollback}"
        exit 1
        ;;
esac

✅ 学习检查点

  • 熟练使用Linux常用命令
  • 能编写Shell脚本自动化任务
  • 能进行系统性能监控和调优
  • 理解Linux权限和安全模型
  • 能排查常见的系统问题

📚 推荐资源

书籍

  • 《鸟哥的Linux私房菜》
  • 《Linux命令行与Shell脚本编程大全》
  • 《深入理解Linux内核》

在线资源

  • Linux Foundation课程
  • Bandit游戏(命令行学习)
  • Explainshell.com

记住:Linux是后端开发的基础,掌握它才能游刃有余! 🐧