作为一名 Linux SRE,我们每天面对的是成百上千台服务器、复杂的微服务架构以及瞬息万变的业务流量。性能调优和故障排查是 SRE 最核心的两项能力,它们不仅关乎系统的稳定性,更直接影响用户的体验和公司的营收。本文将结合笔者在实际生产环境中的经验,从性能指标、工具链、内核参数到典型案例,系统性地梳理一套 Linux 高并发场景下的调优与排查方法论,希望能为同行提供可落地的参考。
调优之前,必须先建立性能基准(Baseline)。没有基准,就无法判断什么是“异常”。SRE 需要关注的四大资源维度:
资源 | 关键指标 | 健康阈值(参考) |
|---|---|---|
CPU | 利用率(%user, %sys, %iowait, %steal) | 长期 > 70% 需关注,> 90% 告警 |
内存 | 可用内存、Swap 使用率、缺页中断 | Swap 使用率 > 0 需警惕 |
磁盘 IO | 吞吐量(MB/s)、IOPS、延迟(await) | 延迟 > 10ms 可能成为瓶颈 |
网络 | 带宽、丢包率、重传率、连接数 | 重传率 > 1% 表示网络不稳定 |
SRE 黄金法则:永远用 百分位数(P50/P95/P99) 来衡量延迟,而非平均值。例如,接口响应时间 P99 > 200ms 即可视为 SLI 违约。
Linux 生态提供了丰富的性能诊断工具,按层级划分:
top / htop:实时查看 CPU、内存、负载。vmstat 1:展示进程、内存、分页、块 IO、中断、上下文切换。重点关注 r(运行队列)、b(阻塞进程)、si/so(交换)、cs(上下文切换)。iostat -x 1:磁盘 IO 详情,%util 表示磁盘忙闲度,await 表示平均服务时间。sar -n DEV 1:网络接口统计,rxpck/s、txpck/s、rxkB/s、txkB/s。pidstat:按进程输出 CPU、内存、IO 统计。例如 pidstat -u 1 查看 CPU 使用率。strace:追踪进程的系统调用,常用于定位“慢”请求。perf:强大的性能采样工具,可分析 CPU 热点、缓存命中率、分支预测等。bpftrace:编写一行脚本即可追踪内核/用户态事件。例如:
bash
bpftrace -e 'kprobe:do_nanosleep { printf("%s slept\n", comm); }'
bcc 工具集(如 funccount、trace、opensnoop、biolatency)大幅降低了动态追踪的门槛。Linux 内核提供了数百个可调参数(/proc/sys/ 或 sysctl),但盲目修改可能适得其反。以下是在高并发 Web 服务中最常用且安全的参数优化(以 sysctl.conf 为例):
# 网络栈优化 – 应对高连接数
net.ipv4.tcp_tw_reuse = 1 # 允许重用 TIME_WAIT 端口(仅客户端)
net.ipv4.tcp_tw_recycle = 0 # 已废弃,且有 NAT 问题,不建议开启
net.ipv4.tcp_fin_timeout = 30 # 缩短 FIN_WAIT2 超时
net.ipv4.tcp_keepalive_time = 600 # 减少无效连接占用资源
net.ipv4.tcp_max_syn_backlog = 8192 # SYN 队列大小
net.core.somaxconn = 65535 # listen 队列大小(需配合应用层)
# 内存管理
vm.swappiness = 10 # 降低使用 Swap 的倾向(SSD 可更激进)
vm.vfs_cache_pressure = 50 # 保留更多 dentry/inode 缓存
# 文件系统
fs.file-max = 1000000 # 系统级文件句柄上限
fs.nr_open = 1000000 # 进程级文件句柄上限注意:修改后执行
sysctl -p生效。建议先在测试环境验证,并配合sar观察变化。
现象:业务高峰时,接口 P99 延迟从 50ms 飙升到 500ms,top 显示 %sys 高达 30%,%user 仅 20%。
排查步骤:
vmstat 1 观察:
text
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 8 0 0 123456 12345 234567 0 0 0 0 50000 80000 20 30 50 0 0
cs(上下文切换)高达 80000/s,远超正常值(< 20000)。in(中断)也达到 50000/s。pidstat -w 1 查看各进程的上下文切换:
text
PID cswch/s nvcswch/s Command 1234 2000 15000 nginx 5678 3000 12000 java
nvcswch(非自愿上下文切换)高,说明线程被抢占,可能是锁竞争或 CPU 不足。perf record -a -g -- sleep 10 采集火焰图数据,发现 __spin_lock 占比极高,定位到某个共享哈希表锁。解决方案:
worker_processes 与 CPU 核心数匹配,避免过度调度。kernel.sched_migration_cost_ns 调大,减少负载均衡导致的迁移。现象:Java 应用运行一周后内存占用持续增长,最终被 OOM Killer 杀掉,/var/log/messages 出现 Out of memory: Kill process。
排查步骤:
/proc/meminfo:
text
MemTotal: 16384000 kB MemFree: 512000 kB Cached: 2000000 kB Shmem: 10000 kB Slab: 800000 kB SReclaimable: 300000 kB SUnreclaim: 500000 kB
SUnreclaim(不可回收 Slab)较高,但更关注进程 RSS。pmap -x <PID> 查看进程内存映射,发现大量匿名内存段([anon])不断增长。valgrind --leak-check=full(开发环境)或 jmap(Java)导出堆 dump,分析发现某个缓存对象未设置过期策略。解决方案:
-Xmx 和 -XX:MaxDirectMemorySize,限制最大堆外内存。现象:MySQL 慢查询增多,iostat 显示 await 达到 50ms(正常 < 10ms),%util 接近 100%。
排查步骤:
iostat -x 1 输出:
text
Device rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await %util sda 0 0 200 300 10000 15000 32 15.5 50.2 99.8
avgqu-sz(平均队列长度)高达 15,说明 IO 密集且排队严重。blktrace + btt 分析 IO 时间线,发现大量随机读(r/s 高但 rkB/s 不高),说明查询未命中缓存。fio 测试磁盘基准性能,确认峰值 IOPS 为 5000,而实际请求已达 6000。解决方案:
none(NVMe)或 mq-deadline(SATA),减少调度开销。调优和排障不能仅靠手工,必须建立可观测性体系。笔者推荐的组合:
sloth 或 prometheus-slo 生成 SLI 报表。wrk、JMeter 或 locust 模拟高并发,并结合 Prometheus 观察极限 QPS,提前扩容。Chaos Mesh 或 Gremlin。Linux SRE 的性能调优与故障排查,本质上是一个假设驱动的推理过程:观察现象 → 提出假设 → 使用工具验证 → 实施修复 → 验证效果。本文给出的工具和案例只是冰山一角,真正的功力在于对操作系统原理的深刻理解以及对业务逻辑的把握。
最后,请记住三条 SRE 心法:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。