跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    性能调优是一个系统化的过程:先定位瓶颈,再有针对性地优化。盲目调参往往适得其反。本文介绍常见的调优手段和适用场景,帮助你从内核参数到应用层逐步提升服务器性能。

    在调优之前,必须先记录当前的性能基线,否则无法衡量优化效果。

    Terminal window
    # 记录系统基本信息
    uname -a
    cat /etc/os-release
    lscpu
    free -h
    lsblk
    # 安装性能分析工具
    sudo dnf install sysstat perf iotop htop -y
    # 启用 sysstat 数据收集
    sudo systemctl enable --now sysstat
    # 查看历史性能数据
    sar -u 1 5 # CPU 使用率
    sar -r 1 5 # 内存使用率
    sar -d 1 5 # 磁盘 I/O
    sar -n DEV 1 5 # 网络吞吐
    Terminal window
    # 快速判断瓶颈类型
    # CPU 瓶颈:load average 持续高于 CPU 核心数
    uptime
    # 内存瓶颈:可用内存低且 swap 活跃
    free -h
    vmstat 1 5
    # I/O 瓶颈:iowait 高
    iostat -xz 1 5
    # 网络瓶颈:丢包或带宽饱和
    ss -s
    sar -n DEV 1 5

    sysctl 用于在运行时修改内核参数。

    Terminal window
    # 查看所有参数
    sysctl -a
    # 查看特定参数
    sysctl net.core.somaxconn
    sysctl vm.swappiness
    # 临时修改(重启后失效)
    sudo sysctl -w net.core.somaxconn=65535
    # 永久修改
    sudo tee /etc/sysctl.d/99-tuning.conf > /dev/null <<'EOF'
    # 自定义内核参数调优
    EOF
    # 应用配置
    sudo sysctl --system
    Terminal window
    sudo tee /etc/sysctl.d/99-network.conf > /dev/null <<'EOF'
    # ==============================
    # 网络性能调优
    # ==============================
    # --- TCP 缓冲区 ---
    # 默认和最大的 TCP 发送/接收缓冲区(字节)
    # 格式:min default max
    net.core.rmem_default = 262144
    net.core.rmem_max = 16777216
    net.core.wmem_default = 262144
    net.core.wmem_max = 16777216
    net.ipv4.tcp_rmem = 4096 87380 16777216
    net.ipv4.tcp_wmem = 4096 65536 16777216
    # --- 连接队列 ---
    # 监听队列最大长度(影响高并发下的连接建立)
    net.core.somaxconn = 65535
    # 半连接队列大小
    net.ipv4.tcp_max_syn_backlog = 65535
    # 网卡接收队列长度
    net.core.netdev_max_backlog = 65535
    # --- TCP 连接优化 ---
    # 启用 TCP Fast Open(减少握手延迟)
    net.ipv4.tcp_fastopen = 3
    # TIME_WAIT 相关
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_fin_timeout = 15
    net.ipv4.tcp_max_tw_buckets = 262144
    # Keepalive 参数
    net.ipv4.tcp_keepalive_time = 600
    net.ipv4.tcp_keepalive_intvl = 30
    net.ipv4.tcp_keepalive_probes = 5
    # --- 拥塞控制 ---
    # 使用 BBR 拥塞控制算法(推荐)
    net.core.default_qdisc = fq
    net.ipv4.tcp_congestion_control = bbr
    # --- 本地端口范围 ---
    net.ipv4.ip_local_port_range = 1024 65535
    # --- 其他 ---
    # 允许更多的 orphan 套接字
    net.ipv4.tcp_max_orphans = 262144
    # SYN Flood 防护
    net.ipv4.tcp_syncookies = 1
    EOF
    sudo sysctl --system

    验证 BBR 是否生效:

    Terminal window
    sysctl net.ipv4.tcp_congestion_control
    # 输出应为:net.ipv4.tcp_congestion_control = bbr
    lsmod | grep bbr
    Terminal window
    sudo tee /etc/sysctl.d/99-memory.conf > /dev/null <<'EOF'
    # ==============================
    # 内存调优
    # ==============================
    # Swappiness:控制内核将内存页交换到 swap 的倾向
    # 0 = 尽量不使用 swap(适合内存充足的数据库服务器)
    # 10 = 低交换倾向(推荐大多数服务器场景)
    # 60 = 默认值
    vm.swappiness = 10
    # 脏页刷新策略
    # 脏页超过内存百分比时后台开始刷新
    vm.dirty_background_ratio = 5
    # 脏页超过此比例时前台进程必须等待刷新
    vm.dirty_ratio = 15
    # 脏页存活时间(厘秒,500 = 5秒)
    vm.dirty_expire_centisecs = 500
    # 刷新线程唤醒间隔(厘秒)
    vm.dirty_writeback_centisecs = 100
    # VFS 缓存压力(默认 100)
    # 低于 100 = 倾向保留 dentry/inode 缓存
    # 高于 100 = 倾向回收缓存
    vm.vfs_cache_pressure = 50
    # 内存不足时的行为
    # 0 = 启发式 OOM(默认)
    # 1 = 允许过量分配
    # 2 = 不允许过量分配
    vm.overcommit_memory = 0
    EOF
    sudo sysctl --system

    大页可以减少 TLB 缺失,提升内存密集型应用(如数据库)的性能。

    Terminal window
    # 查看当前大页配置
    grep -i huge /proc/meminfo
    # 计算需要的大页数量
    # 例如为数据库分配 4GB:4096MB / 2MB(默认大页大小)= 2048 页
    echo "需要的大页数: $((4096 / 2))"
    # 设置大页数量
    sudo sysctl -w vm.nr_hugepages=2048
    # 永久配置
    echo 'vm.nr_hugepages = 2048' | sudo tee -a /etc/sysctl.d/99-memory.conf
    sudo sysctl --system
    # 验证
    grep -i huge /proc/meminfo
    # HugePages_Total: 2048
    # HugePages_Free: 2048
    # Hugepagesize: 2048 kB

    THP 由内核自动管理大页分配。对于大多数服务器应用是有益的,但某些数据库(如 MongoDB、Redis)建议禁用 THP 以避免延迟抖动。

    Terminal window
    # 查看当前状态
    cat /sys/kernel/mm/transparent_hugepage/enabled
    # 临时禁用
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
    # 永久禁用(通过 systemd)
    sudo tee /etc/systemd/system/disable-thp.service > /dev/null <<'EOF'
    [Unit]
    Description=Disable Transparent Huge Pages
    DefaultDependencies=no
    After=sysinit.target local-fs.target
    Before=basic.target
    [Service]
    Type=oneshot
    ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
    ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
    [Install]
    WantedBy=basic.target
    EOF
    sudo systemctl daemon-reload
    sudo systemctl enable disable-thp

    ulimit 控制用户进程可使用的系统资源上限。默认值通常偏保守,高并发场景需要调整。

    Terminal window
    # 查看当前用户的所有限制
    ulimit -a
    # 关键参数:
    # -n 最大打开文件数(open files)
    # -u 最大进程数(max user processes)
    # -l 最大锁定内存(max locked memory)
    Terminal window
    # 修改系统级限制
    sudo tee /etc/security/limits.d/99-tuning.conf > /dev/null <<'EOF'
    # 格式:<domain> <type> <item> <value>
    # 所有用户
    * soft nofile 65535
    * hard nofile 131072
    * soft nproc 65535
    * hard nproc 131072
    # 特定用户(如 nginx)
    nginx soft nofile 131072
    nginx hard nofile 262144
    # root 用户
    root soft nofile 131072
    root hard nofile 262144
    EOF

    对于 systemd 管理的服务,还需要在 service 文件中设置:

    Terminal window
    # 方法一:修改 systemd 默认限制
    sudo mkdir -p /etc/systemd/system.conf.d
    sudo tee /etc/systemd/system.conf.d/limits.conf > /dev/null <<'EOF'
    [Manager]
    DefaultLimitNOFILE=131072
    DefaultLimitNPROC=65535
    EOF
    # 方法二:为特定服务设置(推荐)
    sudo systemctl edit nginx
    # 在编辑器中添加:
    # [Service]
    # LimitNOFILE=131072
    # LimitNPROC=65535
    sudo systemctl daemon-reload
    sudo systemctl restart nginx
    # 验证服务的实际限制
    cat /proc/$(pidof nginx | awk '{print $1}')/limits

    tuned 是 EL 系发行版提供的动态调优守护进程,内置多种预定义的调优方案。

    Terminal window
    sudo dnf install tuned -y
    sudo systemctl enable --now tuned
    # 查看所有可用的调优方案
    tuned-adm list
    # 常用方案:
    # throughput-performance - 高吞吐量优化
    # latency-performance - 低延迟优化
    # network-latency - 网络低延迟
    # network-throughput - 网络高吞吐
    # virtual-guest - 虚拟机客户机
    # virtual-host - 虚拟化宿主机
    # postgresql - PostgreSQL 优化
    # 查看当前方案
    tuned-adm active
    # 切换方案
    sudo tuned-adm profile throughput-performance
    # 获取推荐方案
    tuned-adm recommend
    # 查看方案的具体配置
    tuned-adm profile_info throughput-performance
    Terminal window
    # 基于现有方案创建自定义方案
    sudo mkdir -p /etc/tuned/my-web-server
    sudo tee /etc/tuned/my-web-server/tuned.conf > /dev/null <<'EOF'
    [main]
    summary=Custom tuning for web server
    include=throughput-performance
    [sysctl]
    net.core.somaxconn = 65535
    net.ipv4.tcp_max_syn_backlog = 65535
    net.ipv4.tcp_tw_reuse = 1
    net.core.default_qdisc = fq
    net.ipv4.tcp_congestion_control = bbr
    vm.swappiness = 10
    [vm]
    transparent_hugepages = never
    [disk]
    readahead = 4096
    EOF
    # 应用自定义方案
    sudo tuned-adm profile my-web-server
    sudo tuned-adm active

    I/O 调度器决定了磁盘读写请求的排序和合并策略。

    Terminal window
    # 查看当前 I/O 调度器
    cat /sys/block/sda/queue/scheduler
    # 输出示例:[mq-deadline] kyber bfq none
    # 临时修改
    echo "kyber" | sudo tee /sys/block/sda/queue/scheduler
    # 永久修改(通过 udev 规则)
    sudo tee /etc/udev/rules.d/60-io-scheduler.rules > /dev/null <<'EOF'
    # SSD 使用 none (noop) 或 mq-deadline
    ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
    # HDD 使用 bfq
    ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
    EOF
    调度器适用场景
    none(noop)NVMe SSD、虚拟机(宿主机已做调度)
    mq-deadline通用 SSD,数据库场景(保证截止时间)
    bfqHDD,桌面/交互场景(公平调度)
    kyber高速 SSD,高吞吐场景
    Terminal window
    # 查看当前预读值(单位是 KB,不是 512 字节扇区;2048 = 2 MiB)
    cat /sys/block/sda/queue/read_ahead_kb
    # 顺序读密集的场景可增大预读
    echo 2048 | sudo tee /sys/block/sda/queue/read_ahead_kb
    # 随机读密集的场景(如数据库)减小预读
    echo 128 | sudo tee /sys/block/sda/queue/read_ahead_kb

    将网卡中断绑定到特定 CPU 核心,减少上下文切换:

    Terminal window
    # 查看网卡中断分布
    cat /proc/interrupts | grep eth0
    # 自动设置(使用 irqbalance 服务)
    sudo systemctl enable --now irqbalance
    # 或手动绑定(多队列网卡场景)
    # 查看网卡队列
    ls /sys/class/net/eth0/queues/
    # 安装 tuned 的 network 插件可自动优化
    Terminal window
    # 安装 ethtool
    sudo dnf install ethtool -y
    # 查看网卡信息
    ethtool eth0
    # 查看和修改环形缓冲区大小
    ethtool -g eth0 # 查看
    sudo ethtool -G eth0 rx 4096 tx 4096 # 修改
    # 查看和启用网卡特性
    ethtool -k eth0 # 查看
    sudo ethtool -K eth0 tso on # 启用 TCP 分段卸载
    sudo ethtool -K eth0 gro on # 启用通用接收卸载
    sudo ethtool -K eth0 gso on # 启用通用分段卸载

    高并发代理/NAT 服务器需要增大连接跟踪表:

    Terminal window
    sudo tee /etc/sysctl.d/99-conntrack.conf > /dev/null <<'EOF'
    # 连接跟踪表最大条目数
    net.netfilter.nf_conntrack_max = 1048576
    # 连接跟踪表的哈希桶大小
    # 通常设为 nf_conntrack_max 的 1/4
    net.netfilter.nf_conntrack_buckets = 262144
    # 缩短各状态的超时时间
    net.netfilter.nf_conntrack_tcp_timeout_established = 3600
    net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
    net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
    net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
    EOF
    sudo sysctl --system
    Terminal window
    # 查看 XFS 挂载选项
    mount | grep xfs
    # 优化挂载选项(编辑 /etc/fstab)
    # noatime - 不更新访问时间,减少写入
    # nodiratime - 不更新目录访问时间
    # logbufs=8 - 增加日志缓冲区
    # 示例:
    # /dev/sda1 /data xfs defaults,noatime,nodiratime,logbufs=8 0 0
    # 重新挂载生效(不需要重启)
    sudo mount -o remount,noatime,nodiratime /data
    Terminal window
    # 优化挂载选项
    # noatime - 不更新访问时间
    # commit=60 - 数据提交间隔(秒),增大可提高性能但增加数据丢失风险
    # 示例:
    # /dev/sdb1 /data ext4 defaults,noatime,commit=60 0 2
    sudo mount -o remount,noatime /data
    /usr/local/bin/perf_check.sh
    #!/bin/bash
    # 检查当前系统性能参数配置
    echo "============================================"
    echo " 性能参数检查报告 - $(date)"
    echo "============================================"
    echo ""
    echo "--- CPU ---"
    echo "核心数: $(nproc)"
    echo "当前负载: $(uptime | awk -F'load average:' '{print $2}')"
    echo "调度器: $(tuned-adm active 2>/dev/null || echo '未安装 tuned')"
    echo ""
    echo "--- 内存 ---"
    free -h
    echo "swappiness: $(sysctl -n vm.swappiness)"
    echo "dirty_ratio: $(sysctl -n vm.dirty_ratio)"
    echo "dirty_background_ratio: $(sysctl -n vm.dirty_background_ratio)"
    echo "THP: $(cat /sys/kernel/mm/transparent_hugepage/enabled)"
    echo "HugePages: $(grep HugePages_Total /proc/meminfo)"
    echo ""
    echo "--- 网络 ---"
    echo "somaxconn: $(sysctl -n net.core.somaxconn)"
    echo "tcp_max_syn_backlog: $(sysctl -n net.ipv4.tcp_max_syn_backlog)"
    echo "tcp_congestion: $(sysctl -n net.ipv4.tcp_congestion_control)"
    echo "ip_local_port_range: $(sysctl -n net.ipv4.ip_local_port_range)"
    echo "tcp_tw_reuse: $(sysctl -n net.ipv4.tcp_tw_reuse)"
    echo ""
    echo "--- 文件描述符 ---"
    echo "系统级限制: $(sysctl -n fs.file-max)"
    echo "当前使用量: $(cat /proc/sys/fs/file-nr)"
    echo "ulimit -n (当前用户): $(ulimit -n)"
    echo ""
    echo "--- I/O ---"
    for disk in $(lsblk -dn -o NAME); do
    scheduler=$(cat /sys/block/$disk/queue/scheduler 2>/dev/null)
    readahead=$(cat /sys/block/$disk/queue/read_ahead_kb 2>/dev/null)
    rotational=$(cat /sys/block/$disk/queue/rotational 2>/dev/null)
    type="HDD"
    [ "$rotational" = "0" ] && type="SSD"
    echo "${disk} (${type}): 调度器=${scheduler}, 预读=${readahead}KB"
    done
    echo ""
    echo "--- 连接跟踪 ---"
    if [ -f /proc/sys/net/netfilter/nf_conntrack_max ]; then
    echo "最大连接数: $(sysctl -n net.netfilter.nf_conntrack_max)"
    echo "当前连接数: $(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null || echo N/A)"
    else
    echo "nf_conntrack 模块未加载"
    fi
    Terminal window
    chmod +x /usr/local/bin/perf_check.sh
    1. 先测量后优化 — 使用 sar、vmstat、iostat、perf 定位真正的瓶颈
    2. 每次只改一个参数 — 这样才能确认是哪个改动带来了效果
    3. 记录每次变更 — 方便回退和复盘
    4. 压力测试验证 — 使用 ab、wrk、fio、sysbench 等工具验证优化效果
    5. 关注副作用 — 某些参数的优化可能在其他维度引入问题
    Terminal window
    # 常用压测工具
    sudo dnf install httpd-tools -y # 提供 ab
    # ab -n 10000 -c 100 http://localhost/
    # fio 磁盘性能测试
    sudo dnf install fio -y
    fio --name=randread --ioengine=libaio --rw=randread --bs=4k \
    --size=1G --numjobs=4 --runtime=60 --group_reporting
    # sysbench CPU 测试
    sudo dnf install sysbench -y
    sysbench cpu --threads=$(nproc) run