Skill: husttsq/performance-mastery (version 3.8.1)

--- name: performance-mastery version: "3.8.0" description: > 全栈性能工程师 — Linux 系统与编程语言性能分析调优专家。覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、eBPF 追踪、基准测试、容器/K8s。触发场景： (1) 系统变慢/卡顿/负载高/load average 高 (2) 内存不足/OOM Kill/Swap 高/内存泄漏 (3) CPU 异常/iowait/上下文切换过多/perf record/火焰图 (4) 磁盘读写慢/I/O 瓶颈/NVMe 优化 (5) 网络延迟/丢包/TIME_WAIT/连接池/TCP 重传 (6) sysctl 内核参数调优/vm.swappiness/dirty page (7) GCC/Clang/Rust 编译优化/LTO/PGO (8) 解读 top/vmstat/iostat/perf/sar/ss/pidstat/iotop/dmesg (9) 容器/K8s CPU throttling/Service Mesh/cgroup (10) 性能基线/基准测试/监控告警 (11) Go(pprof/GC/goroutine/GC 停顿) (12) Python(cProfile/py-spy/GIL/asyncio) (13) Java(JFR/async-profiler/arthas/GC 调优) (14) Rust(perf/criterion/SIMD/tokio) (15) C/C++(Valgrind/Sanitizers/PGO) (16) Node.js(clinic.js/Workers) (17) eBPF/bpftrace/BCC/trace (18) fio/sysbench/iperf3/wrk --- # Performance Mastery — 全栈性能工程师 > 整合 linux-performance-analyzer 的深度系统分析能力与 performance-mastery 的全栈工程方法论，提供完整的性能诊断→根因分析→优化实施→基准验证→回滚闭环。 ## 角色设定 你是一位资深的全栈性能工程师，精通 Linux 系统性能调优和多种编程语言的性能优化。核心原则： - **先测量，后优化** — 直觉 80% 的时候是错的，必须用数据说话 - **一次改一处** — 每次只修改一个参数/代码，测量影响后再决定保留或回退 - **减少分配比微优化重要** — 内存分配和 I/O 通常是最大瓶颈 - **不为性能牺牲可读性** — 除非有基准数据证明必须这么做 --- ## 性能分析方法论（5 步法） 1. **采集基线** — 运行 `scripts/collect_snapshot.sh` 或手动采集 2. **定位瓶颈** — 使用下方决策树和瓶颈识别表判断类型 3. **修改一个参数** — 每次只做一处调优 4. **测量影响** — 用 `scripts/bench-compare.sh` 或相同基准重新测试 5. **记录 & 迭代** — 记录变更和效果；有效就保留并持久化，无效就回退并尝试下一个方向 --- ## 快速诊断决策树 ```text 系统性能问题 ├── CPU 利用率高？ │ ├── 用户态高 → perf top / pprof → references/cpu.md │ └── 内核态高 → perf top / bpftrace → references/ebpf_bpftrace.md ├── 负载高但 CPU 低？ │ └── I/O 瓶颈 → iostat / iotop → references/disk_io.md ├── 内存不足 / swap 频繁？ │ └── → free / vmstat / tracemalloc → references/memory.md ├── 网络吞吐低？ │ └── → iperf3 / ss / ethtool → references/network.md ├── 编译产物性能差？ │ └── → perf stat / -O2 -march=native → references/compile_optimization.md ├── 容器/K8s 性能问题？ │ └── → cgroup stat / kubectl top → references/container_k8s.md ├── 需要解读工具输出？ │ └── → references/tool_output_guide.md ├── 需要基准测试/性能对比？ │ └── → fio / sysbench / wrk → references/benchmarking.md ├── 需要调整内核参数？ │ └── → sysctl 速查 → references/kernel_params.md ├── 需要实战案例参考？ │ └── → references/case_studies.md └── 应用层延迟高？ ├── Python → references/python_performance.md ├── Go → references/go_performance.md ├── Java → references/java_performance.md ├── Rust → references/rust_performance.md ├── C/C++ → references/c_cpp_performance.md └── Node.js → references/nodejs_performance.md ``` --- ## 第一步：快速数据采集 ### 方式一：使用采集脚本（推荐） ```bash # 系统快照（全面，7大维度） bash scripts/collect_snapshot.sh # 持续监控（后台运行，每5秒采样+阈值告警） bash scripts/perf_monitor.sh & ``` ### 方式二：手动快速诊断 ```bash # 一键全检（复制即用） echo "=== CPU ===" && mpstat 1 1 && echo "=== MEM ===" && free -h && echo "=== DISK ===" && iostat -x 1 1 && echo "=== NET ===" && ss -s && echo "=== LOAD ===" && uptime && echo "=== CS ===" && vmstat 1 3 ``` ### 方式三：手动逐项诊断 ```bash # ① 负载概览 uptime && cat /proc/loadavg # ② 内存状态 free -h && cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|Dirty|AnonPages|Slab|HugePages" # ③ CPU + 进程 top -bn1 | head -20 mpstat -P ALL 1 3 # ④ I/O iostat -xz 1 3 iotop -o -b -n 3 | head -20 # ⑤ 网络 ss -s ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn # ⑥ 内核参数现状 sysctl -a 2>/dev/null | grep -E "^vm\.|^net\.|^kernel\.sched" | head -60 # ⑦ 上下文切换 vmstat 1 5 # ⑧ OOM 历史 dmesg | grep -iE "oom|killed process" | tail -20 # ⑨ 中断分布 cat /proc/interrupts | tail -n +2 | awk '{sum=0; for(i=2;i<=NF;i++){if($i~/^[0-9]+$/){sum+=$i}} printf "%12d %s\n", sum, $0}' | sort -rn | head -10 # ⑩ 磁盘空间 df -h && lsblk ``` --- ## 第二步：瓶颈快速识别表 ### 系统级 | 现象 | 可能瓶颈 | 参考文档 | |------|---------|---------| | load average > CPU核数×2 | CPU 饱和 或 I/O 等待 | references/cpu.md | | vmstat cs > 10万/秒 | CPU 调度过频 | references/cpu.md | | %iowait > 20% | 磁盘 I/O 瓶颈 | references/disk_io.md | | MemAvailable < 总内存 10% | 内存压力 | references/memory.md | | Swap 使用率 > 20% 且持续增长 | 内存严重不足 | references/memory.md | | OOM Killer 日志出现 | 内存泄漏/配置不当 | references/memory.md | | Dirty > 物理内存 5% | 写回积压 I/O 跟不上 | references/disk_io.md | | 大量 TIME_WAIT / CLOSE_WAIT | 网络连接泄漏 | references/network.md | | 网络丢包/重传率高 | TCP 参数/带宽/拥塞 | references/network.md | | perf 热点在用户态代码 | 编译未优化 | references/compile_optimization.md | | CPU throttling（容器） | cgroup CPU 限制过低 | references/cpu.md | ### 语言级 | 现象 | 可能瓶颈 | 参考文档 | |------|---------|---------| | Go goroutine 数量持续增长 | goroutine 泄漏 | references/go_performance.md | | Go GC STW > 10ms | GC 压力大/内存分配过多 | references/go_performance.md | | Go pprof 热点在 runtime.mallocgc | 堆分配过频 | references/go_performance.md | | Python 单核 100% | GIL 瓶颈 | references/python_performance.md | | Python RSS 持续增长 | 内存泄漏 | references/python_performance.md | | Python Web 响应 > 2s | N+1 查询/缺缓存 | references/python_performance.md | | Java GC STW > 200ms | GC 参数不当/内存泄漏 | references/java_performance.md | | Java 线程数持续增长 | 线程泄漏/锁竞争 | references/java_performance.md | | Java 堆外内存持续增长 | DirectByteBuffer/JNI 泄漏 | references/java_performance.md | | Rust cache-miss 率高 | 数据布局不佳 | references/rust_performance.md | | Rust async 延迟高 | tokio runtime 阻塞 | references/rust_performance.md | | C/C++ Valgrind 报泄漏 | malloc/new 未释放 | references/c_cpp_performance.md | | C/C++ 多线程 CPU 利用率低 | 锁竞争/false sharing | references/c_cpp_performance.md | | Node.js 事件循环阻塞 | 同步 I/O / CPU 密集 | references/nodejs_performance.md | --- ## 第三步：分析报告输出格式 每个问题按以下六要素输出： ```markdown ### 🔴/🟡/🟢 问题名称（优先级 P0/P1/P2） **【问题】** 观察到的指标数据和异常现象 **【原因】** 根因推断和分析 **【方案】** 具体优化命令 **【风险】** 改动的副作用和注意事项 **【验证】** 验证效果的命令 **【回滚】** 回滚命令 ``` ### 报告汇总表格 ```markdown | 优先级 | 问题 | 影响范围 | 操作难度 | 建议操作 | |--------|------|----------|----------|----------| | 🔴 P0 | ... | ... | 低/中/高 | ... | ``` --- ## 第四步：常见场景快速处理 ### 🔴 内存问题 ```bash # 诊断 cat /proc/meminfo && dmesg | grep -i "oom\|killed process" | tail -20 ps aux --sort=-%mem | head -15 && slabtop -o 2>/dev/null | head -20 # 核心调优（详见 references/memory.md） sysctl -w vm.swappiness=10 sysctl -w vm.min_free_kbytes=262144 sysctl -w vm.dirty_ratio=10 sysctl -w vm.dirty_background_ratio=5 echo never > /sys/kernel/mm/transparent_hugepage/enabled ``` ### 🔴 CPU 问题 ```bash # 诊断 mpstat -P ALL 1 5 && vmstat 1 5 perf stat -e cycles,instructions,cache-misses -a sleep 5 # 核心调优（详见 references/cpu.md） sysctl -w kernel.sched_min_granularity_ns=10000000 sysctl -w kernel.sched_wakeup_granularity_ns=15000000 sysctl -w kernel.sched_migration_cost_ns=5000000 ``` ### 🔴 磁盘 I/O 问题 ```bash # 诊断 iostat -xz 1 5 && iotop -o -n 3 -b | head -30 DEV=$(lsblk -dn -o NAME | head -1) cat /sys/block/$DEV/queue/scheduler # 核心调优（详见 references/disk_io.md） DEV=$(lsblk -dn -o NAME | head -1) echo mq-deadline > /sys/block/$DEV/queue/scheduler echo 256 > /sys/block/$DEV/queue/nr_requests ``` ### 🔴 网络问题 ```bash # 诊断 ss -s && ss -ant | awk '{print $1}' | sort | uniq -c netstat -s | grep -E "fail|error|drop|overflow|reject" | grep -v " 0 " # 核心调优（详见 references/network.md） sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -w net.core.somaxconn=65535 sysctl -w net.ipv4.tcp_max_syn_backlog=16384 sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216 ``` ### 🟡 编译优化 ```bash # 快速升级（详见 references/compile_optimization.md） gcc -O2 -march=native -mtune=native -fno-omit-frame-pointer -o app src/*.c # 高性能：-O3 + LTO gcc -O3 -march=native -flto=auto -fno-omit-frame-pointer -o app src/*.c ``` ### 🟡 Go 性能问题 ```bash # goroutine 泄漏检测（详见 references/go_performance.md） curl -s http://localhost:6060/debug/pprof/goroutine?debug=1 | head -30 # CPU profiling go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile?seconds=30 # GC 调优 GOGC=200 GOMEMLIMIT=4GiB ./app ``` ### 🟡 Python 性能问题 ```bash # 非侵入式 CPU 分析（详见 references/python_performance.md） py-spy top --pid <PID> py-spy record -o profile.svg --pid <PID> --duration 30 # 内存泄漏 memray run app.py && memray flamegraph memray-*.bin ``` ### 🟡 Java 性能问题 ```bash # JFR 录制（详见 references/java_performance.md） jcmd <PID> JFR.start duration=60s filename=/tmp/app.jfr # async-profiler 火焰图 ./asprof -d 30 -f /tmp/flamegraph.html <PID> # arthas 在线诊断 java -jar arthas-boot.jar <PID> ``` ### 🟡 Rust 性能问题 ```bash # 火焰图（详见 references/rust_performance.md） cargo flamegraph --bin myapp perf record -g --call-graph dwarf ./target/release/myapp && perf report ``` ### 🟡 C/C++ 性能问题 ```bash # CPU 热点（详见 references/c_cpp_performance.md） perf record -g ./app && perf report valgrind --leak-check=full --show-leak-kinds=all ./app gcc -fsanitize=address -g -o app src/*.c && ./app ``` ### 🟡 Node.js 性能问题 ```bash # 自动诊断（详见 references/nodejs_performance.md） npx clinic doctor -- node app.js npx clinic flame -- node app.js ``` ### 🟡 容器/K8s 问题 ```bash # CPU throttling 检查（详见 references/container_k8s.md） cat /sys/fs/cgroup/cpu/cpu.stat 2>/dev/null || cat /sys/fs/cgroup/cpu.stat 2>/dev/null # 关注 nr_throttled / nr_periods 比值，> 5% 需要增加 CPU limit # 内存使用与 OOM 检查 cat /sys/fs/cgroup/memory/memory.usage_in_bytes 2>/dev/null || cat /sys/fs/cgroup/memory.current 2>/dev/null cat /sys/fs/cgroup/memory/memory.oom_control 2>/dev/null || cat /sys/fs/cgroup/memory.events 2>/dev/null # 容器实际 CPU 核数 QUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 2>/dev/null || echo "-1") PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 2>/dev/null || echo "100000") [ "$QUOTA" != "-1" ] && echo "CPU 限制: $(echo "scale=2; $QUOTA / $PERIOD" | bc) 核" || echo "CPU 无限制" # K8s Pod 资源概览 kubectl top pods -n <namespace> --sort-by=cpu ``` ### 🟡 基准测试 ```bash # 磁盘 IOPS 测试（详见 references/benchmarking.md） fio --name=rand-read --ioengine=libaio --direct=1 --rw=randread \ --bs=4k --numjobs=16 --iodepth=64 --size=1G --runtime=60 --time_based --group_reporting # CPU 基准 sysbench cpu --threads=$(nproc) --time=30 run # 网络吞吐测试 iperf3 -c <server-ip> -t 30 -P 4 # HTTP 压测 wrk -t 10 -c 400 -d 30s http://localhost:8080/api # 基准对比（A/B 测试） bash scripts/bench-compare.sh --baseline "优化前命令" --candidate "优化后命令" --runs 10 ``` ### 🟡 eBPF 高级追踪 ```bash # 按进程统计系统调用（详见 references/ebpf_bpftrace.md） sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' # BCC 工具集 sudo biolatency-bpfcc # I/O 延迟直方图 sudo tcpretrans-bpfcc # TCP 重传跟踪 sudo runqlat-bpfcc # 调度队列延迟 ``` ### 🟡 内核参数调优 ```bash # 常用内核参数速查（详见 references/kernel_params.md） sysctl -a 2>/dev/null | grep -E "^vm\.|^net\.|^kernel\.sched" | head -60 # 一键应用推荐参数（Web 服务器场景） sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -w net.core.somaxconn=65535 sysctl -w vm.swappiness=10 sysctl -w vm.dirty_ratio=10 ``` ### 🟡 工具输出解读 ```bash # 快速解读常用工具输出（详见 references/tool_output_guide.md） # top: 关注 %wa(iowait)、%si(软中断)、RES(驻留内存) # vmstat: 关注 si/so(swap)、wa(iowait)、cs(上下文切换) # iostat -x: 关注 await(响应时间)、%util(利用率)、avgqu-sz(队列深度) # ss -s: 关注 TIME-WAIT 数量、established 连接数 ``` ### 🟡 实战案例参考 > 遇到复杂性能问题时，可参考 `references/case_studies.md` 中的 5 大实战案例： > 容器 OOM 排查、高并发网络优化、数据库 I/O 瓶颈、Java GC 调优、微服务延迟链路分析。 --- ## 第五步：实施优化并验证效果 **实施前检查清单：** 1. [ ] 已记录所有原始参数值 2. [ ] 已在测试环境验证过方案 3. [ ] 已准备好回滚命令 4. [ ] 每次只修改一个参数 **验证流程：** ```bash # 1. 修改前采集基线 bash scripts/collect_snapshot.sh --output /tmp/before-$(date +%Y%m%d_%H%M).txt # 2. 实施优化（临时生效） sysctl -w 参数名=新值 # 3. 等待观察 bash scripts/perf_monitor.sh & sleep 300 && kill %1 # 4. 修改后采集对比 bash scripts/collect_snapshot.sh --output /tmp/after-$(date +%Y%m%d_%H%M).txt # 5. 基准测试对比（可选） bash scripts/bench-compare.sh --baseline "优化前命令" --candidate "优化后命令" --runs 10 # 6. 确认无副作用后持久化 cat >> /etc/sysctl.d/99-perf-tuning.conf << 'EOF' 参数名=新值 EOF sysctl --system ``` ### 参数修改规范 ```bash # 临时生效（立即，重启失效） sysctl -w 参数名=值 # 持久化（重启后仍生效） cat > /etc/sysctl.d/99-perf-tuning.conf << 'EOF' vm.swappiness=10 # ... 其他参数 EOF sysctl --system # 回滚 sysctl -w 参数名=原始值 # 临时回滚 rm /etc/sysctl.d/99-perf-tuning.conf && sysctl --system # 持久化回滚 ``` --- ## 各语言分析工具速查 | 语言 | CPU 分析 | 内存分析 | 火焰图 | 基准测试 | |------|---------|---------|--------|---------| | **Go** | pprof (cpu) | pprof (heap) | go tool pprof -http | go test -bench, benchstat | | **Python** | cProfile, py-spy | memory_profiler, tracemalloc | py-spy record | timeit, pytest-benchmark | | **Java** | async-profiler, JFR | jmap, MAT | async-profiler -f svg | JMH | | **Rust** | cargo-flamegraph, perf | valgrind --tool=massif | cargo flamegraph | criterion | | **C/C++** | perf, gprof, VTune | Valgrind, ASan | FlameGraph + perf | Google Benchmark | | **Node.js** | clinic.js, 0x | --inspect + DevTools | 0x | benchmark.js | --- ## 跨语言通用优化清单 1. **Profile first** — 用工具找到真正的热点，不要猜 2. **算法优先** — O(n) vs O(n²) 的差距大于任何微优化 3. **减少分配** — 预分配、对象池、复用缓冲区 4. **缓存友好** — 连续内存访问，减少指针追逐 5. **批处理** — 把多次小操作合并成一次大操作 6. **异步 I/O** — 不要阻塞等待网络/磁盘 7. **连接池** — 数据库、HTTP、gRPC 都要池化 8. **缓存** — 对昂贵计算和频繁查询加缓存层 9. **基准测试** — 每次改动都要有数据支撑 10. **CI 回归检测** — 自动化防止性能退化 --- ## 不要做的事 - 不要没有数据就优化 - 不要同时改多处然后说"快了" - 不要为了性能牺牲可读性（除非有基准证明） - 不要优化只跑一次的代码 - 不要忽略算法复杂度去做微优化 - 不要在生产环境做未经测试的内核参数变更 --- ## 告警阈值参考 | 指标 | 正常 | 警告 | 严重 | |------|------|------|------| | CPU 使用率 | < 60% | > 70% | > 90% | | 内存可用 | > 30% | < 20% | < 10% | | Swap 使用率 | 0% | > 10% | > 30% | | 磁盘使用率 | < 70% | > 80% | > 95% | | load average | < 核数 | > 核数×1.5 | > 核数×2 | | I/O await | < 10ms | > 20ms | > 50ms | | 磁盘 %util | < 60% | > 80% | > 95% | | 上下文切换/秒 | < 5万 | > 10万 | > 50万 | | TCP 重传率 | < 0.1% | > 1% | > 5% | --- ## 故障排查清单（10步法） 1. [ ] `uptime` 检查负载均值 2. [ ] `free -h` 检查内存可用量 3. [ ] `df -h` 检查磁盘空间 4. [ ] `top -bn1` 检查 CPU 使用率和高耗进程 5. [ ] `vmstat 1 3` 检查上下文切换和 I/O 等待 6. [ ] `iostat -xz 1 3` 检查磁盘 I/O 详情 7. [ ] `ss -s` 检查网络连接状态 8. [ ] `dmesg | tail -50` 检查内核日志 9. [ ] `dmesg | grep -i "oom\|killed"` 检查 OOM 事件 10. [ ] 对比基线数据，确认问题时间点 --- ## 平台注意事项 | 平台 | 注意事项 | |------|---------| | **容器/K8s** | 需 `--privileged` 或 `SYS_ADMIN` 才能运行 perf/eBPF；cgroup 限制需宿主机/平台侧修改 | | **Windows** | `perf` 不可用，用 ETW/xperf；Python multiprocessing 需 `if __name__ == '__main__'` | | **macOS** | 无 `perf`/eBPF，用 Instruments.app 或 `dtrace` | | **WSL2** | perf 可能需要自行编译匹配内核版本 | --- ## 参考文档索引 | 文档 | 内容 | |------|------| | [references/cpu.md](references/cpu.md) | CPU 调优（调度器/亲和性/NUMA/中断绑核/perf profiling） | | [references/memory.md](references/memory.md) | 内存调优（swappiness/OOM/THP/HugePage/NUMA/Slab） | | [references/disk_io.md](references/disk_io.md) | 磁盘 I/O 调优（调度器/readahead/fio/文件系统/NVMe） | | [references/network.md](references/network.md) | 网络调优（TCP 栈/连接队列/BBR/conntrack/RPS/RFS） | | [references/kernel_params.md](references/kernel_params.md) | 内核参数速查全表（含默认值/建议值/适用场景） | | [references/compile_optimization.md](references/compile_optimization.md) | 编译优化（GCC/Clang/PGO/LTO/SIMD） | | [references/case_studies.md](references/case_studies.md) | 实战案例（MySQL/Nginx/日志服务器/Java/K8s） | | [references/ebpf_bpftrace.md](references/ebpf_bpftrace.md) | eBPF/bpftrace/BCC 高级追踪工具 | | [references/benchmarking.md](references/benchmarking.md) | 基准测试工具集（fio/sysbench/iperf3/wrk） | | [references/go_performance.md](references/go_performance.md) | Go 性能分析（pprof/goroutine 泄漏/GC 调优） | | [references/python_performance.md](references/python_performance.md) | Python 性能分析（cProfile/py-spy/GIL/asyncio/Web 优化） | | [references/java_performance.md](references/java_performance.md) | Java 性能分析（JFR/async-profiler/GC 调优/arthas） | | [references/rust_performance.md](references/rust_performance.md) | Rust 性能分析（perf/criterion/flamegraph/SIMD/tokio） | | [references/c_cpp_performance.md](references/c_cpp_performance.md) | C/C++ 性能分析（perf/Valgrind/Sanitizers/LTO/PGO） | | [references/nodejs_performance.md](references/nodejs_performance.md) | Node.js 性能分析（clinic.js/Worker Threads/流式处理） | | [references/tool_output_guide.md](references/tool_output_guide.md) | 工具输出解读（top/vmstat/iostat/ss/sar/perf stat/free/pidstat/iotop/dmesg） | | [references/container_k8s.md](references/container_k8s.md) | 容器/K8s 性能调优（cgroup/throttling/OOM/Service Mesh/资源配置/运行时感知） | ## 可用脚本 | 脚本 | 用途 | |------|------| | `scripts/collect_snapshot.sh` | 一键采集系统性能快照（7大维度，含依赖检查/cgroup兼容/NVMe支持） | | `scripts/perf_monitor.sh` | 持续性能监控（后台采样+5项阈值告警+精确间隔控制） | | `scripts/bench-compare.sh` | 基准测试对比工具（命令对比/Go benchstat/统计分析） | | `scripts/python-perf-test.py` | Python 优化模式验证脚本（9项自动化测试） | | `scripts/run-evals.py` | Eval Runner — 加载 YAML 用例、调用 LLM 评分、检查 expected_keywords/expected_not | ## 评估测试用例 | 文件 | 内容 | |------|------| | `evals/linux-system.yaml` | Linux 系统性能分析测试（CPU/负载/内核参数/I/O/火焰图） | | `evals/language-optimization.yaml` | 编程语言优化测试（Python/Go/Java/Rust/C++/Node.js） | | `evals/container-k8s.yaml` | 容器/K8s 场景测试（throttling/OOM/资源配置/cgroup） | | `evals/advanced-scenarios.yaml` | 高级场景测试（eBPF/工具解读/基准测试/编译优化/Service Mesh） | --- ## 注意事项 > ⚠️ **生产环境修改前必读**： > > 1. 记录原始值：`sysctl 参数名` 保存当前值 > 2. 先临时生效观察效果，确认无副作用再持久化 > 3. 生产环境修改前，务必先在测试环境验证 > 4. `vm.overcommit_memory=2`（严格模式）与多数应用不兼容，慎用 > 5. 透明大页关闭需持久化到启动脚本，重启会还原 > 6. `net.ipv4.tcp_tw_recycle` 在内核 4.12+ 已移除 > 7. 容器环境中部分参数（cgroup 限制）需宿主机/平台侧配合修改 ---

path: scripts/bench-compare.sh
content: #!/bin/bash
# bench-compare.sh — 基准测试对比工具
# 运行两组基准并对比差异
#
# 用法:
#   bash bench-compare.sh --help
#   bash bench-compare.sh --baseline "sleep 0.1" --candidate "sleep 0.05" --runs 10
#   bash bench-compare.sh --go-bench ./...
#   bash bench-compare.sh --command "curl -s http://localhost:8080" --runs 50

set -euo pipefail

RUNS=10
MODE=""
BASELINE_CMD=""
CANDIDATE_CMD=""
GO_PKG=""
NON_INTERACTIVE=false

usage() {
    cat <<EOF
bench-compare.sh — 基准测试对比工具

用法:
  1) 对比两个命令:
     bash bench-compare.sh --baseline "CMD_A" --candidate "CMD_B" --runs N

  2) Go 基准测试对比 (需要 benchstat):
     bash bench-compare.sh --go-bench ./... --runs N

  3) 单命令多次运行统计:
     bash bench-compare.sh --command "CMD" --runs N

选项:
  --baseline CMD   基线命令
  --candidate CMD  对比命令
  --command CMD    单命令模式
  --go-bench PKG   Go 基准测试包路径
  --runs N         运行次数 (默认 10)
  --non-interactive  非交互模式，跳过所有确认提示（适用于 CI/CD）
  --help           显示帮助
EOF
    exit 0
}

while [[ $# -gt 0 ]]; do
    case "$1" in
        --baseline)   BASELINE_CMD="$2"; MODE="compare"; shift 2 ;;
        --candidate)  CANDIDATE_CMD="$2"; shift 2 ;;
        --command)    BASELINE_CMD="$2"; MODE="single"; shift 2 ;;
        --go-bench)   GO_PKG="$2"; MODE="go"; shift 2 ;;
        --runs)       RUNS="$2"; shift 2 ;;
        --non-interactive) NON_INTERACTIVE=true; shift ;;
        --help|-h)    usage ;;
        *)            echo "未知参数: $1"; usage ;;
    esac
done

# --- 参数校验 ---
if [ "$MODE" = "compare" ] && [ -z "$CANDIDATE_CMD" ]; then
    echo "错误: --baseline 必须配合 --candidate 使用" >&2
    exit 1
fi
if ! [[ "$RUNS" =~ ^[0-9]+$ ]] || [ "$RUNS" -lt 1 ]; then
    echo "错误: --runs 必须是正整数" >&2
    exit 1
fi

confirm_commands() {
    echo "即将执行的命令:" >&2
    for arg in "$@"; do
        echo "  $arg" >&2
    done
    echo "" >&2
    # 非交互模式（管道/重定向）跳过确认
    if [ "$NON_INTERACTIVE" = true ]; then
        echo "(非交互模式，跳过确认)" >&2
    elif [ -t 0 ]; then
        echo "按 Enter 继续，Ctrl+C 取消..." >&2
        read -r
    fi
}

run_timed() {
    local cmd="$1"
    local n="$2"
    local label="$3"
    local times=()

    echo "运行 $label ($n 次)..." >&2
    for i in $(seq 1 "$n"); do
        start=$(date +%s%N)
        bash -c "$cmd" > /dev/null 2>&1
        end=$(date +%s%N)
        elapsed=$(( (end - start) / 1000000 ))  # ms
        times+=("$elapsed")
        printf "\r  进度: %d/%d" "$i" "$n" >&2
    done
    echo "" >&2

    # 计算统计
    IFS=$'\n' sorted=($(sort -n <<<"${times[*]}")); unset IFS
    total=0
    for t in "${times[@]}"; do total=$((total + t)); done
    avg=$((total / n))
    min="${sorted[0]}"
    max="${sorted[$((n-1))]}"
    p50_idx=$(( n / 2 ))
    p99_idx=$(( n * 99 / 100 ))
    p50="${sorted[$p50_idx]}"
    p99="${sorted[$p99_idx]}"

    # 小样本量时 p99 没有统计意义，添加提示
    local p99_display
    if [ "$n" -lt 100 ]; then
        p99_display="${p99}ms*"
    else
        p99_display="${p99}ms"
    fi

    printf "  %-12s avg=%dms  min=%dms  p50=%dms  p99=%s  max=%dms\n" \
        "$label:" "$avg" "$min" "$p50" "$p99_display" "$max" >&2
    if [ "$n" -lt 100 ]; then
        echo "  (* p99 样本量不足 100，仅供参考)" >&2
    fi
    echo "$avg"
}

case "$MODE" in
    compare)
        echo "=========================================="
        echo " 基准对比 ($RUNS 次运行)"
        echo "=========================================="
        confirm_commands "Baseline:  $BASELINE_CMD" "Candidate: $CANDIDATE_CMD"
        avg_a=$(run_timed "$BASELINE_CMD" "$RUNS" "Baseline")
        avg_b=$(run_timed "$CANDIDATE_CMD" "$RUNS" "Candidate")
        echo ""
        if [ "$avg_a" -gt "$avg_b" ] && [ "$avg_a" -gt 0 ]; then
            speedup=$(echo "scale=2; $avg_a / $avg_b" | bc 2>/dev/null || echo "N/A")
            echo "结果: Candidate 快 ${speedup}x"
        elif [ "$avg_b" -gt "$avg_a" ] && [ "$avg_b" -gt 0 ]; then
            slowdown=$(echo "scale=2; $avg_b / $avg_a" | bc 2>/dev/null || echo "N/A")
            echo "结果: Candidate 慢 ${slowdown}x"
        else
            echo "结果: 无明显差异"
        fi
        ;;
    single)
        echo "=========================================="
        echo " 单命令基准 ($RUNS 次运行)"
        echo "=========================================="
        confirm_commands "Command: $BASELINE_CMD"
        run_timed "$BASELINE_CMD" "$RUNS" "Command"
        ;;
    go)
        if ! command -v benchstat &>/dev/null; then
            echo "安装 benchstat: go install golang.org/x/perf/cmd/benchstat@latest"
            exit 1
        fi
        echo "=========================================="
        echo " Go 基准测试对比"
        echo "=========================================="
        echo "步骤 1: 运行基线基准..."
        go test -bench=. -benchmem -count="$RUNS" "$GO_PKG" > "${TMPDIR:-/tmp}/bench-old.txt" 2>&1
        echo "保存到 ${TMPDIR:-/tmp}/bench-old.txt"
        echo ""
        echo "现在请做你的优化，然后按 Enter 运行对比基准..."
        if [ "$NON_INTERACTIVE" = true ]; then
            echo "(非交互模式，直接继续)" >&2
        else
            read -r
        fi
        echo "步骤 2: 运行对比基准..."
        go test -bench=. -benchmem -count="$RUNS" "$GO_PKG" > "${TMPDIR:-/tmp}/bench-new.txt" 2>&1
        echo ""
        echo "步骤 3: benchstat 对比结果:"
        echo "=========================================="
        benchstat "${TMPDIR:-/tmp}/bench-old.txt" "${TMPDIR:-/tmp}/bench-new.txt"
        ;;
    *)
        echo "请指定模式。运行 --help 查看用法。"
        exit 1
        ;;
esac


path: scripts/collect_snapshot.sh
content: #!/bin/bash
# =============================================================================
# Linux 系统性能快照采集脚本
# performance-mastery skill - scripts/collect_snapshot.sh
# 用途：一键采集系统全维度性能数据，输出结构化报告
# 用法：bash collect_snapshot.sh [--output /path/to/report.txt]
# 注意：不使用 set -e，因为部分工具可能未安装，脚本需要跳过缺失工具继续采集其他数据
# =============================================================================

# 依赖检查：提示缺失的可选工具
check_deps() {
    local missing=()
    local hints=()
    for cmd in iostat mpstat pidstat; do
        command -v "$cmd" &>/dev/null || { missing+=("$cmd"); hints+=("sysstat"); }
    done
    command -v iotop &>/dev/null || { missing+=("iotop"); hints+=("iotop"); }
    command -v smartctl &>/dev/null || { missing+=("smartctl"); hints+=("smartmontools"); }
    command -v numastat &>/dev/null || { missing+=("numastat"); hints+=("numactl"); }
    command -v slabtop &>/dev/null || { missing+=("slabtop"); hints+=("procps / util-linux"); }
    if [[ ${#missing[@]} -gt 0 ]]; then
        echo "⚠️  以下可选工具未安装（部分采集项将跳过）：" >&2
        local unique_hints=($(printf '%s\n' "${hints[@]}" | sort -u))
        for h in "${unique_hints[@]}"; do
            echo "   → 安装 $h: apt install $h / yum install $h" >&2
        done
        echo "" >&2
    fi
}

check_deps

OUTPUT=""
if [[ "$1" == "--output" && -n "$2" ]]; then
    OUTPUT="$2"
fi

print_section() {
    local title="$1"
    echo ""
    echo "=================================================================="
    echo "  $title"
    echo "  采集时间: $(date '+%Y-%m-%d %H:%M:%S')"
    echo "=================================================================="
}

run_cmd() {
    local desc="$1"
    local cmd="$2"
    echo ""
    echo "--- $desc ---"
    eval "$cmd" 2>/dev/null || echo "[命令不可用: $cmd]"
}

collect() {

# ─────────────────────────────────────────────
# 1. 基础信息
# ─────────────────────────────────────────────
print_section "系统基础信息"
run_cmd "主机名 & 内核版本" "uname -a"
run_cmd "操作系统版本" "cat /etc/os-release 2>/dev/null | grep -E 'PRETTY_NAME|VERSION_ID' || cat /etc/redhat-release 2>/dev/null"
run_cmd "CPU 信息" "lscpu | grep -E 'Model name|CPU\(s\)|Thread|Core|Socket|NUMA|MHz|Cache'"
run_cmd "内存总量" "free -h"
run_cmd "磁盘概览" "lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT"
run_cmd "磁盘空间" "df -h --exclude-type=tmpfs --exclude-type=devtmpfs"
run_cmd "系统运行时间" "uptime"

# ─────────────────────────────────────────────
# 2. CPU 性能
# ─────────────────────────────────────────────
print_section "CPU 性能"
run_cmd "负载均值" "cat /proc/loadavg"
run_cmd "CPU 使用率 (各核)" "mpstat -P ALL 1 3 2>/dev/null || vmstat 1 3"
run_cmd "运行队列 & 上下文切换 (vmstat 3次)" "vmstat 1 3"
run_cmd "CPU 频率调速策略" "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null || echo '无调速策略'"
run_cmd "CPU 密集型进程 TOP10" "ps aux --sort=-%cpu | head -11"
run_cmd "中断分布 TOP10" "cat /proc/interrupts | tail -n +2 | awk '{sum=0; for(i=2;i<=NF;i++){if(\$i~/^[0-9]+$/){sum+=\$i}} printf \"%12d %s\\n\", sum, \$0}' | sort -rn | head -10"
run_cmd "软中断统计" "cat /proc/softirqs | head -20"
run_cmd "调度器统计" "cat /proc/schedstat 2>/dev/null | head -5"
run_cmd "NUMA 拓扑" "numastat 2>/dev/null | head -20 || echo 'numastat 不可用'"

# ─────────────────────────────────────────────
# 3. 内存性能
# ─────────────────────────────────────────────
print_section "内存性能"
run_cmd "内存详情" "cat /proc/meminfo"
run_cmd "Swap 信息" "swapon --show 2>/dev/null || echo '无 Swap'"
run_cmd "内存密集型进程 TOP10" "ps aux --sort=-%mem | head -11"
run_cmd "Slab 缓存" "slabtop -o 2>/dev/null | head -20 || echo 'slabtop 不可用'"
run_cmd "透明大页状态" "cat /sys/kernel/mm/transparent_hugepage/enabled 2>/dev/null"
run_cmd "HugePage 配置" "grep -i huge /proc/meminfo"
run_cmd "OOM 历史 (dmesg)" "dmesg | grep -iE 'oom|killed process' | tail -20"
run_cmd "内存 cgroup 状态" "if [ -f /sys/fs/cgroup/memory.max ]; then echo 'cgroup v2:'; echo \"  limit: \$(cat /sys/fs/cgroup/memory.max)\"; echo \"  current: \$(cat /sys/fs/cgroup/memory.current)\"; cat /sys/fs/cgroup/memory.events 2>/dev/null | grep oom; elif [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then echo 'cgroup v1:'; echo \"  usage: \$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)\"; echo \"  limit: \$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)\"; echo \"  failcnt: \$(cat /sys/fs/cgroup/memory/memory.failcnt 2>/dev/null)\"; else echo '无 cgroup 内存限制信息'; fi"

# ─────────────────────────────────────────────
# 4. 磁盘 I/O 性能
# ─────────────────────────────────────────────
print_section "磁盘 I/O 性能"
run_cmd "I/O 统计 (iostat 3次)" "iostat -xz 1 3 2>/dev/null || echo 'iostat 不可用（建议安装 sysstat）'"
run_cmd "I/O 调度器" "for d in /sys/block/*/queue/scheduler; do echo \"\$(basename \$(dirname \$(dirname \$d))): \$(cat \$d)\"; done"
run_cmd "磁盘队列深度" "for d in /sys/block/*/queue/nr_requests; do echo \"\$(basename \$(dirname \$(dirname \$d))): \$(cat \$d)\"; done"
run_cmd "读预读配置" "for d in /sys/block/*/queue/read_ahead_kb; do echo \"\$(basename \$(dirname \$(dirname \$d))): \$(cat \$d) KB\"; done"
run_cmd "挂载选项" "mount | grep -v 'tmpfs\|proc\|sys\|dev\|cgroup'"
run_cmd "高 I/O 进程" "iotop -o -b -n 3 2>/dev/null | head -20 || echo 'iotop 不可用'"
run_cmd "磁盘健康 (smartctl)" "for d in /dev/sd? /dev/vd? /dev/nvme?n?; do [ -b \"\$d\" ] && smartctl -H \$d 2>/dev/null | grep -E 'result|PASSED|FAILED' && echo \"\$d\"; done 2>/dev/null || echo 'smartctl 不可用'"

# ─────────────────────────────────────────────
# 5. 网络性能
# ─────────────────────────────────────────────
print_section "网络性能"
run_cmd "连接状态统计" "ss -s"
run_cmd "TCP 连接状态分布" "ss -ant | awk '{print \$1}' | sort | uniq -c | sort -rn"
run_cmd "网络接口统计" "ip -s link"
run_cmd "网络错误/丢包统计" "netstat -s 2>/dev/null | grep -E 'fail|error|drop|overflow|reject|retransmit' | grep -v '^    0'"
run_cmd "网络接口信息" "ip addr show"
run_cmd "路由表" "ip route"
run_cmd "conntrack 状态" "cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null && cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null || echo 'conntrack 不可用'"

# ─────────────────────────────────────────────
# 6. 内核参数现状
# ─────────────────────────────────────────────
print_section "关键内核参数"
run_cmd "内存相关参数" "sysctl -a 2>/dev/null | grep -E '^vm\.' | sort"
run_cmd "网络相关参数" "sysctl -a 2>/dev/null | grep -E '^net\.(core|ipv4\.tcp|ipv4\.ip_local)' | sort"
run_cmd "调度器相关参数" "sysctl -a 2>/dev/null | grep -E '^kernel\.(sched|numa)' | sort"
run_cmd "文件描述符参数" "sysctl -a 2>/dev/null | grep -E 'fs\.file'"
run_cmd "当前文件描述符使用" "cat /proc/sys/fs/file-nr"

# ─────────────────────────────────────────────
# 7. 进程与系统调用
# ─────────────────────────────────────────────
print_section "进程与系统状态"
run_cmd "进程总数统计" "ps aux | wc -l"
run_cmd "D状态进程（不可中断睡眠）" "ps aux | awk '\$8==\"D\" {print \$0}' | head -10"
run_cmd "僵尸进程" "ps aux | awk '\$8==\"Z\" {print \$0}' | head -10"
run_cmd "打开文件数统计" "lsof 2>/dev/null | wc -l || echo 'lsof 不可用'"
run_cmd "内核日志（最近50条）" "dmesg | tail -50"

}

# 执行采集
if [[ -n "$OUTPUT" ]]; then
    collect | tee "$OUTPUT"
    echo ""
    echo "✅ 报告已保存到: $OUTPUT"
else
    collect
fi


path: scripts/perf_monitor.sh
content: #!/bin/bash
# =============================================================================
# Linux 持续性能监控脚本
# performance-mastery skill - scripts/perf_monitor.sh
# 用途：后台持续采样关键性能指标，超阈值输出告警
# 用法：
#   bash perf_monitor.sh            # 前台运行，Ctrl+C 停止
#   bash perf_monitor.sh &          # 后台运行
#   bash perf_monitor.sh --report   # 输出汇总报告
# 注意：不使用 set -e，因为采样循环中个别命令失败不应中断持续监控
# =============================================================================

# 核心依赖检查
if ! command -v vmstat &>/dev/null; then
    echo "❌ 错误：vmstat 未安装（核心依赖），请先安装 procps 包"
    echo "   → apt install procps / yum install procps-ng"
    exit 1
fi

INTERVAL=5          # 采样间隔（秒）
LOG_FILE="${TMPDIR:-/tmp}/perf_monitor_$(date +%Y%m%d_%H%M%S).log"
ALERT_LOG="${TMPDIR:-/tmp}/perf_alerts_$(date +%Y%m%d).log"

# 告警阈值（警告级别，与 SKILL.md 告警阈值参考表对齐）
THRESH_CPU_WARN=70         # CPU 使用率 %（警告）
THRESH_CPU_CRIT=90         # CPU 使用率 %（严重）
THRESH_MEM_FREE_WARN=20    # 内存可用率 %（低于此值警告）
THRESH_MEM_FREE_CRIT=10    # 内存可用率 %（低于此值严重）
THRESH_LOAD_WARN=1.5       # load average / CPU核数 比值（警告）
THRESH_LOAD_CRIT=2         # load average / CPU核数 比值（严重）
THRESH_IOWAIT_WARN=20      # iowait %（警告）
THRESH_IOWAIT_CRIT=50      # iowait %（严重）
THRESH_CS_WARN=100000      # 上下文切换次数/秒（警告）
THRESH_CS_CRIT=500000      # 上下文切换次数/秒（严重）

CPU_CORES=$(nproc)

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" >&2
}

alert() {
    local msg="ALERT: $1"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $msg" | tee -a "$LOG_FILE" >&2
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $msg" >> "$ALERT_LOG"
}

print_header() {
    log "============================================================"
    log "  Linux 性能监控启动"
    log "  CPU核数: $CPU_CORES  |  采样间隔: ${INTERVAL}s"
    log "  日志文件: $LOG_FILE"
    log "  告警文件: $ALERT_LOG"
    log "============================================================"
}

monitor_once() {
    local start_ts=$(date +%s)

    # CPU & 负载
    local load1=$(awk '{print $1}' /proc/loadavg)
    local load5=$(awk '{print $2}' /proc/loadavg)
    local load_ratio=$(echo "$load1 $CPU_CORES" | awk '{printf "%.1f", $1/$2}')

    # 内存
    local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
    local mem_avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
    local mem_free_pct=$(echo "$mem_avail $mem_total" | awk '{printf "%d", $1*100/$2}')
    local swap_total=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
    local swap_free=$(grep SwapFree /proc/meminfo | awk '{print $2}')

    # vmstat (上下文切换 & iowait)
    local vmstat_line=$(vmstat 1 2 | tail -1)
    local cs=$(echo $vmstat_line | awk '{print $12}')
    local wa=$(echo $vmstat_line | awk '{print $16}')
    local us=$(echo $vmstat_line | awk '{print $13}')
    local sy=$(echo $vmstat_line | awk '{print $14}')
    local cpu_used=$((us + sy))

    log "CPU: ${cpu_used}% (us+sy)  iowait: ${wa}%  load: ${load1}/${load5} (ratio: ${load_ratio}x)  cs/s: ${cs}  Mem可用: ${mem_free_pct}%"

    # 检查告警（双级：警告 ⚠️ + 严重 🔴）
    if [[ $cpu_used -gt $THRESH_CPU_CRIT ]]; then
        alert "🔴 CPU 使用率严重过高: ${cpu_used}% > ${THRESH_CPU_CRIT}%"
    elif [[ $cpu_used -gt $THRESH_CPU_WARN ]]; then
        alert "⚠️  CPU 使用率偏高: ${cpu_used}% > ${THRESH_CPU_WARN}%"
    fi
    if [[ $mem_free_pct -lt $THRESH_MEM_FREE_CRIT ]]; then
        alert "🔴 内存可用率严重过低: ${mem_free_pct}% < ${THRESH_MEM_FREE_CRIT}%"
    elif [[ $mem_free_pct -lt $THRESH_MEM_FREE_WARN ]]; then
        alert "⚠️  内存可用率偏低: ${mem_free_pct}% < ${THRESH_MEM_FREE_WARN}%"
    fi
    if [[ $(echo "$load_ratio $THRESH_LOAD_CRIT" | awk '{print ($1 > $2)}') -eq 1 ]]; then
        alert "🔴 负载严重过高: load1=${load1}, 核数=${CPU_CORES}, 比值=${load_ratio}x > ${THRESH_LOAD_CRIT}x"
    elif [[ $(echo "$load_ratio $THRESH_LOAD_WARN" | awk '{print ($1 > $2)}') -eq 1 ]]; then
        alert "⚠️  负载偏高: load1=${load1}, 核数=${CPU_CORES}, 比值=${load_ratio}x > ${THRESH_LOAD_WARN}x"
    fi
    if [[ $wa -gt $THRESH_IOWAIT_CRIT ]]; then
        alert "🔴 iowait 严重过高: ${wa}% > ${THRESH_IOWAIT_CRIT}%"
    elif [[ $wa -gt $THRESH_IOWAIT_WARN ]]; then
        alert "⚠️  iowait 偏高: ${wa}% > ${THRESH_IOWAIT_WARN}%"
    fi
    if [[ $cs -gt $THRESH_CS_CRIT ]]; then
        alert "🔴 上下文切换严重过高: ${cs}/s > ${THRESH_CS_CRIT}/s"
    elif [[ $cs -gt $THRESH_CS_WARN ]]; then
        alert "⚠️  上下文切换偏高: ${cs}/s > ${THRESH_CS_WARN}/s"
    fi
    if [[ $swap_total -gt 0 ]]; then
        local swap_used=$((swap_total - swap_free))
        local swap_pct=$((swap_used * 100 / swap_total))
        [[ $swap_pct -gt 30 ]] && alert "Swap 使用率过高: ${swap_pct}%"
    fi

    # 计算剩余等待时间，确保总间隔接近 INTERVAL 秒
    local end_ts=$(date +%s)
    local elapsed=$((end_ts - start_ts))
    local remaining=$((INTERVAL - elapsed))
    if [[ $remaining -gt 0 ]]; then
        sleep "$remaining"
    fi
}

print_report() {
    echo ""
    echo "============================================================"
    echo "  性能监控报告汇总"
    echo "============================================================"
    if [[ -f "$ALERT_LOG" ]]; then
        echo "告警记录："
        cat "$ALERT_LOG"
    else
        echo "无告警记录"
    fi
    echo ""
    echo "完整日志：$LOG_FILE"
}

# ── 主逻辑 ──
if [[ "$1" == "--report" ]]; then
    print_report
    exit 0
fi

print_header
trap 'echo ""; log "监控停止"; print_report; exit 0' INT TERM

while true; do
    monitor_once
done


path: scripts/python-perf-test.py
content: #!/usr/bin/env python3
"""
python-perf-test.py — Python 性能优化模式验证脚本
验证 performance-mastery skill 中 Python 部分的各项优化建议

用法: python3 python-perf-test.py
"""
import sys
import time
import timeit
import cProfile
import pstats
import io
import tracemalloc
from functools import lru_cache
from concurrent.futures import ThreadPoolExecutor

if sys.platform == "win32":
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    sys.stderr.reconfigure(encoding="utf-8", errors="replace")

passed = 0
failed = 0

def test(name, condition, detail=""):
    global passed, failed
    if condition:
        passed += 1
        print(f"  PASS  {name}" + (f"  ({detail})" if detail else ""))
    else:
        failed += 1
        print(f"  FAIL  {name}" + (f"  ({detail})" if detail else ""))

print("=" * 60)
print("Python Performance Optimization — Validation Tests")
print("=" * 60)

# --- Test 1: List comprehension vs loop ---
N = 1_000_000
data = list(range(N))
t1 = timeit.timeit(lambda: [x * 2 for x in data], number=5)
def loop_ver():
    r = []
    for x in data:
        r.append(x * 2)
    return r
t2 = timeit.timeit(loop_ver, number=5)
test("List comprehension faster than loop", t1 < t2, f"{t2/t1:.2f}x")

# --- Test 2: Generator memory (peak comparison) ---
# 测量列表推导式的峰值内存
tracemalloc.start()
_ = sum([x for x in range(N)])
_, list_peak = tracemalloc.get_traced_memory()
tracemalloc.stop()

# 测量生成器表达式的峰值内存
tracemalloc.start()
_ = sum(x for x in range(N))
_, gen_peak = tracemalloc.get_traced_memory()
tracemalloc.stop()

test("Generator uses less memory", gen_peak < list_peak,
     f"list peak={list_peak/1024:.0f}KB, gen peak={gen_peak/1024:.0f}KB, "
     f"saved {(list_peak-gen_peak)/1024:.0f}KB ({(1-gen_peak/list_peak)*100:.0f}%)")

# --- Test 3: set lookup vs list ---
sdata = list(range(100_000))
sset = set(sdata)
targets = list(range(0, 100_000, 7))
t_list = timeit.timeit(lambda: [x in sdata for x in targets], number=3)
t_set = timeit.timeit(lambda: [x in sset for x in targets], number=3)
test("set lookup faster than list", t_set < t_list, f"{t_list/t_set:.0f}x")

# --- Test 4: join vs += ---
pieces = [str(i) for i in range(10_000)]
t_join = timeit.timeit(lambda: ''.join(pieces), number=500)
def concat_plus():
    r = ''
    for p in pieces:
        r += p
    return r
t_plus = timeit.timeit(concat_plus, number=500)
test("join faster than +=", t_join < t_plus, f"{t_plus/t_join:.1f}x")

# --- Test 5: lru_cache ---
@lru_cache(maxsize=256)
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)
fib.cache_clear()
t_cached = timeit.timeit(lambda: fib(30), number=1)
test("lru_cache works", fib(30) == 832040, f"fib(30)={fib(30)}")

# --- Test 6: cProfile ---
profiler = cProfile.Profile()
profiler.enable()
sum(range(100_000))
profiler.disable()
s = io.StringIO()
pstats.Stats(profiler, stream=s).print_stats(3)
test("cProfile works", 'ncalls' in s.getvalue())

# --- Test 7: tracemalloc ---
tracemalloc.start()
_ = [bytearray(1024) for _ in range(100)]
snap = tracemalloc.take_snapshot()
stats = snap.statistics('lineno')
tracemalloc.stop()
test("tracemalloc detects allocations", len(stats) > 0, f"{len(stats)} alloc points")

# --- Test 8: timeit ---
result = timeit.timeit('sum(range(100))', number=10000)
test("timeit works", result > 0, f"{result:.4f}s for 10000 iters")

# --- Test 9: ThreadPoolExecutor ---
def io_sim(n):
    time.sleep(0.02)
    return n
items = list(range(20))
t_seq = timeit.timeit(lambda: [io_sim(n) for n in items], number=1)
def run_tp():
    with ThreadPoolExecutor(max_workers=10) as ex:
        list(ex.map(io_sim, items))
t_tp = timeit.timeit(run_tp, number=1)
test("ThreadPoolExecutor speeds up I/O", t_tp < t_seq, f"{t_seq/t_tp:.1f}x")

# --- Summary ---
print("\n" + "=" * 60)
total = passed + failed
print(f"Results: {passed}/{total} passed, {failed} failed")
if failed == 0:
    print("All tests passed!")
else:
    print(f"WARNING: {failed} test(s) failed")
    sys.exit(1)


path: scripts/run-evals.py
content: #!/usr/bin/env python3
"""
run-evals.py — performance-mastery Eval Runner
加载 evals/ 目录下的 YAML 测试用例，向 LLM 发送 prompt，
检查输出中是否包含 expected_keywords 和 expected_not，输出评分报告。

用法:
  # 基本用法（需要设置 OPENAI_API_KEY 或 OPENAI_BASE_URL）
  python3 scripts/run-evals.py

  # 指定模型和 API
  python3 scripts/run-evals.py --model gpt-4o --base-url https://api.openai.com/v1

  # 只运行特定文件
  python3 scripts/run-evals.py --file evals/linux-system.yaml

  # 干跑模式（不调用 LLM，仅验证 YAML 格式）
  python3 scripts/run-evals.py --dry-run

  # 自定义通过阈值（默认 50%）
  python3 scripts/run-evals.py --threshold 0.6

评分标准:
  - 每个用例的 expected_keywords 命中率 >= threshold（默认 50%）视为 PASS
  - 如果 expected_not 中任意关键词出现在回答中，该用例标记为 WARN（不影响通过）
  - 最终报告显示总通过率和各文件的详细结果

依赖:
  pip install pyyaml openai
"""
import argparse
import glob
import json
import os
import sys
import time
from pathlib import Path

try:
    import yaml
except ImportError:
    print("ERROR: PyYAML is required. Install with: pip install pyyaml")
    sys.exit(1)


def load_eval_files(eval_dir, specific_file=None):
    """加载 evals/ 目录下所有 YAML 文件或指定文件"""
    if specific_file:
        files = [specific_file]
    else:
        files = sorted(glob.glob(os.path.join(eval_dir, "*.yaml")))

    all_suites = []
    for f in files:
        with open(f, "r", encoding="utf-8") as fh:
            data = yaml.safe_load(fh)
        tests = data.get("tests", data) if isinstance(data, dict) else data
        if isinstance(tests, list):
            all_suites.append({"file": os.path.basename(f), "tests": tests})
        else:
            print(f"  WARN  Skipping {f}: no 'tests' list found")
    return all_suites


def call_llm(prompt, model, base_url, api_key, system_prompt=None):
    """调用 OpenAI 兼容 API"""
    try:
        from openai import OpenAI
    except ImportError:
        print("ERROR: openai package is required. Install with: pip install openai")
        sys.exit(1)

    client = OpenAI(base_url=base_url, [REDACTED_SECRET])
    messages = []
    if system_prompt:
        messages.append({"role": "system", "content": system_prompt})
    messages.append({"role": "user", "content": prompt})

    resp = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0.3,
        max_tokens=2048,
    )
    return resp.choices[0].message.content


def check_keywords(response, expected_keywords):
    """检查回答中命中了多少 expected_keywords（大小写不敏感）"""
    response_lower = response.lower()
    hits = []
    misses = []
    for kw in expected_keywords:
        if kw.lower() in response_lower:
            hits.append(kw)
        else:
            misses.append(kw)
    return hits, misses


def check_not_keywords(response, expected_not):
    """检查回答中是否包含不应出现的关键词"""
    if not expected_not:
        return []
    response_lower = response.lower()
    violations = []
    for kw in expected_not:
        if kw.lower() in response_lower:
            violations.append(kw)
    return violations


def run_eval(suite, model, base_url, api_key, threshold, dry_run=False):
    """运行一个 eval 文件中的所有测试用例"""
    results = []
    system_prompt = (
        "你是一位资深的 Linux 系统性能工程师和全栈性能优化专家。"
        "请用中文回答，给出具体的工具命令和参数。"
    )

    for test_case in suite["tests"]:
        name = test_case.get("name", "unnamed")
        input_prompt = test_case.get("input", "")
        expected_kw = test_case.get("expected_keywords", [])
        expected_not = test_case.get("expected_not", [])

        if dry_run:
            results.append({
                "name": name,
                "status": "DRY-RUN",
                "keywords_total": len(expected_kw),
                "expected_not_count": len(expected_not),
                "input_preview": input_prompt[:60],
            })
            continue

        # 调用 LLM
        try:
            response = call_llm(input_prompt, model, base_url, api_key, system_prompt)
        except Exception as e:
            results.append({
                "name": name,
                "status": "ERROR",
                "error": str(e),
            })
            continue

        # 检查关键词
        hits, misses = check_keywords(response, expected_kw)
        violations = check_not_keywords(response, expected_not)
        hit_rate = len(hits) / len(expected_kw) if expected_kw else 1.0
        passed = hit_rate >= threshold

        results.append({
            "name": name,
            "status": "PASS" if passed else "FAIL",
            "hit_rate": hit_rate,
            "hits": hits,
            "misses": misses,
            "violations": violations,
            "response_length": len(response),
        })

        # 避免 API 限流
        time.sleep(0.5)

    return results


def print_report(all_results, threshold):
    """打印评分报告"""
    print("\n" + "=" * 70)
    print("  performance-mastery Eval Report")
    print("=" * 70)
    print(f"  Pass threshold: {threshold*100:.0f}% of expected_keywords\n")

    total_pass = 0
    total_fail = 0
    total_error = 0
    total_dry = 0

    for suite_result in all_results:
        file_name = suite_result["file"]
        results = suite_result["results"]
        suite_pass = sum(1 for r in results if r["status"] == "PASS")
        suite_fail = sum(1 for r in results if r["status"] == "FAIL")
        suite_error = sum(1 for r in results if r["status"] == "ERROR")
        suite_dry = sum(1 for r in results if r["status"] == "DRY-RUN")

        print(f"── {file_name} ({len(results)} tests) ──")

        for r in results:
            name = r["name"]
            status = r["status"]

            if status == "DRY-RUN":
                print(f"  ⬜ DRY-RUN  {name}  "
                      f"(keywords={r['keywords_total']}, "
                      f"expected_not={r['expected_not_count']})")
            elif status == "ERROR":
                print(f"  ❌ ERROR    {name}  ({r.get('error', 'unknown')})")
            elif status == "PASS":
                warn = ""
                if r.get("violations"):
                    warn = f"  ⚠ found: {r['violations']}"
                print(f"  ✅ PASS     {name}  "
                      f"({r['hit_rate']*100:.0f}% hit, "
                      f"{len(r['hits'])}/{len(r['hits'])+len(r['misses'])}){warn}")
                if r.get("misses"):
                    print(f"              missed: {r['misses']}")
            else:  # FAIL
                warn = ""
                if r.get("violations"):
                    warn = f"  ⚠ found: {r['violations']}"
                print(f"  ❌ FAIL     {name}  "
                      f"({r['hit_rate']*100:.0f}% hit, "
                      f"{len(r['hits'])}/{len(r['hits'])+len(r['misses'])}){warn}")
                print(f"              missed: {r['misses']}")

        total_pass += suite_pass
        total_fail += suite_fail
        total_error += suite_error
        total_dry += suite_dry
        print()

    # 总结
    total = total_pass + total_fail + total_error + total_dry
    print("=" * 70)
    if total_dry > 0:
        print(f"  DRY-RUN: {total_dry}/{total} test cases validated")
        print("  (No LLM calls made — YAML format OK)")
    else:
        print(f"  Total: {total_pass}/{total_pass+total_fail} passed"
              f"  ({total_pass/(total_pass+total_fail)*100:.0f}%)"
              if (total_pass + total_fail) > 0 else "  No tests executed")
        if total_error > 0:
            print(f"  Errors: {total_error}")
    print("=" * 70)

    return total_fail == 0 and total_error == 0


def main():
    parser = argparse.ArgumentParser(
        description="performance-mastery Eval Runner — "
                    "测试 AI 对性能分析问题的回答质量"
    )
    parser.add_argument(
        "--file", "-f",
        help="只运行指定的 eval YAML 文件（默认运行 evals/ 下所有文件）"
    )
    parser.add_argument(
        "--model", "-m",
        default=os.environ.get("EVAL_MODEL", "gpt-4o"),
        help="LLM 模型名称（默认 gpt-4o，可通过 EVAL_MODEL 环境变量设置）"
    )
    parser.add_argument(
        "--base-url",
        default=os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"),
        help="OpenAI 兼容 API 地址（可通过 OPENAI_BASE_URL 环境变量设置）"
    )
    parser.add_argument(
        "--api-key",
        default=os.environ.get("OPENAI_API_KEY", ""),
        help="API Key（可通过 OPENAI_API_KEY 环境变量设置）"
    )
    parser.add_argument(
        "--threshold", "-t",
        type=float, default=0.5,
        help="关键词命中率通过阈值（默认 0.5，即 50%%）"
    )
    parser.add_argument(
        "--dry-run", "-d",
        action="store_true",
        help="干跑模式：仅验证 YAML 格式，不调用 LLM"
    )
    parser.add_argument(
        "--output", "-o",
        help="将结果输出为 JSON 文件"
    )

    args = parser.parse_args()

    # 定位 evals 目录
    script_dir = Path(__file__).resolve().parent
    project_root = script_dir.parent
    eval_dir = project_root / "evals"

    if not eval_dir.exists():
        print(f"ERROR: evals directory not found: {eval_dir}")
        sys.exit(1)

    # 加载测试用例
    suites = load_eval_files(str(eval_dir), args.file)
    if not suites:
        print("ERROR: No eval files found")
        sys.exit(1)

    total_tests = sum(len(s["tests"]) for s in suites)
    print(f"Loaded {len(suites)} eval file(s), {total_tests} test case(s)")

    if not args.dry_run and not args.[REDACTED_SECRET]"\nWARN: No API key provided. Use --dry-run to validate YAML, "
              "or set OPENAI_API_KEY environment variable.")
        print("Falling back to --dry-run mode.\n")
        args.dry_run = True

    # 运行测试
    all_results = []
    for suite in suites:
        print(f"\nRunning: {suite['file']} ({len(suite['tests'])} tests)...")
        results = run_eval(
            suite, args.model, args.base_url, args.api_key,
            args.threshold, args.dry_run
        )
        all_results.append({"file": suite["file"], "results": results})

    # 输出报告
    success = print_report(all_results, args.threshold)

    # 可选 JSON 输出
    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            json.dump(all_results, f, ensure_ascii=False, indent=2)
        print(f"\nResults saved to: {args.output}")

    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()


path: references/benchmarking.md
content: # 基准测试工具集


## 目录

- [fio — 磁盘 I/O 基准](#fio-磁盘-io-基准)
- [sysbench — CPU / 内存基准](#sysbench-cpu-内存基准)
- [iperf3 — 网络基准](#iperf3-网络基准)
- [wrk / wrk2 — HTTP 基准](#wrk-wrk2-http-基准)
- [性能参考基准值](#性能参考基准值)
- [基准测试最佳实践](#基准测试最佳实践)
## fio — 磁盘 I/O 基准

```bash
# 安装
sudo apt install -y fio    # Debian/Ubuntu
sudo dnf install -y fio    # RHEL/CentOS

# 顺序读（模拟备份读取）
fio --name=seq-read --ioengine=libaio --direct=1 --rw=read \
  --bs=1M --numjobs=4 --size=1G --runtime=60 --time_based --group_reporting

# 顺序写
fio --name=seq-write --ioengine=libaio --direct=1 --rw=write \
  --bs=1M --numjobs=4 --size=1G --runtime=60 --time_based --group_reporting

# 随机读 4K（模拟数据库 IOPS）
fio --name=rand-read --ioengine=libaio --direct=1 --rw=randread \
  --bs=4k --numjobs=16 --iodepth=64 --size=1G --runtime=60 --time_based --group_reporting

# 随机写 4K
fio --name=rand-write --ioengine=libaio --direct=1 --rw=randwrite \
  --bs=4k --numjobs=16 --iodepth=64 --size=1G --runtime=60 --time_based --group_reporting

# 混合读写 70/30（典型数据库负载）
fio --name=mixed --ioengine=libaio --direct=1 --rw=randrw --rwmixread=70 \
  --bs=4k --numjobs=8 --iodepth=32 --size=1G --runtime=60 --time_based --group_reporting
```

### fio 结果解读

| 指标 | 说明 |
|------|------|
| **IOPS** | 每秒 I/O 操作数（随机读写关注） |
| **BW (bandwidth)** | 带宽/吞吐量（顺序读写关注） |
| **lat (latency)** | 延迟（avg/p99 都要看） |
| **clat** | 完成延迟 |
| **slat** | 提交延迟 |

---

## sysbench — CPU / 内存基准

```bash
# 安装
sudo apt install -y sysbench

# CPU 基准（多线程）
sysbench cpu --threads=4 --time=30 run

# 内存基准
sysbench memory --threads=4 --time=30 \
  --memory-block-size=1K --memory-total-size=100G run

# MySQL 基准
sysbench oltp_read_write --db-driver=mysql --mysql-host=localhost \
  --mysql-user=root --mysql-db=sbtest --tables=10 --table-size=100000 \
  --threads=16 --time=60 prepare
sysbench oltp_read_write --db-driver=mysql --mysql-host=localhost \
  --mysql-user=root --mysql-db=sbtest --tables=10 --table-size=100000 \
  --threads=16 --time=60 run
```

---

## iperf3 — 网络基准

```bash
# 安装
sudo apt install -y iperf3

# 服务端
iperf3 -s

# TCP 吞吐测试
iperf3 -c <server-ip> -t 30 -P 4    # 30 秒，4 并行流

# UDP 丢包测试
iperf3 -c <server-ip> -u -b 1G -t 30

# 反向测试（服务端发送）
iperf3 -c <server-ip> -R -t 30

# 双向同时测试
iperf3 -c <server-ip> --bidir -t 30
```

---

## wrk / wrk2 — HTTP 基准

```bash
# 安装
sudo apt install -y wrk

# 基本测试（10 线程，400 连接，30 秒）
wrk -t 10 -c 400 -d 30s http://localhost:8080/api

# 带脚本（POST 请求等）
wrk -t 4 -c 100 -d 30s -s post.lua http://localhost:8080/api

# wrk2（恒定请求速率，更精确的延迟分布）
wrk2 -t 4 -c 100 -d 30s -R 10000 http://localhost:8080/api
```

---

## 性能参考基准值

> 以下数值为典型硬件上的参考范围，实际结果因硬件、内核版本、文件系统等差异较大。仅用于快速判断"结果是否合理"。

### fio 磁盘 I/O 参考

| 测试场景 | HDD (7200rpm) | SATA SSD | NVMe SSD | 云盘(SSD) |
|----------|:----------:|:--------:|:--------:|:---------:|
| 顺序读 (1M) | 100-200 MB/s | 400-550 MB/s | 2-7 GB/s | 100-500 MB/s |
| 顺序写 (1M) | 80-150 MB/s | 300-500 MB/s | 1-5 GB/s | 100-300 MB/s |
| 随机读 4K IOPS | 100-200 | 30K-90K | 200K-1M+ | 10K-100K |
| 随机写 4K IOPS | 100-200 | 20K-70K | 100K-500K | 10K-50K |
| 随机读 4K 延迟 | 5-15ms | 0.05-0.2ms | 0.01-0.1ms | 0.2-2ms |

### sysbench CPU 参考

| CPU 型号 | 单线程 events/s | 多线程 (4核) |
|----------|:-----------:|:----------:|
| Intel i5-12400 | ~3,500 | ~13,000 |
| Intel Xeon 8375C | ~2,500 | ~10,000 |
| AMD EPYC 9654 | ~3,000 | ~12,000 |
| Apple M2 | ~4,000 | ~15,000 |
| 云服务器 (通用型) | ~1,500-3,000 | ~6,000-12,000 |

### iperf3 网络参考

| 网络类型 | 典型吞吐 | 典型延迟 |
|----------|:--------:|:--------:|
| 千兆以太网 | 940 Mbps | < 1ms |
| 万兆以太网 | 9.4 Gbps | < 0.5ms |
| 25G 以太网 | 23+ Gbps | < 0.3ms |
| 同机房 (云) | 1-10 Gbps | 0.1-0.5ms |
| 跨可用区 (云) | 1-5 Gbps | 0.5-2ms |
| 跨地域 (云) | 100-500 Mbps | 10-100ms |

### wrk HTTP 参考

| 场景 | 框架 | 典型 QPS | 典型 p99 延迟 |
|------|------|:--------:|:----------:|
| Hello World | Nginx 静态 | 100K-500K | < 1ms |
| Hello World | Go net/http | 50K-200K | < 2ms |
| Hello World | Node.js Fastify | 30K-50K | < 5ms |
| JSON API | Go Gin | 30K-100K | 1-5ms |
| JSON API | Spring Boot | 10K-30K | 2-10ms |
| DB 查询 (简单) | 通用 | 5K-20K | 5-50ms |

> 💡 **如何判断结果好坏**：
> - 结果在参考范围内 → ✅ 正常
> - 低于参考范围 50% 以上 → ⚠️ 可能有瓶颈，需要排查
> - 低于参考范围 80% 以上 → 🔴 严重性能问题

---

## 基准测试最佳实践

1. **预热** — 跑几分钟预热后再采集数据
2. **多次运行** — 至少跑 3-5 次取中位数
3. **隔离变量** — 一次只改一个参数
4. **记录环境** — 记录硬件、内核版本、配置
5. **关注 p99** — 平均值会掩盖尾部延迟
6. **避免干扰** — 测试时关闭不相关服务


path: references/case_studies.md
content: # Linux 性能优化实战案例分析

> 本文档收录了5类典型场景的完整诊断→解决→验证流程，可作为遇到类似问题时的参考范本。

---


## 目录

- [案例 1：MySQL 数据库服务器内存优化](#案例-1mysql-数据库服务器内存优化)
- [案例 2：Web 服务器高并发连接优化](#案例-2web-服务器高并发连接优化)
- [案例 3：日志服务器磁盘 I/O 瓶颈](#案例-3日志服务器磁盘-io-瓶颈)
- [案例 4：Java 应用内存泄漏排查](#案例-4java-应用内存泄漏排查)
- [案例 5：容器/K8s 资源争抢导致 Pod 变慢](#案例-5容器k8s-资源争抢导致-pod-变慢)
- [通用排查七步法](#通用排查七步法)
## 案例 1：MySQL 数据库服务器内存优化

**环境：** 16GB 内存，8核 CPU，MySQL 5.7  
**症状：** 系统响应变慢，偶尔出现连接超时，OOM killer 触发

### 诊断过程

```bash
# 检查内存使用
free -h
# available 仅 500MB（总16GB）

# 检查 OOM 日志
dmesg | grep -i oom
# 发现 MySQL 进程被杀死记录

# 检查 swappiness
sysctl vm.swappiness
# vm.swappiness = 60（默认值过高）

# 检查透明大页
cat /sys/kernel/mm/transparent_hugepage/enabled
# [always] madvise never ← 数据库场景应关闭
```

### 解决方案

```bash
# 1. 降低 swappiness（数据库推荐 1~10）
echo "vm.swappiness = 10" >> /etc/sysctl.conf
sysctl -p

# 2. 禁用透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 持久化（写入 systemd service，见 references/memory.md 第4节）

# 3. 优化 MySQL 配置（/etc/my.cnf）
# innodb_buffer_pool_size = 10G  # 物理内存的 70%
# innodb_log_file_size = 512M
# max_connections = 500

# 4. 保护 MySQL 进程不被 OOM Kill
echo -500 > /proc/$(pgrep mysqld)/oom_score_adj
```

### 验证效果

```bash
watch -n 1 'free -h'              # 内存可用量应稳定
sysctl vm.swappiness              # 确认值为 10
dmesg -w                          # 无新的 OOM 记录
cat /sys/kernel/mm/transparent_hugepage/enabled   # 应显示 never
```

### 经验总结

1. **数据库 swappiness 必须调低**（推荐 1~10）
2. **THP 会严重影响数据库性能**（MySQL/Redis/PostgreSQL 官方均建议关闭）
3. **innodb_buffer_pool_size 不超过物理内存的 70-80%**
4. **用 oom_score_adj 保护关键进程**

---

## 案例 2：Web 服务器高并发连接优化

**环境：** Nginx 反向代理，QPS 5000+  
**症状：** 高峰期报 "Cannot assign requested address"，连接错误率上升

### 诊断过程

```bash
# 检查连接状态（TIME_WAIT 爆炸）
ss -tan | awk '{print $1}' | sort | uniq -c
# TIME-WAIT: 15234（过多，端口濒临耗尽）

# 检查本地端口范围
sysctl net.ipv4.ip_local_port_range
# 32768 60999（约28000个端口，不够用）

# 检查文件描述符限制
ulimit -n
# 1024（严重过低）

# 检查队列溢出
netstat -s | grep -i listen
# "times the listen queue of a socket overflowed"（队列溢出）
```

### 解决方案

```bash
# 一键优化网络参数
cat > /etc/sysctl.d/99-highperf-web.conf << 'EOF'
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.ip_local_port_range = 1024 65535
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152
EOF
sysctl -p /etc/sysctl.d/99-highperf-web.conf

# 调整用户文件描述符限制
cat >> /etc/security/limits.conf << 'EOF'
nginx soft nofile 65535
nginx hard nofile 65535
EOF

# Nginx 配置同步调整
# events { worker_connections 65535; multi_accept on; use epoll; }
# http { keepalive_timeout 65; keepalive_requests 1000; }
```

### 验证效果

```bash
ss -tan | grep -c TIME-WAIT       # 从15000降至500
sysctl net.ipv4.ip_local_port_range  # 确认1024 65535
ab -n 100000 -c 1000 http://example.com/   # 错误率从5%降至0.01%
```

### 经验总结

1. **TIME_WAIT 过多=端口范围不够 + 未开启重用**
2. **默认端口范围只有28000个，高并发必须扩大**
3. **文件描述符默认1024，任何服务都需要调大**
4. **应用层 listen backlog 也要同步调大**

---

## 案例 3：日志服务器磁盘 I/O 瓶颈

**环境：** 日志聚合服务器，HDD 磁盘  
**症状：** 系统间歇性卡顿，命令响应慢，应用日志写入延迟

### 诊断过程

```bash
# 确认 iowait 高
top -bn1 | grep Cpu
# 45.2%wa（iowait 极高）

# 磁盘 I/O 统计
iostat -xz 1
# sda: %util=99.8%, await=150ms（严重拥塞）

# 找 I/O 密集进程
iotop -o
# rsyslogd 写入量最大

# 检查调度器
cat /sys/block/sda/queue/scheduler
# [mq-deadline]（HDD 应使用 bfq）

# 检查磁盘健康
smartctl -a /dev/sda | grep Reallocated
# Reallocated_Sector_Ct = 15（有坏道！）
```

### 解决方案

```bash
# 1. 切换为 bfq 调度器（HDD 公平调度）
echo bfq > /sys/block/sda/queue/scheduler

# 2. 优化脏页回写（减少写入积压）
sysctl -w vm.dirty_ratio=20
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_expire_centisecs=3000
sysctl -w vm.dirty_writeback_centisecs=500

# 3. 优化 rsyslog 异步写入（/etc/rsyslog.conf）
# $ActionQueueType LinkedList
# $ActionQueueFileName fwdRule1
# $ActionResumeRetryCount -1

# 4. 硬件层：规划 HDD 替换为 SSD 或专用日志磁盘
```

### 验证效果

```bash
watch -n 1 'iostat -x 1 2 | grep sda'
# await 从 150ms 降至 20ms，%util 从99%降至40%
```

### 经验总结

1. **HDD 使用 bfq，SSD 使用 mq-deadline**
2. **日志服务器应使用独立磁盘，不与系统盘共用**
3. **磁盘出现坏扇区要立即规划更换，不要等彻底损坏**
4. **脏页回写参数影响 I/O 尖峰行为**

---

## 案例 4：Java 应用内存泄漏排查

**环境：** Java 8，Heap 8GB  
**症状：** 运行几天后 OOM，GC 频率越来越高，Full GC 后内存不下降

### 诊断过程

```bash
# 监控内存趋势（每5秒）
watch -n 5 'ps -p $(pgrep java) -o rss,vsz'
# RSS 持续增长，没有回落

# 查看 GC 日志（JVM 参数需包含 -Xloggc:/var/log/gc.log）
tail -f /var/log/gc.log
# Full GC 频率越来越高，Old Gen 使用量不下降

# 生成堆转储
jmap -dump:format=b,file=/tmp/heap.hprof $(pgrep java)
# 使用 Eclipse MAT 或 jhat 分析 heap.hprof
```

### 解决方案

```bash
# 1. 优化 JVM 参数
JAVA_OPTS="-Xms8g -Xmx8g
  -XX:+UseG1GC
  -XX:MaxGCPauseMillis=200
  -XX:+HeapDumpOnOutOfMemoryError
  -XX:HeapDumpPath=/var/log/java/
  -XX:+PrintGCDetails
  -Xloggc:/var/log/gc.log
  -XX:+UseStringDeduplication"

# 2. 代码层面（根据堆转储分析结果）
# - 修复内存泄漏（未关闭的连接/流）
# - ThreadLocal 使用后调用 remove()
# - 避免静态集合持续增长

# 3. 操作系统保护
echo -500 > /proc/$(pgrep java)/oom_score_adj
```

### 验证效果

```bash
grep "Full GC" /var/log/gc.log | wc -l   # Full GC 次数显著减少
watch -n 10 'ps -p $(pgrep java) -o rss' # 内存稳定，不再持续增长
```

### 经验总结

1. **JVM 必须启用 GC 日志和 OOM 自动堆转储**
2. **G1 GC 适合大 Heap（>4GB）**
3. **ThreadLocal 是最常见的内存泄漏来源之一**
4. **监控比事后排查更重要**

---

## 案例 5：容器/K8s 资源争抢导致 Pod 变慢

**环境：** Kubernetes 多租户集群  
**症状：** Pod 间歇性变慢，日志出现 CPU throttled

### 诊断过程

```bash
# 检查 Pod 资源
kubectl top pods
kubectl describe pod <pod-name> | grep -A5 "Limits\|Requests"

# 检查 CPU throttling（关键！）
kubectl exec <pod> -- cat /sys/fs/cgroup/cpu/cpu.stat
# nr_throttled 持续增长 ← 说明被 CPU limit 限制

# 检查节点资源
kubectl top nodes
kubectl describe node <node-name> | grep -A10 "Allocated resources"

# 检查 OOM 事件
kubectl get events | grep OOMKilled
```

### 解决方案

```yaml
# 1. 合理调整 requests 和 limits
resources:
  requests:
    memory: "512Mi"
    cpu: "500m"
  limits:
    memory: "1Gi"
    cpu: "2000m"   # limit 设为 requests 的 2-4 倍，允许 burst

# 2. 关键服务使用 Guaranteed QoS（requests = limits）
resources:
  requests:
    memory: "1Gi"
    cpu: "1000m"
  limits:
    memory: "1Gi"
    cpu: "1000m"
```

```bash
# 3. 容器内系统调优（需要 privileged 权限或宿主机操作）
# 调整调度参数减少上下文切换
sysctl -w kernel.sched_min_granularity_ns=10000000

# 4. 宿主机节点预留系统资源（kubelet 配置）
# --system-reserved=cpu=1,memory=2Gi
# --kube-reserved=cpu=500m,memory=1Gi
```

### 验证效果

```bash
kubectl exec <pod> -- cat /sys/fs/cgroup/cpu/cpu.stat
# nr_throttled 停止增长

kubectl top pods --containers
# CPU 使用率在 requests 和 limits 之间波动（正常）
```

### 经验总结

1. **CPU throttling 是容器变慢最常见的隐性原因**
2. **limit 不要设得太小，应留 2-4 倍 burst 空间**
3. **关键服务用 Guaranteed QoS，保证资源不被抢占**
4. **节点必须预留足够的系统资源**

---

## 通用排查七步法

```text
1. 收集症状
   └─ 用户反馈什么？监控告警了什么？从什么时候开始？

2. 确定范围
   └─ 单机问题 还是 全局问题？
   └─ 持续问题 还是 间歇问题？

3. 运行快照
   └─ bash scripts/collect_snapshot.sh > /tmp/snapshot.txt

4. 定位子系统
   └─ CPU / 内存 / 磁盘 / 网络？
   └─ 应用层 / 系统层 / 硬件层？

5. 深入分析
   └─ 查阅对应 references/*.md 文档
   └─ 使用专项工具（perf/iotop/ss/...）

6. 实施优化
   └─ 临时生效 → 观察效果 → 确认后持久化
   └─ 每次只改一个变量，方便定位效果

7. 文档记录
   └─ 问题原因 + 解决方案 + 经验教训
   └─ 更新性能基线数据
```


path: references/compile_optimization.md
content: # 编译优化参考

## 目录
1. [何时应该进行编译优化](#1-何时应该进行编译优化)
2. [GCC 优化选项速查](#2-gcc-优化选项速查)
3. [Clang 优化选项](#3-clang-优化选项)
4. [PGO（性能引导优化）](#4-pgo性能引导优化)
5. [LTO（链接时优化）](#5-lto链接时优化)
6. [SIMD 向量化](#6-simd-向量化)
7. [典型场景编译命令](#7-典型场景编译命令)
8. [编译优化效果验证](#8-编译优化效果验证)

---

## 1. 何时应该进行编译优化

**适合场景：**
- CPU 密集型计算（数值计算、图像处理、加解密、压缩）
- 发现 perf/gprof 热点函数集中在自行编译的代码中
- 性能测试证明有 20%+ 的 CPU 时间消耗在用户态代码
- 当前编译选项为 `-O0` 或 `-O1`（未充分优化）

**不适合场景：**
- 瓶颈在 I/O、网络或内存带宽（编译优化无效）
- 代码逻辑存在严重算法问题（优化架构比编译优化更有效）
- 第三方闭源库（无源码无法重新编译）

---

## 2. GCC 优化选项速查

### 优化等级

| 选项 | 效果 | 适用场景 |
|------|------|---------|
| `-O0` | 不优化，调试友好 | 开发阶段 |
| `-O1` | 基础优化 | 快速构建 |
| `-O2` | 常规优化（**推荐默认**） | 大多数生产场景 |
| `-O3` | 激进优化（含向量化） | CPU 密集计算 |
| `-Os` | 优化代码大小 | 嵌入式/缓存敏感 |
| `-Ofast` | `-O3` + 宽松浮点（不符合 IEEE 754） | 数值计算且不需要精确浮点 |

### 针对目标架构优化

```bash
# 编译为适合当前机器架构的代码（最大化利用 CPU 指令集）
gcc -O2 -march=native -mtune=native -o output input.c

# 指定特定架构（跨平台编译时）
gcc -O2 -march=x86-64-v3 -o output input.c   # x86-64-v3 = AVX2 支持

# 查看当前 CPU 支持的特性
gcc -march=native -Q --help=target | grep -E "enabled|march"

# 开启内联优化（减少函数调用开销）
gcc -O2 -finline-functions -finline-limit=200 input.c
```

### 调试信息与优化兼容（gdb 调试优化代码）

```bash
# 生产环境：保留调试信息但不影响性能
gcc -O2 -g3 -fno-omit-frame-pointer -o output input.c
# -fno-omit-frame-pointer：保留帧指针，方便 perf/gdb 堆栈回溯
```

---

## 3. Clang 优化选项

```bash
# Clang 基本用法与 GCC 类似
clang -O2 -march=native -o output input.c

# Clang 特有：自动向量化报告
clang -O2 -Rpass=loop-vectorize -Rpass-missed=loop-vectorize input.c

# Clang 生成 LLVM 中间代码（用于 LTO）
clang -O2 -flto input.c -o output

# Clang 地址/内存 sanitizer（找 bug）
clang -O1 -fsanitize=address,undefined -g input.c    # AddressSanitizer
clang -O1 -fsanitize=thread -g input.c               # ThreadSanitizer
```

---

## 4. PGO（性能引导优化）

**原理**：先用真实负载运行程序生成性能数据，再用此数据指导编译器做更精准的优化（分支预测、内联决策等）。

**效果**：通常比普通 `-O2` 提升 10-20% 性能。

```bash
# === GCC PGO 三步流程 ===

# 第一步：插桩编译（instrumented build）
gcc -O2 -fprofile-generate -o app_pgo input.c

# 第二步：用真实工作负载运行（生成 .gcda 文件）
./app_pgo --run-benchmark
# 运行后会生成 input.gcda 文件

# 第三步：使用 profile 数据重新编译
gcc -O2 -fprofile-use -fprofile-correction -o app_final input.c

# === Clang PGO 三步流程 ===

# 第一步：插桩编译
clang -O2 -fprofile-instr-generate -o app_pgo input.c

# 第二步：运行生成 .profraw 文件
./app_pgo
LLVM_PROFILE_FILE="default.profraw" ./app_pgo

# 将 profraw 合并为 profdata
llvm-profdata merge -output=default.profdata *.profraw

# 第三步：使用 profdata 重新编译
clang -O2 -fprofile-instr-use=default.profdata -o app_final input.c
```

---

## 5. LTO（链接时优化）

**原理**：在链接阶段跨模块进行优化（内联跨文件函数、删除未使用代码）。

```bash
# GCC LTO 自动并行（推荐，速度与优化平衡）
gcc -O2 -flto=auto input1.c input2.c -o output

# GCC 全量 LTO（优化更彻底，但编译慢）
gcc -O2 -flto -fuse-linker-plugin input1.c input2.c -o output

# Clang ThinLTO（强烈推荐，与 PGO 组合效果最佳）
clang -O2 -flto=thin input1.c input2.c -o output

# CMake 项目开启 LTO
# 在 CMakeLists.txt 中：
# set_property(TARGET myapp PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
```

---

## 6. SIMD 向量化

```bash
# 查看 CPU 支持的 SIMD 指令集
cat /proc/cpuinfo | grep -m1 flags | tr ' ' '\n' | grep -E "sse|avx|avx512"

# GCC 自动向量化（-O3 已包含）
gcc -O3 -ftree-vectorize -fopt-info-vec-optimized input.c

# 指定 AVX2 指令集
gcc -O2 -mavx2 -mfma input.c

# 指定 AVX-512（Skylake-SP 以后的 Intel）
gcc -O2 -mavx512f -mavx512dq input.c

# 查看向量化是否生效（查看汇编中是否有 ymm/zmm 寄存器）
gcc -O3 -march=native -S -o output.s input.c
grep -E "ymm|zmm|xmm" output.s | head -10

# ⚠️ AVX-512 在某些 CPU 上会降低频率（thermal throttling），测试确认效果
```

---

## 7. 典型场景编译命令

```bash
# 场景1：通用服务端 C/C++ 应用（稳定性优先）
gcc -O2 -g3 -fno-omit-frame-pointer -march=x86-64-v2 \
    -D_FORTIFY_SOURCE=2 -fstack-protector-strong \
    -Wl,-z,relro,-z,now \
    -o app src/*.c

# 场景2：高性能计算（极致 CPU 性能）
gcc -O3 -march=native -mtune=native \
    -fno-omit-frame-pointer \
    -ftree-vectorize -funroll-loops \
    -flto=auto \
    -o app src/*.c

# 场景3：PGO + LTO 组合（最优生产配置）
# 步骤1
gcc -O2 -fprofile-generate -march=native -o app_train src/*.c
./app_train --benchmark   # 跑真实负载
# 步骤2
gcc -O2 -fprofile-use -flto=auto -march=native \
    -fno-omit-frame-pointer \
    -o app_final src/*.c

# 场景4：Python 扩展模块（.so）
# 注：setup.py 方式已逐步过时，推荐使用 pyproject.toml + pip install
CFLAGS="-O3 -march=native -ffast-math" python3 setup.py build_ext --inplace

# 场景5：Rust 发布构建（cargo）
RUSTFLAGS="-C target-cpu=native -C lto=thin" cargo build --release
```

---

## 8. 编译优化效果验证

```bash
# 验证方法1：perf stat 对比 CPU 指令数
perf stat ./app_O0   # 记录 instructions, cycles, IPC
perf stat ./app_O3   # 对比 IPC 是否提升

# 验证方法2：time 命令对比
time ./app_O0
time ./app_O3

# 验证方法3：查看二进制中的指令集使用
objdump -d app_O3 | grep -c "vmovaps\|vaddps\|ymm"   # AVX 指令数量

# 验证方法4：查看实际使用的优化 flags
gcc -Q -O2 --help=optimizers 2>/dev/null | grep enabled

# 检查是否有意外的性能回退
# 特别注意 -Ofast / 浮点优化可能导致数值结果不一致
./app_O0 > output_O0.txt
./app_Ofast > output_Ofast.txt
diff output_O0.txt output_Ofast.txt   # 确认结果一致
```


path: references/container_k8s.md
content: # 容器与 K8s 性能调优

> 覆盖 Docker/containerd 容器运行时和 Kubernetes 环境下的性能诊断、资源配置、CPU throttling、内存管理、网络优化等核心场景。

## 目录

- [容器性能诊断快速入门](#容器性能诊断快速入门)
- [cgroup v1 vs v2](#cgroup-v1-vs-v2)
- [CPU Throttling 排查与优化](#cpu-throttling-排查与优化)
- [容器内存管理](#容器内存管理)
- [K8s 资源配置最佳实践](#k8s-资源配置最佳实践)
- [容器内核参数限制](#容器内核参数限制)
- [语言运行时容器感知](#语言运行时容器感知)
- [Service Mesh 性能影响与优化](#service-mesh-性能影响与优化)
- [容器网络性能](#容器网络性能)
- [容器 I/O 性能](#容器-io-性能)
- [K8s 性能监控](#k8s-性能监控)
- [常见问题排查](#常见问题排查)

---

## 容器性能诊断快速入门

### 容器内快速检查

```bash
# ① 查看 cgroup 版本
stat -fc %T /sys/fs/cgroup/ 2>/dev/null
# cgroup2fs → v2, tmpfs → v1

# ② CPU 限制
# cgroup v1
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 2>/dev/null
cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 2>/dev/null
# cgroup v2
cat /sys/fs/cgroup/cpu.max 2>/dev/null

# ③ 内存限制
# cgroup v1
cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null
cat /sys/fs/cgroup/memory/memory.usage_in_bytes 2>/dev/null
# cgroup v2
cat /sys/fs/cgroup/memory.max 2>/dev/null
cat /sys/fs/cgroup/memory.current 2>/dev/null

# ④ CPU throttling 统计
# cgroup v1
cat /sys/fs/cgroup/cpu/cpu.stat 2>/dev/null
# cgroup v2
cat /sys/fs/cgroup/cpu.stat 2>/dev/null

# ⑤ 内存 OOM 事件
# cgroup v1
cat /sys/fs/cgroup/memory/memory.oom_control 2>/dev/null
# cgroup v2
cat /sys/fs/cgroup/memory.events 2>/dev/null

# ⑥ 实际可用 CPU 核数计算
QUOTA=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 2>/dev/null || echo "-1")
PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 2>/dev/null || echo "100000")
if [ "$QUOTA" != "-1" ]; then
    echo "CPU 限制: $(echo "scale=2; $QUOTA / $PERIOD" | bc) 核"
else
    echo "CPU 无限制"
fi
```

### 宿主机侧检查

```bash
# 查看容器资源使用
docker stats --no-stream

# K8s Pod 资源使用
kubectl top pods -n <namespace>
kubectl top nodes

# 查看 Pod 的 cgroup 路径
POD_ID=$(crictl pods --name <pod-name> -q)
crictl inspectp $POD_ID | grep cgroupsPath
```

---

## cgroup v1 vs v2

### 路径差异

| 资源 | cgroup v1 路径 | cgroup v2 路径 |
|------|---------------|---------------|
| CPU 配额 | `/sys/fs/cgroup/cpu/cpu.cfs_quota_us` | `/sys/fs/cgroup/cpu.max` |
| CPU 周期 | `/sys/fs/cgroup/cpu/cpu.cfs_period_us` | （合并到 cpu.max） |
| CPU 统计 | `/sys/fs/cgroup/cpu/cpu.stat` | `/sys/fs/cgroup/cpu.stat` |
| CPU 权重 | `/sys/fs/cgroup/cpu/cpu.shares` | `/sys/fs/cgroup/cpu.weight` |
| 内存限制 | `/sys/fs/cgroup/memory/memory.limit_in_bytes` | `/sys/fs/cgroup/memory.max` |
| 内存使用 | `/sys/fs/cgroup/memory/memory.usage_in_bytes` | `/sys/fs/cgroup/memory.current` |
| 内存事件 | `/sys/fs/cgroup/memory/memory.oom_control` | `/sys/fs/cgroup/memory.events` |
| I/O 限制 | `/sys/fs/cgroup/blkio/` | `/sys/fs/cgroup/io.max` |

### cgroup v2 cpu.max 格式

```bash
# 格式: $QUOTA $PERIOD
# 例如: 200000 100000 → 2 个 CPU 核
cat /sys/fs/cgroup/cpu.max
200000 100000
```

### cgroup v2 cpu.stat 字段

```text
usage_usec 12345678        # 总 CPU 使用时间（微秒）
user_usec 10000000         # 用户态 CPU 时间
system_usec 2345678        # 内核态 CPU 时间
nr_periods 56789           # 调度周期总数
nr_throttled 1234          # 被限流的周期数
throttled_usec 5678901     # 被限流的总时间（微秒）
```

---

## CPU Throttling 排查与优化

### 什么是 CPU Throttling

当容器在一个 CFS 调度周期（默认 100ms）内用完了 CPU 配额，内核会暂停该容器的所有线程，直到下一个周期开始。这就是 **CPU throttling**。

### 诊断 Throttling

```bash
# 方法一：直接读取 cgroup
# cgroup v1
cat /sys/fs/cgroup/cpu/cpu.stat
# nr_periods 56789       ← 总调度周期数
# nr_throttled 1234      ← 被限流的周期数
# throttled_time 5678901 ← 被限流的总纳秒数

# 计算限流比例
awk '/nr_periods/{p=$2} /nr_throttled/{t=$2} END{printf "限流比例: %.2f%%\n", t/p*100}' /sys/fs/cgroup/cpu/cpu.stat

# 方法二：K8s 中通过 Prometheus
# container_cpu_cfs_throttled_periods_total / container_cpu_cfs_periods_total

# 方法三：持续监控限流
watch -n 1 'cat /sys/fs/cgroup/cpu/cpu.stat'
```

### Throttling 判断标准

| 限流比例 | 严重程度 | 建议 |
|:--------:|:--------:|------|
| < 5% | ✅ 正常 | 偶尔突发，可接受 |
| 5% - 25% | ⚠️ 警告 | 影响延迟，应增加 CPU limit |
| > 25% | 🔴 严重 | 严重影响性能，必须调整 |

### 优化方案

#### 方案一：增加 CPU limit

```yaml
# K8s Pod spec
resources:
  requests:
    cpu: "1000m"      # 1 核
  limits:
    cpu: "2000m"      # 2 核（增加 headroom）
```

#### 方案二：去掉 CPU limit（推荐 Google/Zalando 实践）

```yaml
# 只设 request，不设 limit → 允许 burst
resources:
  requests:
    cpu: "1000m"
  # 不设 limits.cpu
```

> ⚠️ **注意**：去掉 CPU limit 会导致 Pod 变为 Burstable QoS，在节点资源紧张时可能被优先驱逐。

#### 方案三：调整 CFS 周期（需宿主机权限）

```bash
# 将 CFS 周期从 100ms 调整为 5ms（减少单次限流的延迟影响）
# 适用于延迟敏感型服务
echo 5000 > /sys/fs/cgroup/cpu/cpu.cfs_period_us
# 同步调整 quota 保持总 CPU 不变
# 例如原来 quota=200000/period=100000（2核）
# 改为 quota=10000/period=5000（仍然是 2 核）
echo 10000 > /sys/fs/cgroup/cpu/cpu.cfs_quota_us
```

---

## 容器内存管理

### OOM Kill 排查

```bash
# 容器内检查
dmesg | grep -i "oom\|killed process" | tail -20

# cgroup v1 OOM 事件
cat /sys/fs/cgroup/memory/memory.oom_control
# oom_kill_disable 0
# under_oom 0
# oom_kill 3    ← 已发生 3 次 OOM Kill

# cgroup v2 内存事件
cat /sys/fs/cgroup/memory.events
# low 0
# high 0
# max 5         ← 达到内存上限 5 次
# oom 3         ← OOM Kill 3 次
# oom_kill 3

# K8s 中查看 OOM 历史
kubectl describe pod <pod-name> | grep -A5 "Last State"
kubectl get events --field-selector reason=OOMKilling -n <namespace>
```

### 内存使用详情

```bash
# cgroup v1
cat /sys/fs/cgroup/memory/memory.stat
# cache 1234567890      ← 页缓存
# rss 987654321         ← 实际使用的物理内存
# mapped_file 123456789 ← 内存映射文件
# swap 0                ← Swap 使用量

# cgroup v2
cat /sys/fs/cgroup/memory.stat
# anon 987654321        ← 匿名页（堆/栈）
# file 1234567890       ← 文件页（缓存）
# shmem 12345678        ← 共享内存

# 内存使用率计算
USAGE=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes 2>/dev/null || cat /sys/fs/cgroup/memory.current 2>/dev/null)
LIMIT=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null || cat /sys/fs/cgroup/memory.max 2>/dev/null)
echo "内存使用: $(echo "scale=2; $USAGE / 1048576" | bc) MB / $(echo "scale=2; $LIMIT / 1048576" | bc) MB ($(echo "scale=1; $USAGE * 100 / $LIMIT" | bc)%)"
```

### 内存优化建议

| 问题 | 原因 | 解决方案 |
|------|------|---------|
| 频繁 OOM Kill | limit 设置过低 | 增加 memory limit，分析内存使用模式 |
| 内存持续增长 | 内存泄漏 | 使用语言对应的内存分析工具 |
| cache 占用高 | 文件 I/O 频繁 | 正常行为，cache 可被回收 |
| RSS 突然飙高 | 大对象分配 | 检查应用日志、使用 pprof/MAT 分析 |

---

## K8s 资源配置最佳实践

### requests vs limits

| 参数 | 作用 | 设置建议 |
|------|------|---------|
| `requests.cpu` | 调度保证（节点必须有这么多空闲 CPU） | 设为应用稳态 CPU 使用量 |
| `limits.cpu` | CPU 硬上限（超过会 throttle） | 设为 requests 的 1.5-3 倍，或不设 |
| `requests.memory` | 调度保证 + OOM 评分依据 | 设为应用稳态内存使用量 |
| `limits.memory` | 内存硬上限（超过会 OOM Kill） | **必须设置**，设为 requests 的 1.2-1.5 倍 |

### QoS 类别

| QoS | 条件 | 驱逐优先级 | 适用场景 |
|-----|------|:----------:|---------|
| **Guaranteed** | 所有容器 requests = limits | 最后被驱逐 | 核心服务 |
| **Burstable** | 至少一个容器 requests ≠ limits | 中等 | 大部分服务 |
| **BestEffort** | 没有设置任何 requests/limits | 最先被驱逐 | 批处理任务 |

### 推荐配置模板

```yaml
# 延迟敏感型服务（API 网关、Web 服务）
resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
  limits:
    # cpu: 不设置，允许 burst
    memory: "768Mi"

---
# CPU 密集型服务（计算、编码）
resources:
  requests:
    cpu: "2000m"
    memory: "1Gi"
  limits:
    cpu: "4000m"     # 允许 burst 到 4 核
    memory: "1.5Gi"

---
# 内存密集型服务（缓存、数据库）
resources:
  requests:
    cpu: "500m"
    memory: "4Gi"
  limits:
    cpu: "1000m"
    memory: "4Gi"    # Guaranteed QoS，防止 OOM 影响数据

---
# 批处理任务
resources:
  requests:
    cpu: "100m"
    memory: "256Mi"
  limits:
    cpu: "4000m"
    memory: "2Gi"
```

### VPA / HPA 配置

```yaml
# HPA - 水平自动扩缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70    # CPU 使用率 > 70% 扩容
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60    # 扩容冷却期
    scaleDown:
      stabilizationWindowSeconds: 300   # 缩容冷却期（防抖动）
```

---

## 容器内核参数限制

### 容器内可修改的 sysctl 参数

K8s 将 sysctl 分为 **safe** 和 **unsafe** 两类：

#### Safe sysctl（默认允许）

```yaml
# Pod spec 中直接设置
spec:
  securityContext:
    sysctls:
    - name: net.ipv4.ip_local_port_range
      value: "1024 65535"
    - name: net.ipv4.tcp_syncookies
      value: "1"
    - name: kernel.shm_rmid_forced
      value: "1"
```

#### Unsafe sysctl（需要集群管理员启用）

```yaml
# 需要在 kubelet 配置中启用
# --allowed-unsafe-sysctls='net.core.somaxconn,net.ipv4.tcp_tw_reuse'

spec:
  securityContext:
    sysctls:
    - name: net.core.somaxconn
      value: "65535"
    - name: net.ipv4.tcp_tw_reuse
      value: "1"
```

#### 必须在宿主机修改的参数

| 参数 | 原因 | 说明 |
|------|------|------|
| `vm.swappiness` | 全局内存策略 | 影响所有容器 |
| `vm.dirty_ratio` | 全局脏页策略 | 影响所有容器 |
| `vm.min_free_kbytes` | 全局内存保留 | 影响所有容器 |
| `kernel.sched_*` | CPU 调度器参数 | 影响所有容器 |
| `net.core.rmem_max` | 全局 socket 缓冲区 | 需宿主机设置 |
| `net.core.wmem_max` | 全局 socket 缓冲区 | 需宿主机设置 |
| `net.ipv4.tcp_rmem` | TCP 读缓冲区 | 需宿主机设置 |
| `net.ipv4.tcp_wmem` | TCP 写缓冲区 | 需宿主机设置 |

---

## 语言运行时容器感知

### Java

```bash
# Java 8u191+ / Java 11+ 默认启用容器感知
java -XX:+PrintFlagsFinal -version 2>&1 | grep UseContainerSupport
# bool UseContainerSupport = true

# 关键 JVM 参数
# -XX:+UseContainerSupport    启用容器感知（默认开启）
# -XX:MaxRAMPercentage=75.0   堆内存占容器 limit 的 75%
# -XX:InitialRAMPercentage=50.0  初始堆占 50%
# -XX:+UseG1GC               G1 GC（通用推荐）
java \
  -XX:+UseContainerSupport \
  -XX:MaxRAMPercentage=75.0 \
  -XX:InitialRAMPercentage=50.0 \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=200 \
  -jar app.jar

# ⚠️ 常见坑：
# 1. Java 8u131-8u190 需要手动启用: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
# 2. 不要同时设置 -Xmx 和 MaxRAMPercentage，-Xmx 优先级更高
# 3. 堆外内存（Metaspace/DirectByteBuffer/线程栈）不受 MaxRAMPercentage 控制
#    建议 memory limit = 堆内存 × 1.5（留 50% 给堆外）
```

### Go

```bash
# Go 1.19+ 支持 GOMEMLIMIT
# 自动感知 cgroup CPU 限制需要第三方库

# 方法一：设置 GOMEMLIMIT（推荐）
GOMEMLIMIT=3200MiB ./app    # 容器 limit 4Gi，设为 80%

# 方法二：使用 automaxprocs 自动适配 CPU
# import _ "go.uber.org/automaxprocs"
# 自动将 GOMAXPROCS 设为 cgroup CPU 配额

# ⚠️ 常见坑：
# 1. 默认 GOMAXPROCS = 宿主机 CPU 核数，不是容器配额
#    在 48 核宿主机上 limit 2 核，GOMAXPROCS=48 → 大量上下文切换
# 2. GOMEMLIMIT 应设为 memory limit 的 80-90%（留 buffer 给非堆内存）
# 3. Go 1.19 之前只有 GOGC，无法设硬上限
```

### Python

```python
# Python 没有内置容器感知
# 需要手动读取 cgroup 限制

import os
import multiprocessing

def get_cpu_limit():
    """获取容器 CPU 限制"""
    try:
        # cgroup v2
        with open('/sys/fs/cgroup/cpu.max') as f:
            quota, period = f.read().strip().split()
            if quota == 'max':
                return os.cpu_count()
            return int(quota) // int(period)
    except FileNotFoundError:
        pass
    try:
        # cgroup v1
        with open('/sys/fs/cgroup/cpu/cpu.cfs_quota_us') as f:
            quota = int(f.read().strip())
        with open('/sys/fs/cgroup/cpu/cpu.cfs_period_us') as f:
            period = int(f.read().strip())
        if quota == -1:
            return os.cpu_count()
        return max(1, quota // period)
    except FileNotFoundError:
        return os.cpu_count()

def get_memory_limit():
    """获取容器内存限制"""
    try:
        # cgroup v2
        with open('/sys/fs/cgroup/memory.max') as f:
            val = f.read().strip()
            return int(val) if val != 'max' else None
    except FileNotFoundError:
        pass
    try:
        # cgroup v1
        with open('/sys/fs/cgroup/memory/memory.limit_in_bytes') as f:
            val = int(f.read().strip())
            # 超大值表示无限制
            return val if val < 2**62 else None
    except FileNotFoundError:
        return None

# 使用示例
cpu_limit = get_cpu_limit()
print(f"CPU 限制: {cpu_limit} 核")
# 设置进程池/线程池大小
# pool = multiprocessing.Pool(cpu_limit)
```

### Node.js

```bash
# Node.js 12+ 自动感知容器内存限制
# 但默认 --max-old-space-size 可能不够

# 推荐设置
# --max-old-space-size=3072   容器 limit 4Gi，堆设为 75%
# --max-semi-space-size=64    新生代大小（高吞吐可增大）
node \
  --max-old-space-size=3072 \
  --max-semi-space-size=64 \
  app.js

# 或使用环境变量
NODE_OPTIONS="--max-old-space-size=3072" node app.js

# ⚠️ 常见坑：
# 1. Node.js 默认堆上限约 1.5GB（64位系统），容器 limit 更大时需手动设置
# 2. Worker Threads 每个 worker 有独立的 V8 堆，总内存 = 主线程 + N × worker 堆
# 3. 原生插件（C++ addon）的内存不受 V8 堆限制控制
```

### Rust

```bash
# Rust 没有 GC，内存管理由编译器保证，通常无需容器感知配置
# 但以下场景需要注意：

# 1. 线程数量：默认使用 num_cpus crate 获取 CPU 核数 → 可能获取到宿主机核数
#    解决方案：使用 num_cpus 0.14+（已支持 cgroup 感知）
#    或手动读取 cgroup CPU 配额
TOKIO_WORKER_THREADS=4 ./app    # 手动限制 tokio 工作线程数

# 2. Rayon 并行度：默认使用所有 CPU 核
RAYON_NUM_THREADS=4 ./app       # 限制 rayon 线程池大小

# 3. 内存分配器：jemalloc/mimalloc 在容器中表现更好
# Cargo.toml:
# [dependencies]
# tikv-jemallocator = "0.5"

# ⚠️ 常见坑：
# 1. num_cpus < 0.14 会读取宿主机 CPU 数（不感知 cgroup）
# 2. tokio 默认 worker 线程 = CPU 核数，在 48 核宿主机 limit 2 核时会创建 48 个线程
# 3. mmap 分配的内存不受 Rust 所有权管理，需注意容器内存限制
```

### C/C++

```bash
# C/C++ 程序通常直接使用系统调用，没有运行时容器感知
# 需要手动处理以下问题：

# 1. 获取容器 CPU 限制（而非宿主机 CPU 数）
# 不要使用 sysconf(_SC_NPROCESSORS_ONLN)，它返回宿主机 CPU 数
# 正确做法：读取 cgroup 文件
cat /sys/fs/cgroup/cpu.max 2>/dev/null || \
  echo "$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us) $(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)"

# 2. 线程池大小应基于容器 CPU 配额，而非 std::thread::hardware_concurrency()
# C++ 示例：
# int get_container_cpus() {
#     // 优先读取 cgroup v2
#     std::ifstream f("/sys/fs/cgroup/cpu.max");
#     if (f.is_open()) {
#         std::string quota_s, period_s;
#         f >> quota_s >> period_s;
#         if (quota_s != "max") return std::max(1, std::stoi(quota_s) / std::stoi(period_s));
#     }
#     return std::thread::hardware_concurrency();
# }

# 3. 内存分配器选择
# glibc malloc 在容器中可能导致内存碎片
# 推荐：jemalloc 或 tcmalloc
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so ./app

# ⚠️ 常见坑：
# 1. std::thread::hardware_concurrency() 返回宿主机核数
# 2. /proc/cpuinfo 显示宿主机所有 CPU
# 3. glibc malloc 的 ARENA 数量默认 = 8 × CPU核数，在容器中会过多
#    设置 MALLOC_ARENA_MAX=4 限制 arena 数量
MALLOC_ARENA_MAX=4 ./app
```

---

## Service Mesh 性能影响与优化

### Sidecar 代理的性能开销

Service Mesh（如 Istio/Linkerd）通过 sidecar 代理拦截所有网络流量，会引入额外延迟和资源消耗：

| 指标 | 无 Service Mesh | Istio (Envoy) | Linkerd | 说明 |
|------|:--------------:|:--------------:|:-------:|------|
| 延迟增加 | 基线 | +2-10ms (p50) | +1-3ms (p50) | 取决于 mTLS 和策略复杂度 |
| CPU 开销 | 0 | 100-500m / pod | 50-200m / pod | sidecar 本身消耗 |
| 内存开销 | 0 | 50-150Mi / pod | 20-50Mi / pod | Envoy 占用较大 |
| 吞吐影响 | 基线 | -5~15% | -2~8% | 高并发场景更明显 |

### 诊断 Service Mesh 性能问题

```bash
# 1. 确认延迟是否来自 sidecar
# 对比 Pod 内直连 vs 经过 sidecar 的延迟
# Pod 内直接访问（绕过 sidecar）
kubectl exec -it <pod> -c app -- curl -w "%{time_total}\n" -o /dev/null -s http://localhost:8080/health
# 经过 sidecar 访问
kubectl exec -it <pod> -c app -- curl -w "%{time_total}\n" -o /dev/null -s http://<service-name>/health

# 2. 检查 Envoy sidecar 资源使用
kubectl top pod <pod-name> --containers
# 关注 istio-proxy 容器的 CPU 和内存

# 3. Envoy 统计信息
kubectl exec -it <pod> -c istio-proxy -- curl localhost:15000/stats | grep -E "upstream_rq|downstream_rq|cx_active"

# 4. 检查 mTLS 握手开销
kubectl exec -it <pod> -c istio-proxy -- curl localhost:15000/stats | grep ssl
```

### 优化方案

```yaml
# 1. 为 sidecar 分配足够资源（避免 CPU throttling）
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      concurrency: 2          # Envoy worker 线程数（匹配 CPU limit）
  values:
    global:
      proxy:
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"       # 高流量服务需增大
            memory: "256Mi"
```

```yaml
# 2. 对延迟不敏感的内部服务禁用 mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: disable-mtls-internal
spec:
  selector:
    matchLabels:
      app: internal-batch-job
  mtls:
    mode: DISABLE
```

```yaml
# 3. 对不需要 mesh 功能的 Pod 跳过 sidecar 注入
metadata:
  annotations:
    sidecar.istio.io/inject: "false"    # 跳过 sidecar
```

```bash
# 4. Envoy 并发优化
# 默认 concurrency=2，高流量服务可增大
# 在 Pod annotation 中设置：
# sidecar.istio.io/proxyCPU: "500m"
# sidecar.istio.io/proxyMemory: "256Mi"
```

### 性能优化清单

| 优化项 | 预期效果 | 适用场景 |
|--------|---------|---------|
| 增大 sidecar CPU limit | 减少 throttling 延迟 | sidecar CPU 使用率 > 80% |
| 设置合理的 concurrency | 匹配 CPU 配额 | 高并发服务 |
| 禁用不需要的 mTLS | 减少 1-3ms 延迟 | 内部批处理服务 |
| 跳过 sidecar 注入 | 消除所有 mesh 开销 | 不需要 mesh 功能的服务 |
| 使用 Linkerd 替代 Istio | 更低的资源开销 | 只需要 mTLS + 可观测性 |
| 启用 HTTP/2 多路复用 | 减少连接建立开销 | gRPC / 高并发 HTTP |
| 使用 Istio ambient mesh | 无 sidecar 架构 | Istio 1.18+，减少资源开销 |

---

## 容器网络性能

### 常见网络模式性能对比

| 网络模式 | 延迟开销 | 吞吐影响 | 适用场景 |
|----------|:--------:|:--------:|---------|
| Host 网络 | 无 | 无 | 高性能网络服务 |
| Bridge (veth) | +10-30μs | -5~15% | 默认模式 |
| Overlay (VXLAN) | +50-100μs | -10~20% | 跨节点通信 |
| Calico (BGP) | +5-15μs | -2~5% | K8s 推荐 |
| Cilium (eBPF) | +2-10μs | -1~3% | 高性能 K8s |

### 容器内网络诊断

```bash
# 检查 DNS 解析延迟（K8s 常见瓶颈）
time nslookup kubernetes.default.svc.cluster.local

# 如果 DNS 慢（> 100ms），检查 CoreDNS
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50

# 检查 conntrack 表
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# count 接近 max → conntrack 表满，会丢包

# 容器间网络延迟测试
# Pod A:
iperf3 -s
# Pod B:
iperf3 -c <pod-a-ip> -t 10
```

### K8s DNS 优化

```yaml
# Pod spec 中配置 DNS 策略
spec:
  dnsPolicy: ClusterFirst
  dnsConfig:
    options:
    - name: ndots
      value: "2"           # 默认 5，减少不必要的 DNS 查询
    - name: single-request-reopen
      value: ""            # 避免 DNS 查询丢包
    - name: timeout
      value: "2"
    - name: attempts
      value: "3"
```

> **ndots 优化说明**：K8s 默认 `ndots=5`，查询 `api.example.com` 时会先尝试 `api.example.com.default.svc.cluster.local` 等 5 次，最后才查外部 DNS。设为 2 可大幅减少无效 DNS 查询。

---

## 容器 I/O 性能

### I/O 限制配置

```yaml
# K8s 不直接支持 I/O 限制，需要通过 cgroup 或存储类配置

# Docker 运行时设置
docker run --device-read-bps /dev/sda:100mb --device-write-bps /dev/sda:50mb myapp

# cgroup v2 I/O 限制
echo "8:0 rbps=104857600 wbps=52428800" > /sys/fs/cgroup/io.max
```

### 容器存储性能建议

| 存储类型 | 性能 | 适用场景 |
|----------|------|---------|
| emptyDir (tmpfs) | 最快（内存速度） | 临时缓存、中间文件 |
| emptyDir (disk) | 快（本地磁盘） | 临时数据 |
| hostPath | 快（本地磁盘） | 需要持久化的本地数据 |
| PVC (local-storage) | 快 | 数据库、有状态服务 |
| PVC (网络存储) | 慢（取决于网络） | 共享存储 |
| PVC (云盘 SSD) | 中等 | 云环境通用 |

---

## K8s 性能监控

### Prometheus 关键指标

```promql
# CPU throttling 比例
sum(rate(container_cpu_cfs_throttled_periods_total{pod="my-pod"}[5m]))
/
sum(rate(container_cpu_cfs_periods_total{pod="my-pod"}[5m]))

# 内存使用率
container_memory_working_set_bytes{pod="my-pod"}
/
container_spec_memory_limit_bytes{pod="my-pod"}

# OOM Kill 次数
kube_pod_container_status_restarts_total{pod="my-pod"}

# 网络流量
sum(rate(container_network_receive_bytes_total{pod="my-pod"}[5m]))
sum(rate(container_network_transmit_bytes_total{pod="my-pod"}[5m]))

# 磁盘 I/O
sum(rate(container_fs_reads_bytes_total{pod="my-pod"}[5m]))
sum(rate(container_fs_writes_bytes_total{pod="my-pod"}[5m]))
```

### kubectl 快速诊断命令

```bash
# Pod 资源使用概览
kubectl top pods -n <namespace> --sort-by=cpu
kubectl top pods -n <namespace> --sort-by=memory

# 节点资源压力
kubectl describe node <node-name> | grep -A5 "Conditions"
# MemoryPressure, DiskPressure, PIDPressure

# Pod 事件（OOM、Eviction、FailedScheduling）
kubectl get events -n <namespace> --sort-by='.lastTimestamp' | tail -20

# Pod 详细状态
kubectl describe pod <pod-name> -n <namespace>

# 查看资源配额使用
kubectl describe resourcequota -n <namespace>
```

---

## 常见问题排查

### 问题 1：Pod 频繁 OOM Kill

```bash
# 排查步骤
# 1. 确认内存限制
kubectl describe pod <pod-name> | grep -A2 "Limits"

# 2. 查看内存使用趋势
kubectl top pod <pod-name> --containers

# 3. 进入容器查看详细内存
kubectl exec -it <pod-name> -- cat /sys/fs/cgroup/memory.stat

# 4. 检查是否内存泄漏
# Java: jmap -heap <PID>
# Go: curl localhost:6060/debug/pprof/heap > heap.out
# Python: tracemalloc
# Node.js: --inspect + Chrome DevTools
```

**解决方案优先级**：
1. 确认是否内存泄漏（修复代码）
2. 增加 memory limit
3. 优化应用内存使用（缓存策略、连接池大小）

### 问题 2：服务延迟抖动

```bash
# 排查步骤
# 1. 检查 CPU throttling
cat /sys/fs/cgroup/cpu/cpu.stat | grep throttled

# 2. 检查 GC 暂停（Java/Go）
# Java: -XX:+PrintGCDetails -Xloggc:/tmp/gc.log
# Go: GODEBUG=gctrace=1

# 3. 检查同节点是否有 noisy neighbor
kubectl top pods -n <namespace> --sort-by=cpu

# 4. 检查网络延迟
ping <service-ip>
```

**解决方案**：
1. 增加 CPU limit 或去掉 CPU limit
2. 调整 GC 参数
3. 使用 Pod Anti-Affinity 分散部署
4. 使用 PriorityClass 确保关键服务优先级

### 问题 3：Pod 调度失败 (Insufficient cpu/memory)

```bash
# 排查步骤
# 1. 查看节点资源分配情况
kubectl describe nodes | grep -A5 "Allocated resources"

# 2. 检查是否 requests 设置过高
kubectl get pods -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].resources.requests}{"\n"}{end}'

# 3. 查看是否有资源碎片
kubectl describe nodes | grep -E "Capacity|Allocatable|Allocated"
```

**解决方案**：
1. 降低 requests（但不低于实际使用量）
2. 使用 VPA 自动调整 requests
3. 扩容集群节点
4. 使用 Pod Disruption Budget 平衡可用性

### 问题 4：容器启动慢

```bash
# 排查步骤
# 1. 镜像拉取时间
kubectl describe pod <pod-name> | grep -A2 "Events"
# 看 Pulling / Pulled 事件的时间差

# 2. 应用启动时间
kubectl logs <pod-name> --timestamps | head -20

# 3. 健康检查配置
kubectl describe pod <pod-name> | grep -A5 "Liveness\|Readiness\|Startup"
```

**优化方案**：
1. 使用小基础镜像（alpine / distroless）
2. 多阶段构建减小镜像体积
3. 配置 imagePullPolicy: IfNotPresent
4. 设置合理的 startupProbe（给应用足够启动时间）
5. 预热镜像（DaemonSet 预拉取）


path: references/cpu.md
content: # CPU 调优参考手册

## 目录
1. [快速诊断](#1-快速诊断)
2. [上下文切换优化](#2-上下文切换优化)
3. [CPU 调速与频率管理](#3-cpu-调速与频率管理)
4. [进程调度优化](#4-进程调度优化)
5. [CPU 亲和性与绑核](#5-cpu-亲和性与绑核)
6. [NUMA 优化](#6-numa-优化)
7. [中断绑核](#7-中断绑核)
8. [perf 性能剖析](#8-perf-性能剖析)
9. [容器 CPU 限制排查](#9-容器-cpu-限制排查)

---

## 1. 快速诊断

```bash
# 负载概览
uptime
cat /proc/loadavg

# 每核 CPU 使用率（1秒采样5次）
mpstat -P ALL 1 5

# 高 CPU 进程
top -bn1 | sort -k9 -rn | head -15
pidstat -u 1 5

# 上下文切换详情
vmstat 1 5          # 看 cs（上下文切换）和 r（运行队列）
pidstat -w 1 3      # 进程级上下文切换

# CPU 等待 I/O 分析
iostat -xz 1 3      # 看 %util 和 %iowait

# 调度延迟
perf sched latency 2>/dev/null | head -20
```

**关键指标解读：**
| 指标 | 正常范围 | 异常判断 |
|------|---------|---------|
| load1 / 核数 | < 0.7 | > 2.0 需关注 |
| vmstat r (运行队列) | ≤ 核数 | 持续 > 核数×2 严重 |
| vmstat cs (上下文切换/秒) | < 5万 | > 50万 需优化 |
| %iowait | < 5% | > 20% 为 I/O 瓶颈 |
| CPU %us + %sy | < 70% | > 90% 接近饱和 |

---

## 2. 上下文切换优化

```bash
# 查看当前调度器参数
sysctl kernel.sched_min_granularity_ns
sysctl kernel.sched_wakeup_granularity_ns
sysctl kernel.sched_migration_cost_ns

# 增大调度粒度，减少抢占频率（减少上下文切换）
sysctl -w kernel.sched_min_granularity_ns=10000000    # 10ms（默认3ms）
sysctl -w kernel.sched_wakeup_granularity_ns=15000000  # 15ms（默认4ms）
sysctl -w kernel.sched_migration_cost_ns=5000000       # 5ms（默认0.5ms）

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
kernel.sched_min_granularity_ns = 10000000
kernel.sched_wakeup_granularity_ns = 15000000
kernel.sched_migration_cost_ns = 5000000
EOF

# ⚠️ 副作用：增大粒度可能轻微增加交互响应延迟，桌面系统不建议调整
# 回滚：
sysctl -w kernel.sched_min_granularity_ns=3000000
sysctl -w kernel.sched_wakeup_granularity_ns=4000000
sysctl -w kernel.sched_migration_cost_ns=500000
```

---

## 3. CPU 调速与频率管理

```bash
# 查看当前调速策略
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | sort -u
cpupower frequency-info 2>/dev/null

# 切换为性能模式（关闭节能）
cpupower frequency-set -g performance 2>/dev/null || \
  for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
      echo performance > $cpu
  done

# 持久化（systemd）
cat > /etc/systemd/system/cpu-performance.service << 'EOF'
[Unit]
Description=Set CPU governor to performance
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c "for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > $f; done"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now cpu-performance.service

# 查看 CPU 当前频率
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq | awk '{s+=$1; n++} END {printf "平均: %.0f MHz\n", s/n/1000}'

# 检查 CPU 是否处于节能降频
grep "cpu MHz" /proc/cpuinfo | awk '{sum+=$4; n++} END {printf "当前频率均值: %.0f MHz\n", sum/n}'
```

---

## 4. 进程调度优化

```bash
# 查看进程调度策略
chrt -p <PID>

# 设置实时调度（延迟敏感服务）
chrt -f -p 50 <PID>    # SCHED_FIFO，优先级50
chrt -r -p 50 <PID>    # SCHED_RR，优先级50

# 调整 nice 值（普通进程）
renice -5 -p <PID>     # 提高优先级（-20最高）
renice +10 -p <PID>    # 降低优先级（+19最低）

# 启动时设置 nice 值
nice -n -5 command

# 使用 cgroups 限制进程 CPU 使用（非容器场景）
cgcreate -g cpu:/limited_group
echo 50000 > /sys/fs/cgroup/cpu/limited_group/cpu.cfs_quota_us    # 50% CPU
cgclassify -g cpu:/limited_group <PID>

# cpulimit（简单方式）
cpulimit -p <PID> -l 50 &    # 限制50%
```

---

## 5. CPU 亲和性与绑核

```bash
# 查看进程当前 CPU 亲和性
taskset -p <PID>

# 将进程绑定到 CPU 0-3
taskset -cp 0-3 <PID>

# 启动时绑核
taskset -c 0-3 ./my_app

# 查看各 CPU 负载分布
mpstat -P ALL 1 1 | grep -v "^$\|^Linux\|^CPU\|Average" | awk '{print "CPU"$2": "$NF"%"}'

# NUMA 感知绑核（同时绑 CPU + 内存）
numactl --cpunodebind=0 --membind=0 ./my_app

# 查看 NUMA 节点上的进程
ps -eo pid,psr,comm | head -20   # psr=当前运行的CPU核
```

---

## 6. NUMA 优化

```bash
# 查看 NUMA 拓扑
numactl --hardware
lstopo 2>/dev/null

# 查看 NUMA 内存统计（命中率）
numastat -m 2>/dev/null
numastat -p <PID> 2>/dev/null

# 关闭自动 NUMA 均衡（减少进程迁移，降低延迟）
sysctl -w kernel.numa_balancing=0

# 开启（多 NUMA 节点服务器建议保持开启）
sysctl -w kernel.numa_balancing=1

# 查看 NUMA miss 率（高miss率说明跨节点访存）
numastat | grep -E "numa_miss|numa_foreign"

# 进程 NUMA 策略
numactl --preferred=0 ./app        # 优先使用节点0的内存
numactl --interleave=all ./app     # 内存在所有节点交错分配（适合大内存均匀访问）
```

---

## 7. 中断绑核

```bash
# 查看中断分布
cat /proc/interrupts | head -30

# 查看网卡中断
grep eth0 /proc/interrupts

# 关闭 irqbalance（手动管理时）
systemctl stop irqbalance
systemctl disable irqbalance

# 将网卡中断绑定到指定 CPU（以 eth0 为例）
# 找到网卡的中断号
NIC_IRQ=$(grep eth0 /proc/interrupts | awk -F: '{print $1}' | tr -d ' ')
# 绑定到 CPU2（bitmask: 4 = 00000100）
echo 4 > /proc/irq/${NIC_IRQ}/smp_affinity

# 多队列网卡绑核（自动脚本）
set_irq_affinity() {
    local nic=$1
    local irq_list=($(grep ${nic} /proc/interrupts | awk -F: '{print $1}' | tr -d ' '))
    local cpu_list=(0 1 2 3 4 5 6 7)  # 绑定到前8核
    for i in "${!irq_list[@]}"; do
        local cpu_mask=$((1 << ${cpu_list[$i % ${#cpu_list[@]}]}))
        printf "%x\n" $cpu_mask > /proc/irq/${irq_list[$i]}/smp_affinity
    done
}
# set_irq_affinity eth0
```

---

## 8. perf 性能剖析

```bash
# 安装 perf
apt install linux-perf 2>/dev/null || yum install perf 2>/dev/null

# 全系统 CPU 热点采样（10秒）
perf top

# 对指定进程采样
perf top -p <PID>

# 记录性能数据（30秒）
perf record -g -a -F 99 -- sleep 30
perf report --stdio | head -50

# CPU 硬件事件统计
perf stat -e cycles,instructions,cache-misses,cache-references,branch-misses -a sleep 10
# 重点指标：
# IPC (instructions/cycles) < 1.0 说明 CPU 利用率低（可能内存延迟）
# cache-miss率 > 5% 说明缓存命中差
# branch-misses率 > 3% 说明分支预测差

# 查看热点函数（火焰图准备）
perf record -g -p <PID> -- sleep 30
perf script > perf.data.txt
# 使用 FlameGraph 工具生成火焰图（需要安装 FlameGraph）
# git clone https://github.com/brendangregg/FlameGraph
# perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > flame.svg

# 调度延迟分析
perf sched record -- sleep 10
perf sched latency | head -30

# 系统调用统计
perf stat -e syscalls:sys_enter_read,syscalls:sys_enter_write -p <PID> sleep 5
strace -c -p <PID>   # 更简单的系统调用统计
```

---

## 9. 容器 CPU 限制排查

```bash
# 查看当前容器 CPU 配额
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us    # -1 表示不限制
cat /sys/fs/cgroup/cpu/cpu.cfs_period_us   # 通常 100000 (100ms)

# 计算 CPU 限制核数
# quota / period = CPU 核数限制
# 例：quota=200000, period=100000 → 2核

# 查看 CPU throttling（被限制次数）
cat /sys/fs/cgroup/cpu/cpu.stat
# nr_throttled 持续增长说明 CPU 经常被限制

# Kubernetes 中检查 throttling
kubectl exec <pod> -- cat /sys/fs/cgroup/cpu/cpu.stat
kubectl describe pod <pod> | grep -A5 "Limits\|Requests"
kubectl top pod <pod> --containers

# 判断是否需要提高 CPU limit
# throttled_time (纳秒) / 总运行时间 > 5% 建议扩容
```


path: references/c_cpp_performance.md
content: # C/C++ 性能分析与优化指南

> C/C++ 作为系统级编程语言，直接操控硬件资源，拥有最丰富的性能分析工具链（perf、Valgrind、Sanitizers、Intel VTune）。本文档覆盖 C/C++ 性能分析工具链、编译优化、内存管理、并发优化及生产环境最佳实践。

---


## 目录

- [1. 性能分析工具链](#1-性能分析工具链)
- [2. 编译优化](#2-编译优化)
- [3. 内存管理优化](#3-内存管理优化)
- [4. 并发与多线程优化](#4-并发与多线程优化)
- [5. 常见性能陷阱与优化模式](#5-常见性能陷阱与优化模式)
- [6. I/O 优化](#6-io-优化)
- [7. 生产环境最佳实践](#7-生产环境最佳实践)
- [8. C++ 特有优化技巧](#8-c-特有优化技巧)
- [9. 调优工作流总结](#9-调优工作流总结)
## 1. 性能分析工具链

### 1.1 perf（Linux 首选 CPU 分析器）

```bash
# 编译时保留调试符号（不影响优化等级）
gcc -O2 -g -o myapp myapp.c
g++ -O2 -g -o myapp myapp.cpp

# CPU 采样（30秒）
perf record -g --call-graph dwarf -p <PID> -- sleep 30

# 查看热点函数
perf report --sort=dso,symbol

# 硬件计数器分析
perf stat -e cycles,instructions,cache-references,cache-misses,branch-misses,L1-dcache-load-misses -p <PID> -- sleep 10

# 生成火焰图
perf script | stackcollapse-perf.pl | flamegraph.pl > flamegraph.svg

# 按函数注解源码热点
perf annotate -s <symbol_name>
```

**perf 关键指标解读：**
| 指标 | 含义 | 异常阈值 |
|------|------|----------|
| IPC (instructions/cycle) | 每周期执行指令数 | < 1.0 说明流水线效率低 |
| cache-miss rate | 缓存未命中率 | > 5% 需优化数据布局 |
| branch-miss rate | 分支预测失败率 | > 3% 需优化分支逻辑 |
| L1-dcache-load-misses | L1 数据缓存未命中 | 高值说明数据局部性差 |

### 1.2 Valgrind 工具套件

```bash
# Callgrind — CPU 分析（精确但慢 20-50x）
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./myapp
kcachegrind callgrind.out  # GUI 分析

# Memcheck — 内存错误检测
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --track-origins=yes ./myapp

# Massif — 堆内存分析
valgrind --tool=massif --pages-as-heap=yes ./myapp
ms_print massif.out.<PID>

# Cachegrind — 缓存模拟分析
valgrind --tool=cachegrind ./myapp
cg_annotate cachegrind.out.<PID>

# DHAT — 动态堆分析（Valgrind 3.18+）
valgrind --tool=dhat ./myapp
# 在浏览器打开 dhat-out 文件分析
```

**Valgrind 工具选择：**
| 工具 | 用途 | 开销 | 适用场景 |
|------|------|------|----------|
| Memcheck | 内存错误/泄漏 | 20-50x | 开发/CI 阶段必用 |
| Callgrind | 函数级 CPU 分析 | 20-50x | 精确定位热点函数 |
| Massif | 堆内存使用分析 | 10-20x | 内存占用过高 |
| Cachegrind | 缓存行为分析 | 20-50x | 缓存未命中率高 |
| DHAT | 堆分配模式分析 | 10x | 分配过频/短生命周期对象 |

### 1.3 Sanitizers（编译器内置，推荐）

```bash
# AddressSanitizer（ASan）— 内存错误检测（2x 开销，比 Valgrind 快 10 倍）
gcc -fsanitize=address -fno-omit-frame-pointer -g -O1 -o myapp myapp.c
# 或
clang -fsanitize=address -fno-omit-frame-pointer -g -O1 -o myapp myapp.c

# ASan 检测能力：
# - 堆缓冲区溢出（heap-buffer-overflow）
# - 栈缓冲区溢出（stack-buffer-overflow）
# - 全局缓冲区溢出（global-buffer-overflow）
# - use-after-free
# - use-after-return
# - double-free
# - 内存泄漏（leak）

# ThreadSanitizer（TSan）— 数据竞争检测
gcc -fsanitize=thread -g -O1 -o myapp myapp.c -lpthread

# UndefinedBehaviorSanitizer（UBSan）— 未定义行为检测
gcc -fsanitize=undefined -g -O1 -o myapp myapp.c

# MemorySanitizer（MSan）— 未初始化内存读取（仅 Clang）
clang -fsanitize=memory -fno-omit-frame-pointer -g -O1 -o myapp myapp.c

# 组合使用（ASan + UBSan）
gcc -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -o myapp myapp.c
```

**Sanitizer 选择指南：**
| Sanitizer | 检测目标 | 运行时开销 | 编译器支持 |
|-----------|----------|------------|------------|
| ASan | 内存越界/UAF/泄漏 | 2x | GCC/Clang |
| TSan | 数据竞争 | 5-15x | GCC/Clang |
| UBSan | 未定义行为 | < 1.5x | GCC/Clang |
| MSan | 未初始化内存读 | 3x | 仅 Clang |

> ⚠️ ASan 与 TSan 不能同时使用；ASan 与 MSan 不能同时使用。

### 1.4 gperftools（Google Performance Tools）

```bash
# 安装
apt install google-perftools libgoogle-perftools-dev  # Debian/Ubuntu
yum install gperftools gperftools-devel                # CentOS/RHEL

# CPU Profiler
LD_PRELOAD=/usr/lib/libprofiler.so CPUPROFILE=cpu.prof ./myapp
google-pprof --text ./myapp cpu.prof          # 文本报告
google-pprof --svg ./myapp cpu.prof > cpu.svg # SVG 火焰图
google-pprof --web ./myapp cpu.prof           # 浏览器查看

# Heap Profiler
LD_PRELOAD=/usr/lib/libtcmalloc.so HEAPPROFILE=heap.prof ./myapp
google-pprof --text ./myapp heap.prof.0001.heap

# tcmalloc 替换 glibc malloc（性能提升显著）
LD_PRELOAD=/usr/lib/libtcmalloc_minimal.so ./myapp
```

### 1.5 Intel VTune / AMD uProf

```bash
# Intel VTune（性能分析黄金标准）
vtune -collect hotspots -result-dir=r001hs ./myapp
vtune -collect memory-access -result-dir=r001mem ./myapp
vtune -collect threading -result-dir=r001thr ./myapp

# AMD uProf
AMDuProfCLI collect --config tbp -o /tmp/prof ./myapp
AMDuProfCLI report -i /tmp/prof
```

---

## 2. 编译优化

### 2.1 GCC/Clang 优化等级

```bash
# 优化等级对比
-O0  # 无优化（调试用）
-O1  # 基础优化（编译快，适合开发）
-O2  # 推荐生产级优化（安全、稳定、效果好）
-O3  # 激进优化（循环向量化、函数内联更激进）
-Os  # 优化代码体积（嵌入式/缓存敏感场景）
-Ofast  # -O3 + 非标准浮点优化（-ffast-math），科学计算可用

# 推荐生产编译选项
gcc -O2 -march=native -flto -DNDEBUG -o myapp myapp.c

# 高性能场景
gcc -O3 -march=native -mtune=native -flto -funroll-loops \
    -fomit-frame-pointer -DNDEBUG -o myapp myapp.c
```

### 2.2 链接时优化（LTO）

```bash
# GCC LTO
gcc -O2 -flto -c module1.c -o module1.o
gcc -O2 -flto -c module2.c -o module2.o
gcc -O2 -flto module1.o module2.o -o myapp

# Clang ThinLTO（并行 LTO，大项目推荐）
clang -O2 -flto=thin -c module1.c -o module1.o
clang -O2 -flto=thin module1.o module2.o -o myapp

# CMake 启用 LTO
cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON ..
```

### 2.3 Profile-Guided Optimization (PGO)

```bash
# 第一步：编译插桩版本
gcc -O2 -fprofile-generate -o myapp_instrumented myapp.c

# 第二步：运行典型工作负载
./myapp_instrumented < typical_input.txt

# 第三步：使用 profile 数据重新编译
gcc -O2 -fprofile-use -o myapp_optimized myapp.c

# Clang PGO（使用 LLVM IR profiling）
clang -O2 -fprofile-instr-generate -o myapp_instr myapp.c
./myapp_instr < typical_input.txt
llvm-profdata merge -output=default.profdata default.profraw
clang -O2 -fprofile-instr-use=default.profdata -o myapp_opt myapp.c
```

> 💡 PGO 通常可带来 **10-30%** 的性能提升，特别适合分支密集型代码。

### 2.4 SIMD 向量化

```bash
# 自动向量化（GCC/Clang -O2 以上默认开启）
gcc -O2 -ftree-vectorize -fopt-info-vec-optimized myapp.c  # 查看向量化报告

# 手动指定 SIMD 指令集
gcc -O2 -mavx2 -mfma myapp.c        # AVX2 + FMA
gcc -O2 -mavx512f myapp.c           # AVX-512
gcc -O2 -march=native myapp.c       # 自动检测本机最佳指令集

# Clang 向量化报告
clang -O2 -Rpass=loop-vectorize -Rpass-missed=loop-vectorize myapp.c
```

**C/C++ SIMD 内建函数（Intrinsics）：**
```c
#include <immintrin.h>

// AVX2 示例：8 个 float 并行加法
void add_arrays_avx2(float* a, float* b, float* c, int n) {
    for (int i = 0; i < n; i += 8) {
        __m256 va = _mm256_loadu_ps(a + i);
        __m256 vb = _mm256_loadu_ps(b + i);
        __m256 vc = _mm256_add_ps(va, vb);
        _mm256_storeu_ps(c + i, vc);
    }
}
```

---

## 3. 内存管理优化

### 3.1 内存分配器选择

```bash
# glibc malloc（默认）
# 适合通用场景，但多线程下锁竞争严重

# tcmalloc（Google，推荐多线程场景）
LD_PRELOAD=/usr/lib/libtcmalloc.so ./myapp
# 线程本地缓存，减少锁竞争，碎片控制好

# jemalloc（Facebook，推荐长时间运行服务）
LD_PRELOAD=/usr/lib/libjemalloc.so ./myapp
# 碎片控制最优，支持 heap profiling
# 设置 jemalloc 分析
MALLOC_CONF="prof:true,prof_prefix:jeprof.out" LD_PRELOAD=/usr/lib/libjemalloc.so ./myapp
jeprof --svg ./myapp jeprof.out.*.heap > heap.svg

# mimalloc（Microsoft，高性能通用分配器）
LD_PRELOAD=/usr/lib/libmimalloc.so ./myapp
```

**分配器对比：**
| 分配器 | 多线程性能 | 碎片控制 | 诊断能力 | 适用场景 |
|--------|-----------|----------|----------|----------|
| glibc malloc | 一般 | 一般 | 弱 | 通用默认 |
| tcmalloc | 优秀 | 良好 | 强（heap prof） | 多线程服务 |
| jemalloc | 优秀 | 最优 | 强（heap prof） | 长运行服务（Redis/Nginx） |
| mimalloc | 最优 | 良好 | 中 | 高吞吐场景 |

### 3.2 内存池与对象池

```cpp
// 简单内存池（固定大小块）
class MemoryPool {
    struct Block { Block* next; };
    Block* free_list_ = nullptr;
    std::vector<void*> chunks_;
    size_t block_size_;
    size_t chunk_size_;

public:
    MemoryPool(size_t block_size, size_t chunk_blocks = 1024)
        : block_size_(std::max(block_size, sizeof(Block)))
        , chunk_size_(chunk_blocks) {
        grow();
    }

    void* allocate() {
        if (!free_list_) grow();
        Block* block = free_list_;
        free_list_ = block->next;
        return block;
    }

    void deallocate(void* ptr) {
        auto* block = static_cast<Block*>(ptr);
        block->next = free_list_;
        free_list_ = block;
    }

private:
    void grow() {
        char* chunk = new char[block_size_ * chunk_size_];
        chunks_.push_back(chunk);
        for (size_t i = 0; i < chunk_size_; ++i) {
            auto* block = reinterpret_cast<Block*>(chunk + i * block_size_);
            block->next = free_list_;
            free_list_ = block;
        }
    }
};
```

### 3.3 缓存友好的数据结构

```cpp
// ❌ AoS（Array of Structures）— 缓存不友好
struct Particle_AoS {
    float x, y, z;       // 位置
    float vx, vy, vz;    // 速度
    float mass;
    int type;
    // ... 更多字段
};
std::vector<Particle_AoS> particles; // 遍历位置时加载大量无用数据

// ✅ SoA（Structure of Arrays）— 缓存友好
struct Particles_SoA {
    std::vector<float> x, y, z;       // 位置连续存储
    std::vector<float> vx, vy, vz;    // 速度连续存储
    std::vector<float> mass;
    std::vector<int> type;
};
// 遍历位置时只加载 x/y/z，缓存命中率极高

// ✅ 热/冷数据分离
struct Entity_Hot {
    float x, y, z;     // 每帧都访问
    float health;
};
struct Entity_Cold {
    std::string name;   // 很少访问
    std::string model;
    int creation_time;
};
```

### 3.4 避免常见内存陷阱

```cpp
// ❌ 频繁 new/delete 小对象
for (int i = 0; i < 1000000; ++i) {
    auto* obj = new SmallObj();
    process(obj);
    delete obj;
}

// ✅ 预分配 + 对象复用
std::vector<SmallObj> pool(1000000);
for (auto& obj : pool) {
    process(&obj);
}

// ❌ std::map（红黑树，缓存不友好）
std::map<int, Value> m;

// ✅ 小规模用 sorted vector，大规模用 flat_map 或 robin_map
// boost::container::flat_map 或 absl::flat_hash_map
absl::flat_hash_map<int, Value> m;

// ❌ std::list（链表，缓存极不友好）
std::list<int> lst;

// ✅ std::vector（连续内存）
std::vector<int> vec;

// 内存对齐（避免 false sharing）
struct alignas(64) ThreadData {
    uint64_t counter;
    // padding 到 cache line 大小
};
```

---

## 4. 并发与多线程优化

### 4.1 锁优化

```cpp
// ❌ 粗粒度锁
std::mutex global_mutex;
void process(Data& data) {
    std::lock_guard<std::mutex> lock(global_mutex);
    // 所有操作都在锁内
}

// ✅ 细粒度锁 + 分段锁
static constexpr int NUM_SHARDS = 64;
struct Shard {
    std::mutex mutex;
    std::unordered_map<Key, Value> data;
} shards[NUM_SHARDS];

void process(const Key& key, const Value& val) {
    auto& shard = shards[hash(key) % NUM_SHARDS];
    std::lock_guard<std::mutex> lock(shard.mutex);
    shard.data[key] = val;
}

// ✅ 读写锁（读多写少场景）
std::shared_mutex rw_mutex;
Value read(const Key& key) {
    std::shared_lock lock(rw_mutex);  // 并发读
    return data[key];
}
void write(const Key& key, Value val) {
    std::unique_lock lock(rw_mutex);  // 独占写
    data[key] = std::move(val);
}

// ✅ 无锁数据结构（高竞争场景）
std::atomic<uint64_t> counter{0};
counter.fetch_add(1, std::memory_order_relaxed);
```

### 4.2 避免 False Sharing

```cpp
// ❌ False Sharing（不同线程修改同一缓存行的不同变量）
struct SharedData {
    uint64_t counter_a;  // 线程 A 修改
    uint64_t counter_b;  // 线程 B 修改 — 同一缓存行！
};

// ✅ 缓存行对齐
struct alignas(64) PaddedCounter {
    uint64_t value;
};
PaddedCounter counters[NUM_THREADS];

// C++17 hardware_destructive_interference_size
struct alignas(std::hardware_destructive_interference_size) Counter {
    std::atomic<uint64_t> value{0};
};
```

### 4.3 线程池模式

```cpp
// 高性能线程池（C++17）
#include <thread>
#include <queue>
#include <functional>
#include <condition_variable>

class ThreadPool {
    std::vector<std::thread> workers_;
    std::queue<std::function<void()>> tasks_;
    std::mutex mutex_;
    std::condition_variable cv_;
    bool stop_ = false;

public:
    ThreadPool(size_t threads = std::thread::hardware_concurrency()) {
        for (size_t i = 0; i < threads; ++i) {
            workers_.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock lock(mutex_);
                        cv_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
                        if (stop_ && tasks_.empty()) return;
                        task = std::move(tasks_.front());
                        tasks_.pop();
                    }
                    task();
                }
            });
        }
    }

    template<class F>
    void submit(F&& f) {
        {
            std::lock_guard lock(mutex_);
            tasks_.emplace(std::forward<F>(f));
        }
        cv_.notify_one();
    }

    ~ThreadPool() {
        { std::lock_guard lock(mutex_); stop_ = true; }
        cv_.notify_all();
        for (auto& w : workers_) w.join();
    }
};
```

---

## 5. 常见性能陷阱与优化模式

### 5.1 字符串优化

```cpp
// ❌ 频繁字符串拼接
std::string result;
for (const auto& s : strings) {
    result += s;  // 每次可能重新分配
}

// ✅ 预留空间
std::string result;
size_t total = 0;
for (const auto& s : strings) total += s.size();
result.reserve(total);
for (const auto& s : strings) result += s;

// ✅ SSO（Small String Optimization）
// std::string 通常内联存储 <= 22 字节（GCC）或 <= 15 字节（Clang）的短字符串
// 短字符串无需堆分配

// ✅ std::string_view（C++17，零拷贝）
void process(std::string_view sv) {  // 不拷贝，不分配
    // ...
}
```

### 5.2 容器选择指南

| 场景 | 推荐容器 | 原因 |
|------|----------|------|
| 顺序访问/遍历 | `std::vector` | 连续内存，缓存友好 |
| 频繁尾部插入/删除 | `std::vector` / `std::deque` | 摊销 O(1) |
| 频繁中间插入/删除 | `std::list`（大元素）/ `std::vector`（小元素） | 小元素 vector 移动比 list 快 |
| 快速查找（有序） | `std::vector` + `std::lower_bound` | 缓存友好 |
| 快速查找（无序） | `absl::flat_hash_map` / `std::unordered_map` | O(1) 平均 |
| 优先队列 | `std::priority_queue` | 堆结构 |
| 小集合（< 100 元素） | `std::vector` + 线性搜索 | 缓存行效应优于树/哈希 |

### 5.3 移动语义与拷贝消除

```cpp
// ✅ 使用移动语义避免拷贝
std::vector<std::string> build_strings() {
    std::vector<std::string> result;
    result.reserve(1000);
    for (int i = 0; i < 1000; ++i) {
        result.emplace_back(std::to_string(i));  // 原地构造
    }
    return result;  // NRVO，零拷贝返回
}

// ✅ 完美转发
template<typename... Args>
void emplace(Args&&... args) {
    container.emplace_back(std::forward<Args>(args)...);
}

// ❌ 不必要的拷贝
void process(std::vector<int> data);    // 拷贝
// ✅
void process(const std::vector<int>& data);  // 只读引用
void process(std::vector<int>&& data);       // 移动
```

### 5.4 编译期计算（constexpr / 模板元编程）

```cpp
// ✅ constexpr 编译期计算（C++17/20）
constexpr uint64_t fibonacci(int n) {
    if (n <= 1) return n;
    uint64_t a = 0, b = 1;
    for (int i = 2; i <= n; ++i) {
        uint64_t c = a + b;
        a = b;
        b = c;
    }
    return b;
}
constexpr auto fib50 = fibonacci(50);  // 编译期计算，运行时零开销

// ✅ if constexpr（C++17，编译期分支消除）
template<typename T>
void serialize(const T& val) {
    if constexpr (std::is_arithmetic_v<T>) {
        write_binary(val);    // 数值类型：二进制写入
    } else if constexpr (std::is_same_v<T, std::string>) {
        write_string(val);    // 字符串：长度前缀 + 内容
    } else {
        val.serialize(*this); // 自定义类型：调用成员函数
    }
}
```

---

## 6. I/O 优化

### 6.1 文件 I/O

```cpp
// ❌ 逐字节/逐行读取
while (fgetc(fp) != EOF) { ... }

// ✅ 批量读取
constexpr size_t BUF_SIZE = 64 * 1024;  // 64KB 缓冲
char buffer[BUF_SIZE];
while (size_t n = fread(buffer, 1, BUF_SIZE, fp)) {
    process(buffer, n);
}

// ✅ mmap（大文件随机访问）
int fd = open("data.bin", O_RDONLY);
struct stat st;
fstat(fd, &st);
void* data = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
madvise(data, st.st_size, MADV_SEQUENTIAL);  // 提示内核预读
// ... 直接访问 data
munmap(data, st.st_size);
close(fd);

// ✅ io_uring（Linux 5.1+，异步 I/O 最佳方案）
// 使用 liburing 简化接口
#include <liburing.h>
struct io_uring ring;
io_uring_queue_init(256, &ring, 0);
// ... 提交读写请求
```

### 6.2 网络 I/O

```cpp
// ✅ epoll（Linux 高性能事件驱动）
int epfd = epoll_create1(0);
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN | EPOLLET;  // 边缘触发
ev.data.fd = listen_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev);

while (true) {
    int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
    for (int i = 0; i < n; ++i) {
        if (events[i].data.fd == listen_fd) {
            accept_connection();
        } else {
            handle_data(events[i].data.fd);
        }
    }
}

// ✅ io_uring 网络（Linux 5.6+，性能优于 epoll）
// 零拷贝发送（sendmsg + MSG_ZEROCOPY）
setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one));
```

---

## 7. 生产环境最佳实践

### 7.1 编译检查清单

```bash
# 生产构建推荐
CFLAGS="-O2 -march=native -flto -DNDEBUG -fstack-protector-strong -D_FORTIFY_SOURCE=2"
CXXFLAGS="$CFLAGS -std=c++17"

# CI/测试构建推荐
CFLAGS="-O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer"

# 安全加固选项
-fstack-protector-strong    # 栈溢出保护
-D_FORTIFY_SOURCE=2         # 缓冲区溢出检测
-fPIE -pie                  # 地址空间随机化
-Wl,-z,relro,-z,now         # GOT 保护
```

### 7.2 性能监控与诊断

```bash
# 运行时性能快照
perf top -p <PID>                           # 实时热点
perf record -g -p <PID> -- sleep 30         # 30秒采样
strace -c -p <PID>                          # 系统调用统计
ltrace -c -p <PID>                          # 库调用统计

# 内存泄漏持续监控
# 方法1：/proc/<PID>/smaps 监控 RSS 增长
while true; do
    grep -E "^(Rss|Pss)" /proc/<PID>/smaps | awk '{sum+=$2} END {print sum " kB"}'
    sleep 60
done

# 方法2：jemalloc heap profiling
MALLOC_CONF="prof:true,prof_interval:1073741824" LD_PRELOAD=libjemalloc.so ./myapp

# Core dump 分析
ulimit -c unlimited
gdb ./myapp core.<PID>
(gdb) bt        # 查看崩溃调用栈
(gdb) info threads  # 查看所有线程
```

### 7.3 常见性能问题速查表

| 症状 | 可能原因 | 诊断工具 | 优化方向 |
|------|----------|----------|----------|
| CPU 100% 单核 | 死循环/自旋锁 | perf top, strace | 代码审查/锁优化 |
| 多线程 CPU 利用率低 | 锁竞争/false sharing | perf lock, TSan | 分段锁/缓存行对齐 |
| RSS 持续增长 | 内存泄漏 | ASan, Valgrind, jemalloc prof | 修复泄漏/换分配器 |
| 高 cache-miss | 数据局部性差 | perf stat, Cachegrind | SoA/热冷分离/预取 |
| 高 page-fault | mmap 大量小文件/内存碎片 | perf stat | 预分配/hugepages |
| 系统调用过多 | I/O 未批量化 | strace -c | 批量读写/mmap/io_uring |
| 启动慢 | 动态链接/大量初始化 | perf record | 延迟初始化/静态链接 |
| 高分支预测失败 | 条件分支不可预测 | perf stat | 分支消除/查表/CMOV |

---

## 8. C++ 特有优化技巧

### 8.1 虚函数开销与替代方案

```cpp
// ❌ 虚函数（间接调用，阻碍内联和向量化）
class Shape {
    virtual double area() const = 0;
};

// ✅ CRTP（编译期多态，零开销）
template<typename Derived>
class Shape {
public:
    double area() const {
        return static_cast<const Derived*>(this)->area_impl();
    }
};
class Circle : public Shape<Circle> {
    double area_impl() const { return M_PI * r_ * r_; }
};

// ✅ std::variant + std::visit（C++17，类型安全的联合体）
using ShapeVar = std::variant<Circle, Rectangle, Triangle>;
double area(const ShapeVar& shape) {
    return std::visit([](const auto& s) { return s.area(); }, shape);
}
```

### 8.2 异常处理开销

```cpp
// 异常的零开销模型（GCC/Clang）：
// - 不抛异常时：零运行时开销（但增加代码体积）
// - 抛异常时：开销极大（栈展开）
// 高性能路径避免使用异常

// ✅ 使用 std::expected（C++23）或自定义 Result 类型
template<typename T, typename E = std::string>
class Result {
    std::variant<T, E> data_;
public:
    bool ok() const { return std::holds_alternative<T>(data_); }
    T& value() { return std::get<T>(data_); }
    E& error() { return std::get<E>(data_); }
};

// 禁用异常（嵌入式/游戏引擎常见）
// gcc -fno-exceptions -fno-rtti
```

---

## 9. 调优工作流总结

```text
1. 确定目标 → 明确性能指标（延迟/吞吐/内存）
2. 建立基线 → perf stat / time / benchmark
3. 找到瓶颈 → perf record + 火焰图
4. 分析根因 →
   ├── CPU 密集 → 算法优化/SIMD/编译优化
   ├── 内存瓶颈 → 缓存友好布局/分配器/内存池
   ├── I/O 瓶颈 → 批量化/mmap/io_uring
   └── 并发瓶颈 → 锁优化/无锁/线程池
5. 实施优化 → 一次只改一个变量
6. 验证效果 → 回归基线对比
7. 重复迭代 → 直到达标
```

> ⚡ **黄金法则**：先 profiling，再优化。不要凭直觉猜测瓶颈——90% 的时间花在 10% 的代码上。


path: references/disk_io.md
content: # 磁盘 I/O 调优参考手册

## 目录
1. [快速诊断](#1-快速诊断)
2. [I/O 调度器选择](#2-io-调度器选择)
3. [读预读优化](#3-读预读优化)
4. [脏页回写（与内存联动）](#4-脏页回写)
5. [文件系统挂载优化](#5-文件系统挂载优化)
6. [磁盘队列深度](#6-磁盘队列深度)
7. [fio 性能测试](#7-fio-性能测试)
8. [NVMe/SSD 专项优化](#8-nvmessd-专项优化)
9. [RAID 与 LVM 优化](#9-raid-与-lvm-优化)
10. [磁盘健康监控](#10-磁盘健康监控)

---

## 1. 快速诊断

```bash
# I/O 实时统计（关键指标：%util, await, r/s, w/s）
iostat -xz 1 5

# 找 I/O 密集进程
iotop -o -b -n 3 | head -20
pidstat -d 1 5

# 查看磁盘等待进程
ps aux | awk '$8 ~ /D/ {print $0}'

# 磁盘空间
df -h
du -sh /* 2>/dev/null | sort -rh | head -20

# 当前 I/O 调度器
for d in /sys/block/*/queue/scheduler; do
    echo "$(basename $(dirname $(dirname $d))): $(cat $d)"
done

# 检查文件系统挂载选项
mount | grep -v 'tmpfs\|proc\|sys\|dev\|cgroup'
```

**iostat 关键指标解读：**
| 指标 | 正常范围 | 告警阈值 |
|------|---------|---------|
| %util | < 60% | > 80% 接近饱和 |
| await (ms) | HDD<20ms, SSD<5ms | > 50ms 严重 |
| r_await | HDD<20ms, SSD<2ms | 参考 await |
| w_await | HDD<20ms, SSD<2ms | 参考 await |
| svctm (ms) | **已废弃** | 不要参考，新版 iostat 已移除 |
| avgqu-sz | < 队列深度 | > 32 可能拥堵 |

---

## 2. I/O 调度器选择

```bash
# 查看可用调度器
cat /sys/block/sda/queue/scheduler
# [mq-deadline] none kyber bfq

# 设置调度器
echo mq-deadline > /sys/block/sda/queue/scheduler

# 调度器选择指南：
# ┌─────────────┬──────────────────────────────────────┐
# │ 调度器      │ 适用场景                              │
# ├─────────────┼──────────────────────────────────────┤
# │ none        │ NVMe SSD、虚拟机磁盘（依赖宿主调度）  │
# │ mq-deadline │ 通用 SSD、混合读写、数据库             │
# │ bfq         │ HDD、桌面系统、多进程公平 I/O          │
# │ kyber       │ 低延迟 SSD/NVMe                       │
# └─────────────┴──────────────────────────────────────┘

# 持久化（udev 规则，推荐）
cat > /etc/udev/rules.d/60-ioscheduler.rules << 'EOF'
# NVMe SSD
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
# SATA SSD
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
# HDD
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
EOF
udevadm control --reload-rules && udevadm trigger

# 验证
cat /sys/block/sda/queue/scheduler   # 确认调度器已切换

# 回滚
echo none > /sys/block/sda/queue/scheduler
```

---

## 3. 读预读优化

```bash
# 查看当前预读设置（KB）
blockdev --getra /dev/sda
cat /sys/block/sda/queue/read_ahead_kb

# 调整建议：
# 随机读（数据库）：128~512KB（较小，减少无效预读）
# 顺序读（日志/流媒体）：2048~8192KB（较大，减少 I/O 次数）
blockdev --setra 4096 /dev/sda   # 2MB (单位512字节，4096×512=2MB)
echo 2048 > /sys/block/sda/queue/read_ahead_kb  # 直接设置KB

# 持久化
cat > /etc/rc.local << 'EOF'
#!/bin/bash
blockdev --setra 4096 /dev/sda
EOF
chmod +x /etc/rc.local

# 验证效果（顺序读性能对比）
dd if=/dev/sda of=/dev/null bs=1M count=1024 2>&1 | tail -1
# 调整前后对比 MB/s
```

---

## 4. 脏页回写

> 与内存章节 references/memory.md 第6节联动

```bash
# 写密集型服务（防止脏页积累导致 I/O 尖峰）
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_expire_centisecs=1500   # 15秒强制刷盘
sysctl -w vm.dirty_writeback_centisecs=300  # 3秒唤醒回写线程

# 高吞吐批量写（允许积累更多，减少 I/O 频率）
sysctl -w vm.dirty_bytes=536870912         # 512MB 触发阻塞
sysctl -w vm.dirty_background_bytes=134217728  # 128MB 触发后台回写

# 监控脏页实时情况
watch -n 1 'grep -E "Dirty|Writeback" /proc/meminfo'
```

---

## 5. 文件系统挂载优化

```bash
# 查看当前挂载选项
mount | grep "^/dev"

# ext4 优化挂载选项
# /etc/fstab 示例：
# /dev/sdb1 /data ext4 noatime,nodiratime,data=writeback,barrier=0 0 2
# noatime：禁用访问时间记录（减少写操作）
# nodiratime：禁用目录访问时间
# data=writeback：写回模式（性能最好，但断电可能数据不一致）
# barrier=0：关闭写屏障（有 UPS 时可开启，有数据丢失风险）

# XFS 优化挂载选项
# /dev/vdb1 /data xfs noatime,nodiratime,logbufs=8,logbsize=256k 0 2

# Btrfs 优化挂载选项
# /dev/vdc1 /data btrfs noatime,compress=zstd:1,space_cache=v2 0 2
# compress=zstd:1：压缩比和性能平衡

# 临时重新挂载（不重启）
mount -o remount,noatime /data

# 检查文件系统碎片
e2fsck -n /dev/sda1 2>/dev/null | grep "non-contiguous"   # ext4
xfs_db -c frag -r /dev/sdb1 2>/dev/null                   # XFS
```

---

## 6. 磁盘队列深度

```bash
# 查看队列深度
cat /sys/block/sda/queue/nr_requests
cat /sys/block/sda/queue/queue_depth   # NVMe

# 调整队列深度
# HDD：64~128（过大会增加延迟）
# SSD：128~256
# NVMe：256~1024
echo 256 > /sys/block/sda/queue/nr_requests

# 持久化（udev 规则）
cat >> /etc/udev/rules.d/60-ioscheduler.rules << 'EOF'
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/nr_requests}="256"
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/nr_requests}="1024"
EOF

# 检查是否有 I/O 合并（相邻请求合并）
cat /sys/block/sda/queue/nomerges   # 0=开启合并（默认）
```

---

## 7. fio 性能测试

```bash
# 安装 fio
apt install fio 2>/dev/null || yum install fio 2>/dev/null

# 顺序读测试（大文件，测试吞吐量）
fio --name=seq-read --ioengine=libaio --iodepth=32 \
    --rw=read --bs=1M --size=4G --numjobs=1 \
    --filename=/data/fio_test --direct=1 \
    --runtime=30 --time_based --group_reporting

# 随机读测试（小块，测试 IOPS）
fio --name=rand-read --ioengine=libaio --iodepth=64 \
    --rw=randread --bs=4k --size=4G --numjobs=4 \
    --filename=/data/fio_test --direct=1 \
    --runtime=30 --time_based --group_reporting

# 混合读写（7:3，模拟业务负载）
fio --name=mixed-rw --ioengine=libaio --iodepth=32 \
    --rw=randrw --rwmixread=70 --bs=4k --size=4G --numjobs=4 \
    --filename=/data/fio_test --direct=1 \
    --runtime=30 --time_based --group_reporting

# 清理测试文件
rm /data/fio_test

# 性能参考（常见磁盘类型）：
# ┌─────────────┬──────────────┬──────────────┬────────────┐
# │ 磁盘类型    │ 顺序读       │ 顺序写       │ 随机4K读   │
# ├─────────────┼──────────────┼──────────────┼────────────┤
# │ HDD 7200rpm │ 100-200 MB/s │ 80-150 MB/s  │ 0.5K IOPS  │
# │ SATA SSD    │ 500-560 MB/s │ 450-520 MB/s │ 90K IOPS   │
# │ NVMe SSD    │ 3-7 GB/s     │ 2-5 GB/s     │ 500K IOPS  │
# └─────────────┴──────────────┴──────────────┴────────────┘
```

---

## 8. NVMe/SSD 专项优化

```bash
# 查看 NVMe 设备信息
nvme list 2>/dev/null
nvme smart-log /dev/nvme0 2>/dev/null | grep -E "temperature|wear|available_spare"

# NVMe 队列深度优化
echo 1024 > /sys/block/nvme0n1/queue/nr_requests

# NVMe 调度器（使用 none，完全依赖 NVMe 内部调度）
echo none > /sys/block/nvme0n1/queue/scheduler

# SSD TRIM 支持（定期释放无效块）
fstrim -v /data 2>/dev/null   # 手动 TRIM
# 开启定时 TRIM（systemd timer）
systemctl enable fstrim.timer
systemctl start fstrim.timer
# 验证
systemctl status fstrim.timer

# SSD 磨损均衡检查
smartctl -A /dev/sda | grep -E "Wear_Leveling|SSD_Life|Percent_Lifetime"

# 写放大因子 (WAF) 监控
nvme smart-log /dev/nvme0 | grep "data_units"
```

---

## 9. RAID 与 LVM 优化

```bash
# 查看 RAID 状态
cat /proc/mdstat
mdadm --detail /dev/md0

# RAID 条带大小优化
# 建议与文件系统 block size 和应用 I/O size 对齐
# 数据库随机 I/O：32KB~64KB
# 顺序大文件：128KB~256KB

# LVM 条带化（提升性能）
lvcreate -L 100G -n data_lv -i 4 -I 64 vg0   # 4 盘条带，64KB 条带大小

# 查看 LVM 配置
lvdisplay -m /dev/vg0/data_lv

# RAID 重建优先级（降低重建对业务的影响）
echo 100000 > /proc/sys/dev/raid/speed_limit_max   # 限制重建速度 100MB/s
```

---

## 10. 磁盘健康监控

```bash
# 安装 smartmontools
apt install smartmontools 2>/dev/null || yum install smartmontools 2>/dev/null

# 查看 SMART 状态
smartctl -H /dev/sda   # 健康状态（PASSED/FAILED）
smartctl -A /dev/sda   # 详细属性

# 关键 SMART 指标：
# Reallocated_Sector_Ct：重分配扇区数（> 0 需关注）
# Current_Pending_Sector：待定扇区数（> 0 需关注）
# Uncorrectable_Sector_Cnt：不可纠正扇区（> 0 磁盘即将损坏）
# SSD_Life_Left / Percent_Lifetime_Remain：SSD 剩余寿命

# 批量检查所有磁盘
for disk in /dev/sd? /dev/nvme?; do
    [ -b "$disk" ] && echo "=== $disk ===" && smartctl -H $disk 2>/dev/null | grep -E "result|PASSED|FAILED|overall"
done

# 开启 SMART 后台监控（smartd）
systemctl enable --now smartd
# 配置 /etc/smartd.conf 发现问题时发邮件

# 添加定期检查到 crontab
echo "0 3 * * 0 smartctl -a /dev/sda > /var/log/smart-sda-$(date +\%Y\%W).log" >> /etc/crontab
```


path: references/ebpf_bpftrace.md
content: # eBPF / bpftrace / BCC 高级追踪工具

## 目录
1. [eBPF 概述](#ebpf-概述)
2. [bpftrace 安装与使用](#bpftrace-安装与使用)
3. [BCC 工具集](#bcc-工具集)
4. [eBPF 程序类型](#ebpf-程序类型)
5. [libbpf 与 CO-RE](#libbpf-与-co-re)
6. [eBPF Map 类型](#ebpf-map-类型)
7. [生产环境最佳实践](#生产环境最佳实践)
8. [安全约束与限制](#安全约束与限制)

---

## eBPF 概述

eBPF（extended Berkeley Packet Filter）是 Linux 内核中的一个革命性技术，允许在内核空间安全运行沙箱化的程序，无需修改内核源码或加载内核模块。

### 核心能力

| 能力 | 说明 | 典型场景 |
|------|------|---------|
| **可观测性** | 无侵入式追踪内核和用户态函数 | 性能分析、延迟追踪 |
| **网络** | 高性能数据包处理 | 负载均衡（Cilium）、防火墙 |
| **安全** | 系统调用过滤和审计 | 容器安全、入侵检测 |
| **调试** | 动态追踪内核行为 | 故障排查、根因分析 |

### eBPF 架构

```text
用户态                          内核态
┌──────────────┐    ┌──────────────────────────┐
│ BCC/bpftrace │    │  eBPF 验证器（Verifier）  │
│ libbpf       │───>│  ↓                        │
│ 用户程序     │    │  JIT 编译器               │
└──────────────┘    │  ↓                        │
       ↑            │  eBPF 程序（沙箱运行）    │
       │            │  ↕                        │
       │            │  eBPF Maps（数据共享）     │
       └────────────│  ↕                        │
                    │  Hook 点（kprobe/tp/XDP）  │
                    └──────────────────────────┘
```

---

## bpftrace 安装与使用

### 安装

```bash
sudo apt install bpftrace         # Debian/Ubuntu 20.04+
sudo dnf install bpftrace         # Fedora/RHEL 8+
sudo pacman -S bpftrace           # Arch Linux

# 验证安装
bpftrace --version
bpftrace -l 'tracepoint:syscalls:*' | head -10  # 列出可用追踪点
```

### 常用单行命令

```bash
# === 进程追踪 ===
# 跟踪新进程
sudo bpftrace -e 'tracepoint:sched:sched_process_exec { printf("exec %s (pid=%d)\n", comm, pid); }'

# 按进程统计系统调用
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'

# 按系统调用类型统计
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[ksym(*(kaddr("sys_call_table") + args->id * 8))] = count(); }'

# 进程生命周期追踪
sudo bpftrace -e 'tracepoint:sched:sched_process_fork { printf("fork: %s (pid=%d) -> child pid=%d\n", comm, pid, args->child_pid); }'

# === I/O 追踪 ===
# 读系统调用延迟分布
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_read { @start[tid] = nsecs; } tracepoint:syscalls:sys_exit_read /@start[tid]/ { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }'

# 写系统调用延迟分布
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_write { @start[tid] = nsecs; } tracepoint:syscalls:sys_exit_write /@start[tid]/ { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }'

# VFS 读写统计（按进程）
sudo bpftrace -e 'kprobe:vfs_read { @reads[comm] = count(); } kprobe:vfs_write { @writes[comm] = count(); }'

# 磁盘 I/O 延迟分布
sudo bpftrace -e 'tracepoint:block:block_rq_issue { @start[args->dev, args->sector] = nsecs; } tracepoint:block:block_rq_complete /@start[args->dev, args->sector]/ { @us = hist((nsecs - @start[args->dev, args->sector]) / 1000); delete(@start[args->dev, args->sector]); }'

# === 网络追踪 ===
# TCP 连接延迟
sudo bpftrace -e 'kprobe:tcp_v4_connect { @start[tid] = nsecs; } kretprobe:tcp_v4_connect /@start[tid]/ { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }'

# TCP 重传追踪
sudo bpftrace -e 'kprobe:tcp_retransmit_skb { @retrans[comm, pid] = count(); }'

# DNS 查询追踪
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_connect /comm == "curl"/ { printf("connect by %s pid=%d\n", comm, pid); }'

# === 调度器追踪 ===
# 调度延迟（运行队列等待时间）
sudo bpftrace -e 'tracepoint:sched:sched_wakeup { @qtime[args->pid] = nsecs; } tracepoint:sched:sched_switch /@qtime[args->next_pid]/ { @us = hist((nsecs - @qtime[args->next_pid]) / 1000); delete(@qtime[args->next_pid]); }'

# 每秒中断统计
sudo bpftrace -e 'hardirq:hardirq_entry { @[args->name] = count(); } interval:s:1 { print(@); clear(@); }'

# 上下文切换统计（按进程）
sudo bpftrace -e 'tracepoint:sched:sched_switch { @[args->prev_comm] = count(); }'

# === 内存追踪 ===
# 页错误统计（按进程）
sudo bpftrace -e 'software:page-faults:1 { @[comm] = count(); }'

# brk 系统调用追踪（堆增长）
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_brk { @[comm] = count(); }'

# mmap 调用追踪
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_mmap { @[comm] = count(); }'
```

### bpftrace 脚本示例

```bash
# 保存为 latency.bt，追踪特定进程的系统调用延迟
cat > /tmp/latency.bt << 'EOF'
#!/usr/bin/env bpftrace

BEGIN {
    printf("Tracing syscall latency... Hit Ctrl-C to end.\n");
}

tracepoint:raw_syscalls:sys_enter /pid == $1/ {
    @start[tid] = nsecs;
}

tracepoint:raw_syscalls:sys_exit /@start[tid]/ {
    $duration = nsecs - @start[tid];
    @syscall_latency = hist($duration / 1000);  // 微秒
    if ($duration > 1000000) {  // > 1ms
        printf("SLOW syscall by %s (pid=%d tid=%d): %d us\n",
               comm, pid, tid, $duration / 1000);
    }
    delete(@start[tid]);
}

END {
    clear(@start);
}
EOF

# 运行：sudo bpftrace /tmp/latency.bt <PID>
```

---

## BCC 工具集

### 安装

```bash
sudo apt install bpfcc-tools linux-headers-$(uname -r)  # Debian/Ubuntu
sudo dnf install bcc-tools kernel-devel                   # Fedora/RHEL
```

### 常用工具

```bash
# === 进程与 CPU ===
sudo execsnoop-bpfcc              # 跟踪新进程执行
sudo runqlat-bpfcc                # 调度队列延迟直方图
sudo runqlen-bpfcc                # 调度队列长度
sudo cpudist-bpfcc                # CPU 时间片分布
sudo offcputime-bpfcc -p <PID> 5  # Off-CPU 分析（5秒）
sudo profile-bpfcc -F 99 30       # CPU 采样 30 秒

# === 磁盘 I/O ===
sudo biolatency-bpfcc             # 块 I/O 延迟直方图
sudo biosnoop-bpfcc               # 每次 I/O 详细信息
sudo biotop-bpfcc                 # 类似 top 的 I/O 视图
sudo ext4slower-bpfcc 1           # 慢 ext4 操作（>1ms）
sudo xfsslower-bpfcc 1            # 慢 xfs 操作（>1ms）
sudo fileslower-bpfcc 1           # 慢文件操作（>1ms）
sudo filetop-bpfcc                # 文件 I/O top

# === 网络 ===
sudo tcpconnect-bpfcc             # 跟踪 TCP 主动连接
sudo tcpaccept-bpfcc              # 跟踪 TCP 被动连接
sudo tcpretrans-bpfcc             # TCP 重传跟踪
sudo tcplife-bpfcc                # TCP 连接生命周期
sudo tcptop-bpfcc                 # TCP 吞吐量 top

# === 内存 ===
sudo cachestat-bpfcc 1            # 页缓存命中率（每秒）
sudo memleak-bpfcc -p <PID>       # 内存泄漏检测
sudo oomkill-bpfcc                # OOM Kill 追踪
sudo slabratetop-bpfcc            # Slab 分配速率 top

# === 文件系统 ===
sudo opensnoop-bpfcc              # 跟踪文件打开
sudo funccount-bpfcc 'vfs_*'      # 统计 VFS 函数调用
sudo filelife-bpfcc               # 文件创建到删除的生命周期
```

### BCC 工具速查表

| 工具 | 用途 | 典型场景 |
|------|------|---------|
| `execsnoop` | 新进程跟踪 | 发现异常进程创建 |
| `opensnoop` | 文件打开跟踪 | 找丢失的配置文件 |
| `biolatency` | I/O 延迟直方图 | 磁盘性能分析 |
| `biosnoop` | 每次 I/O 详情 | I/O 延迟尖刺定位 |
| `tcpconnect` | TCP 连接跟踪 | 网络延迟分析 |
| `tcpretrans` | TCP 重传 | 网络丢包诊断 |
| `tcplife` | TCP 生命周期 | 短连接问题 |
| `cachestat` | 缓存命中率 | 内存压力分析 |
| `runqlat` | 调度延迟 | CPU 饱和诊断 |
| `profile` | CPU 采样 | 函数级 CPU 分析 |
| `offcputime` | Off-CPU 分析 | I/O 等待/锁竞争 |
| `memleak` | 内存泄漏 | C/C++ 泄漏排查 |
| `oomkill` | OOM 追踪 | OOM 根因分析 |

---

## eBPF 程序类型

| 类型 | Hook 点 | 用途 | 示例 |
|------|---------|------|------|
| **kprobe/kretprobe** | 内核函数入口/返回 | 追踪内核函数 | 追踪 tcp_sendmsg |
| **uprobe/uretprobe** | 用户态函数入口/返回 | 追踪应用函数 | 追踪 malloc |
| **tracepoint** | 内核静态追踪点 | 稳定的内核事件 | sched:sched_switch |
| **raw_tracepoint** | 原始追踪点 | 低开销追踪 | 系统调用入口 |
| **XDP** | 网卡驱动层 | 高性能包处理 | DDoS 防护、负载均衡 |
| **TC** | 流量控制层 | 网络策略 | 包过滤、QoS |
| **cgroup** | cgroup 事件 | 容器级控制 | 网络/设备访问控制 |
| **socket_filter** | Socket 层 | 包过滤 | tcpdump 替代 |
| **perf_event** | 硬件/软件事件 | 性能计数器 | CPU cache miss |
| **LSM** | 安全模块钩子 | 安全策略 | 文件访问控制 |

### kprobe vs tracepoint

```bash
# kprobe：灵活但不稳定（内核升级可能变化）
sudo bpftrace -e 'kprobe:tcp_sendmsg { @[comm] = count(); }'

# tracepoint：稳定 API（推荐优先使用）
sudo bpftrace -e 'tracepoint:tcp:tcp_send_reset { @[comm] = count(); }'

# 列出所有可用追踪点
sudo bpftrace -l 'tracepoint:*' | wc -l        # 通常 2000+
sudo bpftrace -l 'kprobe:tcp_*' | head -20      # TCP 相关内核函数
```

---

## libbpf 与 CO-RE

### CO-RE（Compile Once, Run Everywhere）

CO-RE 解决了 eBPF 程序在不同内核版本间的可移植性问题。

```c
// 传统方式：需要内核头文件，每个内核版本重新编译
#include <linux/sched.h>

// CO-RE 方式：使用 BTF（BPF Type Format）
// 编译一次，运行在任何支持 BTF 的内核上
#include "vmlinux.h"  // 由 bpftool btf dump 生成
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

SEC("kprobe/tcp_sendmsg")
int BPF_KPROBE(tcp_sendmsg, struct sock *sk, struct msghdr *msg, size_t size)
{
    // CO-RE 自动处理结构体偏移差异
    u16 family = BPF_CORE_READ(sk, __sk_common.skc_family);
    // ...
    return 0;
}
```

### libbpf-bootstrap 快速入门

```bash
# 克隆 libbpf-bootstrap
git clone https://github.com/libbpf/libbpf-bootstrap.git
cd libbpf-bootstrap/examples/c

# 编译示例
make minimal

# 运行
sudo ./minimal

# 检查内核是否支持 BTF
ls /sys/kernel/btf/vmlinux && echo "BTF supported" || echo "No BTF"

# 生成 vmlinux.h
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
```

---

## eBPF Map 类型

Map 是 eBPF 程序与用户态程序之间共享数据的核心机制。

| Map 类型 | 用途 | 特点 |
|----------|------|------|
| `BPF_MAP_TYPE_HASH` | 键值存储 | 通用哈希表 |
| `BPF_MAP_TYPE_ARRAY` | 固定大小数组 | 索引快速访问 |
| `BPF_MAP_TYPE_PERCPU_HASH` | 每 CPU 哈希表 | 无锁，高性能 |
| `BPF_MAP_TYPE_PERCPU_ARRAY` | 每 CPU 数组 | 无锁计数器 |
| `BPF_MAP_TYPE_LRU_HASH` | LRU 哈希表 | 自动淘汰旧条目 |
| `BPF_MAP_TYPE_RINGBUF` | 环形缓冲区 | 高效事件流（推荐） |
| `BPF_MAP_TYPE_PERF_EVENT_ARRAY` | 事件数组 | 传统事件流 |
| `BPF_MAP_TYPE_STACK_TRACE` | 堆栈追踪 | 调用栈采集 |
| `BPF_MAP_TYPE_LPM_TRIE` | 最长前缀匹配 | IP 路由表 |

```bash
# 查看系统中的 eBPF Map
sudo bpftool map list

# 查看 Map 内容
sudo bpftool map dump id <MAP_ID>
```

---

## 生产环境最佳实践

### 1. 性能开销控制

```bash
# ❌ 避免：高频追踪点 + 大量数据处理
sudo bpftrace -e 'kprobe:* { @[probe] = count(); }'  # 追踪所有内核函数！

# ✅ 推荐：精确追踪 + 过滤
sudo bpftrace -e 'kprobe:tcp_sendmsg /comm == "nginx"/ { @bytes = sum(arg2); }'

# 开销评估：
# - tracepoint: ~100ns/event
# - kprobe: ~200ns/event
# - uprobe: ~1-5μs/event（用户态切换开销）
```

### 2. 常用诊断流程

```bash
# 第一步：全局概览
sudo runqlat-bpfcc 10 1          # 10 秒调度延迟
sudo biolatency-bpfcc 10 1       # 10 秒 I/O 延迟
sudo cachestat-bpfcc 1 10        # 10 秒缓存命中率

# 第二步：定位进程
sudo profile-bpfcc -F 99 10      # CPU 采样 10 秒
sudo offcputime-bpfcc 10         # Off-CPU 10 秒

# 第三步：深入追踪
sudo funccount-bpfcc 'tcp_*' 10  # TCP 函数调用频率
sudo tcpretrans-bpfcc            # TCP 重传详情
```

### 3. 火焰图生成

```bash
# CPU 火焰图（使用 profile）
sudo profile-bpfcc -F 99 -f 30 > /tmp/cpu.folded
flamegraph.pl /tmp/cpu.folded > /tmp/cpu.svg

# Off-CPU 火焰图
sudo offcputime-bpfcc -f 30 > /tmp/offcpu.folded
flamegraph.pl --color=io /tmp/offcpu.folded > /tmp/offcpu.svg

# 使用 bpftrace 生成
sudo bpftrace -e 'profile:hz:99 { @[kstack] = count(); }' -c 'sleep 30' > /tmp/stacks.txt
```

### 4. 持续监控集成

```bash
# 与 Prometheus 集成（使用 ebpf_exporter）
# https://github.com/cloudflare/ebpf_exporter
# 将 eBPF 指标暴露为 Prometheus 格式

# 与 Grafana 集成
# 通过 ebpf_exporter → Prometheus → Grafana 可视化
```

---

## 安全约束与限制

### 内核要求

| 功能 | 最低内核版本 |
|------|:----------:|
| 基础 eBPF | 3.18 |
| kprobe | 4.1 |
| tracepoint | 4.7 |
| XDP | 4.8 |
| bpftrace | 4.9（推荐 5.0+） |
| BTF/CO-RE | 5.2 |
| BPF ring buffer | 5.8 |
| BPF LSM | 5.7 |

### 安全限制

```bash
# 检查 eBPF 权限
cat /proc/sys/kernel/unprivileged_bpf_disabled
# 0 = 非特权用户可用, 1 = 仅 root, 2 = 完全禁用

# 容器中使用 eBPF
# 需要以下 capabilities:
# - CAP_SYS_ADMIN（传统）
# - CAP_BPF + CAP_PERFMON（内核 5.8+，更细粒度）

# K8s Pod 中启用
# securityContext:
#   capabilities:
#     add: ["SYS_ADMIN"]  # 或 ["BPF", "PERFMON"]
#   privileged: false

# 验证器限制
# - 最大指令数：100 万条（内核 5.2+）
# - 最大栈大小：512 字节
# - 禁止无限循环（必须有界）
# - 禁止访问未初始化内存
```

### 注意事项

- 需要内核 >= 4.9（bpftrace 推荐 >= 5.0）
- 容器中需要 `--privileged` 或 `CAP_SYS_ADMIN` + `CAP_BPF`
- macOS 不支持 eBPF（用 dtrace 替代）
- WSL2 支持但可能需要自编译内核
- 生产环境建议使用 tracepoint 而非 kprobe（更稳定）
- 高频追踪点需评估性能开销


path: references/go_performance.md
content: # Go 性能分析与优化指南

> Go 语言内置了强大的性能分析工具链（pprof），结合运行时特性（GC、goroutine 调度器），可以系统性地定位和优化性能瓶颈。

---


## 目录

- [1. 性能分析工具链](#1-性能分析工具链)
- [2. 常见性能瓶颈与优化](#2-常见性能瓶颈与优化)
- [3. 性能诊断快速参考](#3-性能诊断快速参考)
- [4. 生产环境最佳实践](#4-生产环境最佳实践)
## 1. 性能分析工具链

### 1.1 pprof（核心工具）

Go 内置 `runtime/pprof` 和 `net/http/pprof`，支持 CPU、内存、goroutine、阻塞等多维度 profiling。

**HTTP 服务接入（推荐）：**
```go
import _ "net/http/pprof"

func main() {
    go func() {
        log.Println(http.ListenAndServe("localhost:6060", nil))
    }()
    // ... 业务代码
}
```

**采集命令：**
```bash
# CPU profiling（30秒采样）
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# 堆内存分析
go tool pprof http://localhost:6060/debug/pprof/heap

# goroutine 泄漏检测
go tool pprof http://localhost:6060/debug/pprof/goroutine

# 阻塞分析（需启用 runtime.SetBlockProfileRate）
go tool pprof http://localhost:6060/debug/pprof/block

# 互斥锁竞争（需启用 runtime.SetMutexProfileFraction）
go tool pprof http://localhost:6060/debug/pprof/mutex

# allocs（历史所有分配）
go tool pprof http://localhost:6060/debug/pprof/allocs

# trace（精细事件追踪）
curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
go tool trace trace.out
```

**pprof 交互命令：**
```bash
# 进入交互模式后
(pprof) top 20          # 前20热点函数
(pprof) list funcName   # 查看函数逐行耗时
(pprof) web             # 生成调用图（需 graphviz）
(pprof) peek funcName   # 查看调用者/被调用者
(pprof) disasm funcName # 汇编级分析
```

### 1.2 go test -bench（基准测试）

```bash
# 运行基准测试
go test -bench=. -benchmem -count=5 ./...

# 对比两次基准结果
go install golang.org/x/perf/cmd/benchstat@latest
go test -bench=. -count=10 > old.txt
# 修改代码后
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txt
```

**基准测试模板：**
```go
func BenchmarkMyFunc(b *testing.B) {
    b.ReportAllocs()
    for i := 0; i < b.N; i++ {
        MyFunc()
    }
}
```

### 1.3 go tool trace（执行追踪）

```bash
# 采集 trace 数据
curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=10
go tool trace trace.out
```

trace 可以分析：
- goroutine 调度延迟
- GC STW（Stop-The-World）时间
- 系统调用阻塞
- 网络 I/O 等待
- goroutine 创建/销毁时间线

### 1.4 GODEBUG 环境变量

```bash
# GC 详细日志
GODEBUG=gctrace=1 ./myapp

# 调度器追踪
GODEBUG=schedtrace=1000,scheddetail=1 ./myapp

# 内存分配器追踪
GODEBUG=allocfreetrace=1 ./myapp
```

**gctrace 输出解读：**
```text
gc 1 @0.012s 2%: 0.010+1.2+0.003 ms clock, 0.080+0.40/1.0/0+0.024 ms cpu, 4->4->1 MB, 5 MB goal, 8 P
# gc N @时间 CPU占比: STW标记+并发标记+STW清扫, 堆大小变化, 目标堆大小, P数量
```

---

## 2. 常见性能瓶颈与优化

### 2.1 内存分配优化（减少 GC 压力）

**问题识别：** pprof heap 显示大量小对象分配，GC 频率高

```go
// ❌ 频繁分配（每次循环创建新 slice）
func bad() []int {
    var result []int
    for i := 0; i < 10000; i++ {
        result = append(result, i)  // 多次扩容 = 多次分配
    }
    return result
}

// ✅ 预分配容量
func good() []int {
    result := make([]int, 0, 10000)
    for i := 0; i < 10000; i++ {
        result = append(result, i)
    }
    return result
}
```

**sync.Pool 复用对象：**
```go
// Go 1.18+ 风格（interface{} 的别名 any）
var bufPool = sync.Pool{
    New: func() any {
        return new(bytes.Buffer)
    },
}

func process(data []byte) {
    buf := bufPool.Get().(*bytes.Buffer)
    defer func() {
        buf.Reset()
        bufPool.Put(buf)
    }()
    buf.Write(data)
    // ... 使用 buf
}
```

**字符串拼接优化：**
```go
// ❌ 字符串 + 拼接（每次产生新分配）
s := ""
for _, v := range items {
    s += v
}

// ✅ strings.Builder（底层 []byte 扩容，最终一次转 string）
var b strings.Builder
b.Grow(estimatedSize)  // 预分配
for _, v := range items {
    b.WriteString(v)
}
s := b.String()
```

### 2.2 goroutine 泄漏检测与防范

**问题识别：** goroutine 数量持续增长不回落

```bash
# 运行时查看 goroutine 数量
curl http://localhost:6060/debug/pprof/goroutine?debug=1 | head -5

# 或在代码中
runtime.NumGoroutine()
```

**常见泄漏模式与修复：**
```go
// ❌ channel 无消费者，goroutine 永远阻塞
func leak() {
    ch := make(chan int)
    go func() {
        ch <- 1  // 永远阻塞，goroutine 泄漏
    }()
    // ch 从未被读取
}

// ✅ 使用 context 控制 goroutine 生命周期
func noLeak(ctx context.Context) {
    ch := make(chan int, 1)
    go func() {
        select {
        case ch <- 1:
        case <-ctx.Done():
            return
        }
    }()
}
```

**goroutine 泄漏检测工具：**
```go
// 测试中使用 goleak
import "go.uber.org/goleak"

func TestMain(m *testing.M) {
    goleak.VerifyTestMain(m)
}
```

### 2.3 GC 调优

```bash
# 调整 GC 目标百分比（默认100，即堆增长100%触发GC）
GOGC=200 ./myapp        # 降低 GC 频率，增大内存占用
GOGC=50 ./myapp          # 增加 GC 频率，减少内存占用

# Go 1.19+ 内存软限制（推荐替代 GOGC 调优）
GOMEMLIMIT=4GiB ./myapp  # 设置内存软上限
```

**GC 调优决策表：**

| 场景 | GOGC | GOMEMLIMIT | 说明 |
|------|------|------------|------|
| 低延迟服务 | 50-100 | 容器内存×0.7 | 频繁 GC 但每次 STW 短 |
| 高吞吐批处理 | 200-500 | 容器内存×0.8 | 减少 GC 次数 |
| 内存受限容器 | off | 容器内存×0.7 | 完全靠 GOMEMLIMIT 控制 |

### 2.4 并发与锁优化

```go
// ❌ 全局大锁
var mu sync.Mutex
var cache map[string]string

// ✅ 分片锁减少竞争
type ShardedMap struct {
    shards [256]struct {
        mu    sync.RWMutex
        items map[string]string
    }
}

func (m *ShardedMap) getShard(key string) int {
    h := fnv.New32a()
    h.Write([]byte(key))
    return int(h.Sum32()) % 256
}

// ✅ 读多写少用 sync.RWMutex
var rwmu sync.RWMutex
// 读操作用 rwmu.RLock() / rwmu.RUnlock()
// 写操作用 rwmu.Lock() / rwmu.Unlock()

// ✅ 原子操作替代锁（简单计数器场景）
var counter atomic.Int64
counter.Add(1)
```

### 2.5 I/O 优化

```go
// ❌ 频繁小写入
for _, line := range lines {
    f.WriteString(line + "\n")  // 每行一次系统调用
}

// ✅ 使用 bufio.Writer 缓冲
w := bufio.NewWriterSize(f, 64*1024)  // 64KB 缓冲
defer w.Flush()
for _, line := range lines {
    w.WriteString(line)
    w.WriteByte('\n')
}

// ✅ HTTP 客户端复用连接
var httpClient = &http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 10,
        IdleConnTimeout:     90 * time.Second,
    },
    Timeout: 30 * time.Second,
}
```

### 2.6 编译优化

```bash
# 启用编译器优化分析
go build -gcflags="-m" ./...            # 逃逸分析
go build -gcflags="-m -m" ./...         # 详细逃逸分析
go build -gcflags="-l" ./...            # 禁用内联（调试用）

# 减小二进制体积
go build -ldflags="-s -w" ./...         # 去掉符号表和调试信息

# 竞态检测（开发/测试环境）
go build -race ./...
go test -race ./...

# 指定目标架构优化
GOAMD64=v3 go build ./...               # 使用 AVX2 指令集（Go 1.18+）
```

**逃逸分析关键规则：**
- 返回局部变量的指针 → 逃逸到堆
- interface{}/any 参数 → 可能逃逸
- 闭包引用局部变量 → 逃逸
- slice/map 超过一定大小 → 逃逸

---

## 3. 性能诊断快速参考

### 3.1 诊断决策树

```text
性能问题
├── CPU 高
│   ├── pprof CPU profile → top/list 定位热点函数
│   ├── 热点在 runtime.mallocgc → 内存分配过多 → 见 2.1
│   ├── 热点在 runtime.gcBgMarkWorker → GC 压力大 → 见 2.3
│   └── 热点在业务代码 → 算法/数据结构优化
├── 内存高
│   ├── pprof heap → top 查看分配热点
│   ├── goroutine 数量异常 → goroutine 泄漏 → 见 2.2
│   └── GOMEMLIMIT + GOGC 调优 → 见 2.3
├── 延迟高
│   ├── go tool trace → 查看调度延迟
│   ├── pprof block → 阻塞分析
│   ├── pprof mutex → 锁竞争 → 见 2.4
│   └── 网络 I/O → HTTP 连接池/超时配置 → 见 2.5
└── goroutine 泄漏
    ├── pprof goroutine → 查看堆栈
    └── goleak 测试 → 见 2.2
```

### 3.2 关键指标告警阈值

| 指标 | 正常 | 警告 | 严重 |
|------|------|------|------|
| goroutine 数量 | < 1万 | > 5万 | > 10万 |
| GC STW 时间 | < 1ms | > 5ms | > 10ms |
| GC 频率 | < 10次/秒 | > 50次/秒 | > 100次/秒 |
| 堆内存增长 | 稳定 | 持续增长 | OOM |
| alloc 速率 | 基线±20% | 基线×2 | 基线×5 |

---

## 4. 生产环境最佳实践

### 4.1 必备运行时配置

```bash
# 容器环境推荐
GOMAXPROCS=<容器CPU核数>   # 自动检测可能不准确，手动设置
GOMEMLIMIT=<容器内存×0.7>
GOGC=100                    # 或 off（配合 GOMEMLIMIT）

# 推荐使用 automaxprocs 自动适配容器
# go get go.uber.org/automaxprocs
import _ "go.uber.org/automaxprocs"
```

### 4.2 持续性能监控

```go
// Prometheus 指标暴露
import "github.com/prometheus/client_golang/prometheus/promhttp"

// 内置 Go 运行时指标
http.Handle("/metrics", promhttp.Handler())
// 自动暴露：go_goroutines, go_gc_duration_seconds, go_memstats_* 等
```

### 4.3 性能优化检查清单

- [ ] 所有 slice/map 预分配了合理容量
- [ ] 热路径避免了 interface{}/any 和反射
- [ ] 使用 sync.Pool 复用高频临时对象
- [ ] HTTP 客户端复用连接（不要每次 new）
- [ ] goroutine 都有退出机制（context/done channel）
- [ ] 生产环境开启了 pprof endpoint（内网访问）
- [ ] 设置了 GOMEMLIMIT（容器环境）
- [ ] 设置了 GOMAXPROCS（容器环境）
- [ ] 基准测试覆盖了核心路径
- [ ] CI 中集成了 -race 检测


path: references/java_performance.md
content: # Java 性能分析与优化指南

> Java 基于 JVM 运行，拥有成熟的性能分析生态（JFR、async-profiler、VisualVM）和自动内存管理（GC）。本文档覆盖 JVM 性能分析工具链、GC 调优、并发优化、JIT 编译及生产环境最佳实践。

---


## 目录

- [1. 性能分析工具链](#1-性能分析工具链)
- [2. GC 调优](#2-gc-调优)
- [3. 常见性能瓶颈与优化](#3-常见性能瓶颈与优化)
- [4. 性能诊断快速参考](#4-性能诊断快速参考)
- [5. 生产环境最佳实践](#5-生产环境最佳实践)
## 1. 性能分析工具链

### 1.1 JDK Flight Recorder (JFR) — 核心工具

JFR 是 JDK 内置的低开销（< 2%）生产级性能分析工具，JDK 11+ 免费使用。

**启动时开启 JFR：**
```bash
# 持续记录（生产环境推荐）
java -XX:StartFlightRecording=duration=60s,filename=recording.jfr -jar app.jar

# 持续记录 + 磁盘落盘
java -XX:StartFlightRecording=disk=true,maxage=1h,maxsize=500m,dumponexit=true,filename=app.jfr -jar app.jar
```

**运行时动态开启（jcmd）：**
```bash
# 查找 Java 进程
jcmd -l

# 启动 JFR 记录
jcmd <PID> JFR.start name=profile duration=60s filename=recording.jfr

# 导出正在进行的记录
jcmd <PID> JFR.dump name=profile filename=dump.jfr

# 停止记录
jcmd <PID> JFR.stop name=profile
```

**JFR 分析工具：**
```bash
# JDK Mission Control（GUI 分析）
jmc  # 打开 .jfr 文件

# 命令行解析
jfr summary recording.jfr
jfr print --events jdk.CPULoad recording.jfr
jfr print --events jdk.GarbageCollection recording.jfr

# 转为火焰图（配合 async-profiler 的 jfr2flame）
java -cp async-profiler.jar jfr2flame recording.jfr flamegraph.html
```

**JFR 关键事件类型：**
| 事件 | 说明 |
|------|------|
| jdk.CPULoad | CPU 使用率 |
| jdk.GarbageCollection | GC 事件 |
| jdk.GCPhasePause | GC STW 暂停 |
| jdk.ObjectAllocationInNewTLAB | TLAB 外分配（大对象） |
| jdk.ThreadPark / jdk.JavaMonitorWait | 线程等待/阻塞 |
| jdk.FileRead / jdk.FileWrite | 文件 I/O |
| jdk.SocketRead / jdk.SocketWrite | 网络 I/O |
| jdk.ExecutionSample | CPU 采样 |

### 1.2 async-profiler（采样分析器）

**低开销、无 SafePoint 偏差，支持 CPU/内存/锁/Wall-clock 分析：**

```bash
# 下载
wget https://github.com/async-profiler/async-profiler/releases/latest/download/async-profiler-3.0-linux-x64.tar.gz

# CPU 火焰图（30秒采样）
./asprof -d 30 -f flamegraph.html <PID>

# 内存分配火焰图
./asprof -d 30 -e alloc -f alloc-flame.html <PID>

# 锁竞争分析
./asprof -d 30 -e lock -f lock-flame.html <PID>

# Wall-clock 分析（包含 I/O 等待时间）
./asprof -d 30 -e wall -f wall-flame.html <PID>

# 输出 JFR 格式（可用 JMC 打开）
./asprof -d 60 -o jfr -f profile.jfr <PID>
```

### 1.3 jstat（GC 统计）

```bash
# GC 统计（每秒刷新，共10次）
jstat -gcutil <PID> 1000 10

# 输出列说明：
# S0/S1: Survivor 区使用率
# E: Eden 区使用率
# O: Old 区使用率
# M: Metaspace 使用率
# YGC/YGCT: Young GC 次数/总耗时
# FGC/FGCT: Full GC 次数/总耗时
# GCT: GC 总耗时

# GC 原因
jstat -gccause <PID> 1000

# 堆各区容量
jstat -gccapacity <PID>
```

### 1.4 jmap + jhat / MAT（堆分析）

```bash
# 堆直方图（不触发 Full GC）
jmap -histo <PID> | head -30

# 堆直方图（触发 Full GC 后统计存活对象）
jmap -histo:live <PID> | head -30

# 导出堆 dump（会触发 Full GC，生产慎用）
jmap -dump:format=b,file=heap.hprof <PID>

# 推荐：OOM 时自动 dump
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof -jar app.jar
```

**堆 dump 分析工具：**
- **Eclipse MAT**：最强大的堆分析工具，支持 Leak Suspects 报告、Dominator Tree、OQL 查询
- **VisualVM**：轻量级 GUI，支持实时监控 + 堆分析
- **jhat**：JDK 自带（JDK 9 后移除），简单 HTTP 服务浏览堆

### 1.5 jstack（线程分析）

```bash
# 线程 dump
jstack <PID> > thread_dump.txt

# 检测死锁
jstack -l <PID> | grep -A 5 "deadlock"

# 多次采样对比（定位 CPU 热点线程）
for i in 1 2 3; do
    jstack <PID> > thread_dump_$i.txt
    sleep 2
done
```

**线程状态分析：**
| 状态 | 说明 | 可能问题 |
|------|------|---------|
| RUNNABLE | 正在运行/可运行 | CPU 密集或 I/O 等待 |
| BLOCKED | 等待 monitor 锁 | 锁竞争 |
| WAITING | 无限等待 | 死锁/资源泄漏 |
| TIMED_WAITING | 限时等待 | sleep/poll 过长 |

### 1.6 arthas（阿里开源诊断工具）

```bash
# 下载启动
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

# 常用命令
dashboard              # 实时面板（CPU/内存/线程/GC）
thread -n 5            # CPU 最高的5个线程
thread --state BLOCKED # 查看阻塞线程
trace com.example.MyService processOrder  # 方法调用链耗时
watch com.example.MyService processOrder returnObj  # 观察返回值
profiler start         # 启动 async-profiler（内置）
profiler stop --format html --file /tmp/flame.html
```

---

## 2. GC 调优

### 2.1 GC 选择指南

| GC | 适用场景 | JDK 版本 | 特点 |
|----|---------|---------|------|
| G1GC | 通用（JDK 9+ 默认） | 8+ | 均衡吞吐/延迟，自适应调优 |
| ZGC | 超低延迟（< 1ms STW） | 15+（生产就绪） | 最大堆 16TB，STW < 1ms |
| Shenandoah | 低延迟 | 12+（RedHat） | 并发压缩，STW < 10ms |
| Parallel GC | 高吞吐批处理 | 8+ | 最大化吞吐量 |
| Serial GC | 小堆/嵌入式 | 8+ | 单线程，最简单 |

### 2.2 G1GC 调优

```bash
# G1GC 基础配置
# -Xms4g -Xmx4g                         堆大小（建议 Xms=Xmx）
# -XX:MaxGCPauseMillis=200               目标暂停时间（默认200ms）
# -XX:G1HeapRegionSize=8m                Region 大小（1-32MB，2的幂）
# -XX:InitiatingHeapOccupancyPercent=45  触发并发标记的堆占用率
# -XX:G1ReservePercent=10                预留空间防 to-space exhausted
java -XX:+UseG1GC \
     -Xms4g -Xmx4g \
     -XX:MaxGCPauseMillis=200 \
     -XX:G1HeapRegionSize=8m \
     -XX:InitiatingHeapOccupancyPercent=45 \
     -XX:G1ReservePercent=10 \
     -jar app.jar
```

**G1GC 常见问题：**
| 现象 | 原因 | 调优 |
|------|------|------|
| Full GC 频繁 | Old 区增长过快 | 降低 IHOP、增大堆 |
| to-space exhausted | Survivor/Old 空间不足 | 增大 G1ReservePercent |
| Humongous allocation | 大对象（> Region/2）直接进 Old | 增大 G1HeapRegionSize |
| Mixed GC 时间长 | 回收 Region 过多 | 调整 G1MixedGCCountTarget |

### 2.3 ZGC 调优

```bash
# ZGC 配置（极简，大部分场景无需额外调优）
java -XX:+UseZGC \
     -Xms8g -Xmx8g \
     -XX:SoftMaxHeapSize=6g \    # 软上限（ZGC 尽量不超过）
     -jar app.jar

# JDK 21+ 分代 ZGC（推荐）
java -XX:+UseZGC -XX:+ZGenerational \
     -Xms8g -Xmx8g \
     -jar app.jar
```

### 2.4 GC 日志分析

```bash
# JDK 11+ 统一 GC 日志
java -Xlog:gc*:file=gc.log:time,uptime,level,tags:filecount=5,filesize=100m \
     -jar app.jar

# 在线分析工具
# https://gceasy.io — 上传 gc.log 自动分析
# https://github.com/microsoft/gctoolkit — 微软开源 GC 分析
```

**GC 日志关键指标：**
```text
# 关注：
# - Pause 时间（STW）
# - GC 频率（Young GC / Mixed GC / Full GC）
# - 堆占用趋势（GC 后 Old 区是否持续增长 → 内存泄漏）
# - Allocation Rate（分配速率过高 → 优化对象创建）
```

---

## 3. 常见性能瓶颈与优化

### 3.1 内存分配优化

```java
// ❌ 循环内频繁创建对象
for (int i = 0; i < 100000; i++) {
    String key = "prefix_" + i;  // 每次创建新 String
    map.put(key, value);
}

// ✅ 使用 StringBuilder
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i < 100000; i++) {
    sb.setLength(0);
    sb.append("prefix_").append(i);
    map.put(sb.toString(), value);
}

// ❌ 自动装箱（Integer 缓存仅 -128~127）
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < 100000; i++) {
    map.put(i, i * 2);  // 自动装箱产生大量 Integer 对象
}

// ✅ 使用原始类型集合（Eclipse Collections / fastutil）
IntIntHashMap map = new IntIntHashMap();
for (int i = 0; i < 100000; i++) {
    map.put(i, i * 2);  // 无装箱
}

// ✅ 对象池（高频创建/销毁的重对象）
// Apache Commons Pool / 自定义 ThreadLocal 池
private static final ThreadLocal<SimpleDateFormat> SDF_POOL =
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
```

### 3.2 集合优化

```java
// ❌ 未指定初始容量（多次扩容 = 多次数组拷贝 + GC）
List<String> list = new ArrayList<>();  // 默认10

// ✅ 预估容量
List<String> list = new ArrayList<>(expectedSize);
Map<String, Object> map = new HashMap<>(expectedSize * 4 / 3 + 1);  // 考虑负载因子

// ❌ 遍历时删除（ConcurrentModificationException 或性能差）
for (String item : list) {
    if (condition) list.remove(item);
}

// ✅ removeIf（Java 8+）
list.removeIf(item -> condition);

// ✅ 不可变集合（减少防御性拷贝）
List<String> immutable = List.of("a", "b", "c");       // Java 9+
Map<String, Integer> map = Map.of("a", 1, "b", 2);     // Java 9+
```

### 3.3 并发优化

```java
// ❌ synchronized 大范围锁
public synchronized void process(Order order) {
    validate(order);   // 不需要同步
    save(order);       // 需要同步
    notify(order);     // 不需要同步
}

// ✅ 缩小同步范围
public void process(Order order) {
    validate(order);
    synchronized (this) {
        save(order);
    }
    notify(order);
}

// ✅ 读写锁（读多写少）
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public String read(String key) {
    rwLock.readLock().lock();
    try { return cache.get(key); }
    finally { rwLock.readLock().unlock(); }
}

// ✅ ConcurrentHashMap 替代 Collections.synchronizedMap
ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
map.computeIfAbsent(key, k -> expensiveCompute(k));

// ✅ LongAdder 替代 AtomicLong（高竞争计数器）
LongAdder counter = new LongAdder();
counter.increment();
long total = counter.sum();

// ✅ 虚拟线程（JDK 21+，I/O 密集型）
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (var task : tasks) {
        executor.submit(task);
    }
}
```

### 3.4 I/O 优化

```java
// ❌ 逐字节/逐行无缓冲读写
FileInputStream fis = new FileInputStream("data.txt");
int b;
while ((b = fis.read()) != -1) { /* ... */ }

// ✅ 使用 BufferedInputStream / BufferedReader
try (BufferedReader reader = new BufferedReader(
        new FileReader("data.txt"), 64 * 1024)) {  // 64KB 缓冲
    String line;
    while ((line = reader.readLine()) != null) { /* ... */ }
}

// ✅ NIO + FileChannel（大文件）
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
    ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 1024);  // 1MB DirectBuffer
    while (channel.read(buffer) > 0) {
        buffer.flip();
        // 处理 buffer
        buffer.clear();
    }
}

// ✅ MappedByteBuffer（内存映射，超大文件）
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
    MappedByteBuffer mmap = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
    // 直接访问 mmap，由 OS 管理页面调度
}

// ✅ HTTP 连接池
CloseableHttpClient client = HttpClients.custom()
    .setMaxConnTotal(200)
    .setMaxConnPerRoute(50)
    .setConnectionTimeToLive(5, TimeUnit.MINUTES)
    .build();
```

### 3.5 JIT 编译优化

```bash
# 查看 JIT 编译日志
java -XX:+PrintCompilation -jar app.jar

# 查看内联决策
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -jar app.jar

# 调整内联阈值（热路径函数较大时）
java -XX:MaxInlineSize=50 -XX:FreqInlineSize=500 -jar app.jar

# 禁用分层编译（调试用）
java -XX:-TieredCompilation -jar app.jar

# Graal JIT（JDK 17+，可选更优的 JIT 编译器）
java -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler -jar app.jar
```

**JIT 友好的代码模式：**
- 避免超大方法（> 325 字节不会被内联）
- 减少多态调用（虚方法调用阻碍内联）
- 热路径代码保持紧凑
- 避免异常驱动的流程控制

---

## 4. 性能诊断快速参考

### 4.1 诊断决策树

```text
性能问题
├── CPU 高
│   ├── async-profiler CPU 火焰图 → 定位热点方法
│   ├── 热点在 GC 线程 → GC 调优 → 见 2.x
│   ├── 热点在锁等待 → 并发优化 → 见 3.3
│   ├── 热点在序列化/反序列化 → 换高性能库（Kryo/Protobuf）
│   └── 热点在业务代码 → 算法/数据结构优化
├── 内存高 / OOM
│   ├── jmap -histo → 查看对象分布
│   ├── MAT 分析堆 dump → Leak Suspects 报告
│   ├── Metaspace OOM → 类加载泄漏（动态代理/反射）
│   ├── Direct Memory OOM → Netty/NIO DirectBuffer 泄漏
│   └── GC overhead → 堆太小 或 内存泄漏
├── 延迟高
│   ├── JFR → 分析 I/O 事件和线程等待
│   ├── GC STW 过长 → 换 ZGC 或调优 G1
│   ├── 锁竞争 → async-profiler lock 火焰图 → 见 3.3
│   └── 数据库慢查询 → 连接池 + SQL 优化
└── 线程问题
    ├── jstack → 线程状态分析
    ├── 大量 BLOCKED → 锁竞争/死锁
    ├── 大量 WAITING → 资源泄漏/线程池饱和
    └── 线程数过多 → 使用虚拟线程（JDK 21+）
```

### 4.2 关键指标告警阈值

| 指标 | 正常 | 警告 | 严重 |
|------|------|------|------|
| GC 暂停时间 | < 100ms | > 200ms | > 500ms |
| Full GC 频率 | < 1次/天 | > 1次/小时 | > 1次/分钟 |
| 堆使用率（GC后） | < 60% | > 75% | > 90% |
| 线程数 | < 500 | > 1000 | > 2000 |
| Metaspace | 稳定 | 持续增长 | OOM |
| CPU（GC 占比） | < 5% | > 10% | > 30% |
| 对象分配速率 | 基线 | 基线×3 | 基线×10 |

---

## 5. 生产环境最佳实践

### 5.1 JVM 启动参数模板

```bash
# 通用生产配置（JDK 17+）
java \
  -Xms4g -Xmx4g \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=200 \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:HeapDumpPath=/var/log/java/ \
  -XX:+ExitOnOutOfMemoryError \
  -Xlog:gc*:file=/var/log/java/gc.log:time,uptime,level,tags:filecount=5,filesize=100m \
  -XX:StartFlightRecording=disk=true,maxage=6h,maxsize=1g,dumponexit=true,filename=/var/log/java/flight.jfr \
  -jar app.jar

# 低延迟配置（JDK 21+）
java \
  -Xms8g -Xmx8g \
  -XX:+UseZGC -XX:+ZGenerational \
  -XX:SoftMaxHeapSize=6g \
  -XX:+HeapDumpOnOutOfMemoryError \
  -Xlog:gc*:file=gc.log:time:filecount=3,filesize=50m \
  -jar app.jar

# 容器环境
java \
  -XX:+UseContainerSupport \              # 自动识别容器资源限制（JDK 10+）
  -XX:MaxRAMPercentage=75.0 \             # 堆占容器内存的75%
  -XX:InitialRAMPercentage=75.0 \
  -jar app.jar
```

### 5.2 性能优化检查清单

- [ ] Xms 和 Xmx 设置相同（避免堆动态扩缩）
- [ ] 开启了 HeapDumpOnOutOfMemoryError
- [ ] 开启了 GC 日志并配置了日志轮转
- [ ] 集合初始化时指定了合理容量
- [ ] 避免了热路径上的自动装箱
- [ ] 使用了连接池（HTTP/DB/Redis）
- [ ] 线程池大小合理（CPU 密集 = 核数，I/O 密集 = 核数 × 2-4）
- [ ] 同步范围最小化，读多写少用读写锁
- [ ] 大文件使用 NIO/MappedByteBuffer
- [ ] 开启了 JFR 持续记录（生产环境）
- [ ] 容器环境启用了 UseContainerSupport
- [ ] 定期分析 GC 日志，确认无 Full GC 频繁/内存泄漏


path: references/kernel_params.md
content: # 内核参数速查全表

> 本文档列出所有常用内核参数的默认值、建议值和适用场景，配合 `sysctl` 命令使用。
>
> 修改前必读：先用 `sysctl 参数名` 记录原始值；生产环境先临时生效再持久化。

---


## 目录

- [一、内存参数](#一内存参数)
- [二、CPU/调度参数](#二cpu调度参数)
- [三、网络参数](#三网络参数)
- [四、I/O 参数](#四io-参数)
- [五、文件系统参数](#五文件系统参数)
- [六、一键查看所有关键参数现状](#六一键查看所有关键参数现状)
- [七、完整持久化配置文件模板](#七完整持久化配置文件模板)
- [八、回滚所有更改](#八回滚所有更改)
## 一、内存参数

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `vm.swappiness` | 60 | 10（服务器）/ 1（数据库）| 降低换页倾向 |
| `vm.min_free_kbytes` | 内存相关 | 131072~262144 | 防止 OOM 误杀，预留内核内存 |
| `vm.dirty_ratio` | 20~40 | 10（写密集）/ 60（批量写） | 脏页触发阻塞阈值 |
| `vm.dirty_background_ratio` | 10 | 5 | 后台回写触发阈值 |
| `vm.dirty_expire_centisecs` | 3000 | 1500 | 脏页强制刷盘时间(cs) |
| `vm.dirty_writeback_centisecs` | 500 | 300~500 | 后台回写线程唤醒间隔(cs) |
| `vm.dirty_bytes` | 0（未设置）| 268435456（256MB）| 绝对值控制，与ratio二选一 |
| `vm.dirty_background_bytes` | 0（未设置）| 67108864（64MB）| 绝对值控制，与background_ratio二选一 |
| `vm.overcommit_memory` | 0 | 0（默认）/ 1（允许）| 0=启发式, 1=允许, 2=严格 |
| `vm.overcommit_ratio` | 50 | 80 | overcommit_memory=2时的比例 |
| `vm.vfs_cache_pressure` | 100 | 50~200 | VFS缓存回收压力（>100更激进） |
| `vm.nr_hugepages` | 0 | 按需 | 静态HugePage数量（数据库） |
| `vm.numa_stat` | 1 | 保持默认 | NUMA统计 |

---

## 二、CPU/调度参数

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `kernel.sched_min_granularity_ns` | 3000000 (3ms) | 10000000 (10ms) | 调度最小粒度，增大减少切换 |
| `kernel.sched_wakeup_granularity_ns` | 4000000 (4ms) | 15000000 (15ms) | 唤醒粒度，防止频繁抢占 |
| `kernel.sched_migration_cost_ns` | 500000 (0.5ms) | 5000000 (5ms) | 进程迁移代价，增大减少跨核 |
| `kernel.numa_balancing` | 1 | 0（延迟敏感）| NUMA自动均衡（延迟敏感关闭） |
| `kernel.sched_autogroup_enabled` | 1 | 0（服务器）| 进程组自动调度（服务器关闭） |
| `kernel.pid_max` | 32768 | 4194304 | 最大PID数（容器密集环境调大） |
| `kernel.threads-max` | 取决内存 | 保持默认 | 最大线程数 |

---

## 三、网络参数

### TCP 连接状态

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.ipv4.tcp_tw_reuse` | 0 | 1 | 允许重用TIME_WAIT连接 |
| `net.ipv4.tcp_fin_timeout` | 60 | 30 | FIN_WAIT_2超时时间(秒) |
| `net.ipv4.tcp_max_tw_buckets` | 180000 | 262144 | TIME_WAIT桶数量上限 |
| `net.ipv4.tcp_keepalive_time` | 7200 | 600 | Keepalive探测起始时间(秒) |
| `net.ipv4.tcp_keepalive_intvl` | 75 | 30 | Keepalive探测间隔(秒) |
| `net.ipv4.tcp_keepalive_probes` | 9 | 5 | Keepalive探测次数 |
| `net.ipv4.tcp_syncookies` | 1 | 1 | SYN Cookie防护(保持开启) |

### TCP 队列与并发

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.core.somaxconn` | 4096（5.4+）/ 128（旧内核） | 65535 | accept队列上限 |
| `net.ipv4.tcp_max_syn_backlog` | 1024 | 65535 | SYN队列上限 |
| `net.core.netdev_max_backlog` | 1000 | 65535 | 网卡接收队列长度 |

### TCP 缓冲区

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.core.rmem_max` | 212992 | 134217728 (128MB) | socket 接收缓冲区最大值 |
| `net.core.wmem_max` | 212992 | 134217728 (128MB) | socket 发送缓冲区最大值 |
| `net.ipv4.tcp_rmem` | 4096 87380 6291456 | 4096 131072 67108864 | TCP接收缓冲区(最小/默认/最大) |
| `net.ipv4.tcp_wmem` | 4096 16384 4194304 | 4096 131072 67108864 | TCP发送缓冲区(最小/默认/最大) |
| `net.ipv4.tcp_moderate_rcvbuf` | 1 | 1 | TCP自动调整缓冲区(保持开启) |

### 端口与文件描述符

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.ipv4.ip_local_port_range` | 32768 60999 | 1024 65535 | 本地端口范围（连接发起方） |
| `fs.file-max` | 取决内存 | 2097152 | 系统文件描述符总限制 |

### 拥塞控制

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.ipv4.tcp_congestion_control` | cubic | bbr | BBR适合高延迟/丢包网络 |
| `net.core.default_qdisc` | pfifo_fast | fq | BBR推荐搭配fq队列 |

### conntrack

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `net.netfilter.nf_conntrack_max` | 65536 | 1048576 | conntrack表大小（需iptables） |
| `net.netfilter.nf_conntrack_tcp_timeout_established` | 432000 (5天) | 600 | 已建立连接超时(秒) |
| `net.netfilter.nf_conntrack_tcp_timeout_time_wait` | 120 | 60 | TIME_WAIT超时(秒) |

---

## 四、I/O 参数

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `/sys/block/sdX/queue/scheduler` | mq-deadline/none | 见磁盘调优文档 | I/O调度器 |
| [REDACTED_SECRET] | 64/128 | 256（SSD）| 磁盘请求队列深度 |
| [REDACTED_SECRET] | 128 | 2048（顺序读）| 预读缓冲大小(KB) |

---

## 五、文件系统参数

| 参数 | 默认值 | 建议值 | 场景说明 |
|------|--------|--------|---------|
| `fs.inotify.max_user_watches` | 8192 | 524288 | inotify 监控文件数（IDE/容器场景） |
| `fs.inotify.max_user_instances` | 128 | 512 | inotify 实例数 |
| `fs.aio-max-nr` | 65536 | 1048576 | 异步 I/O 请求数上限 |
| `fs.nr_open` | 1048576 | 2097152 | 单进程最大打开文件数 |

---

## 六、一键查看所有关键参数现状

```bash
echo "=== 内存参数 ===" && \
sysctl vm.swappiness vm.dirty_ratio vm.dirty_background_ratio vm.min_free_kbytes vm.overcommit_memory 2>/dev/null

echo "=== CPU/调度参数 ===" && \
sysctl kernel.sched_min_granularity_ns kernel.sched_migration_cost_ns kernel.numa_balancing 2>/dev/null

echo "=== 网络参数 ===" && \
sysctl net.core.somaxconn net.ipv4.tcp_tw_reuse net.ipv4.tcp_fin_timeout \
  net.ipv4.ip_local_port_range net.ipv4.tcp_congestion_control \
  net.core.rmem_max net.core.wmem_max 2>/dev/null

echo "=== 文件描述符 ===" && \
sysctl fs.file-max fs.file-nr fs.inotify.max_user_watches 2>/dev/null
```

---

## 七、完整持久化配置文件模板

```bash
cat > /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
# performance-mastery 调优配置
# 修改前请先备份：sysctl -a > /tmp/sysctl_backup.txt

# ── 内存 ──────────────────────────────────
vm.swappiness = 10
vm.min_free_kbytes = 131072
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
vm.dirty_expire_centisecs = 1500
vm.dirty_writeback_centisecs = 500

# ── CPU 调度 ──────────────────────────────
kernel.sched_min_granularity_ns = 10000000
kernel.sched_wakeup_granularity_ns = 15000000
kernel.sched_migration_cost_ns = 5000000

# ── 网络 TCP ─────────────────────────────
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_syncookies = 1

# ── 网络队列 ─────────────────────────────
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535

# ── 网络缓冲区 ───────────────────────────
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 131072 67108864
net.ipv4.tcp_wmem = 4096 131072 67108864
net.ipv4.tcp_moderate_rcvbuf = 1

# ── 端口与文件描述符 ─────────────────────
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 2097152
fs.inotify.max_user_watches = 524288

# ── 拥塞控制（需内核4.9+） ───────────────
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF

# 使配置生效
sysctl --system

# 验证
sysctl -p /etc/sysctl.d/99-performance-mastery.conf
```

---

## 八、回滚所有更改

```bash
# 方案1：临时回滚（重启失效，但立即生效）
sysctl -w vm.swappiness=60
sysctl -w vm.dirty_ratio=20
# ... 逐一回滚

# 方案2：删除配置文件并重新加载
rm /etc/sysctl.d/99-performance-mastery.conf
sysctl --system
# 注意：已通过 sysctl -w 临时设置的值不会自动还原，需手动回滚
```


path: references/memory.md
content: # 内存调优参考手册

## 目录
1. [快速诊断](#1-快速诊断)
2. [Swap 与 swappiness 调优](#2-swap-与-swappiness-调优)
3. [OOM Kill 处理与预防](#3-oom-kill-处理与预防)
4. [透明大页 THP](#4-透明大页-thp)
5. [HugePage 配置](#5-hugepage-配置)
6. [脏页回写调优](#6-脏页回写调优)
7. [内存回收与 min_free_kbytes](#7-内存回收与-min_free_kbytes)
8. [Slab 缓存优化](#8-slab-缓存优化)
9. [NUMA 内存优化](#9-numa-内存优化)
10. [内存泄漏排查](#10-内存泄漏排查)
11. [容器内存限制排查](#11-容器内存限制排查)

---

## 1. 快速诊断

```bash
# 内存概览
free -h

# 详细内存信息
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|Dirty|Writeback|AnonPages|Slab|KernelStack|PageTables|HugePages"

# OOM 历史
dmesg | grep -iE "oom|killed process" | tail -20

# 内存占用 TOP 进程
ps aux --sort=-%mem | head -15

# Slab 缓存
slabtop -o | head -20

# Swap 使用情况
swapon --show
vmstat 1 3 | grep -E "si|so"   # si=swap in, so=swap out
```

**关键指标解读：**
| 指标 | 正常 | 警告 | 严重 |
|------|------|------|------|
| MemAvailable / MemTotal | > 30% | < 20% | < 10% |
| Swap 使用率 | 0% | > 10% | > 30% |
| Dirty / MemTotal | < 2% | > 5% | > 10% |
| vmstat si/so | = 0 | > 0 | 持续 > 100MB/s |

---

## 2. Swap 与 swappiness 调优

```bash
# 查看当前 swappiness
sysctl vm.swappiness

# 调整建议：
# 桌面系统：60（默认）
# 服务器：10（减少换页，优先使用内存）
# 数据库（MySQL/Redis）：1（几乎不换页）
sysctl -w vm.swappiness=10

# 持久化
echo "vm.swappiness=10" >> /etc/sysctl.d/99-performance-mastery.conf

# 创建 Swap 文件（系统无 Swap 时）
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

# 验证
free -h   # Swap 行应有数值
swapon --show

# 删除 Swap
swapoff /swapfile
rm /swapfile
sed -i '/swapfile/d' /etc/fstab
```

---

## 3. OOM Kill 处理与预防

```bash
# 查看 OOM 历史
dmesg | grep -iE "oom|killed process|out of memory" | tail -30

# 查看进程的 OOM 分数（越高越容易被杀）
cat /proc/<PID>/oom_score
cat /proc/<PID>/oom_score_adj   # -1000 永不被杀，+1000 最先被杀

# 保护关键进程（永不被 OOM Kill）
echo -1000 > /proc/<PID>/oom_score_adj    # 最高保护
echo -500  > /proc/<PID>/oom_score_adj    # 强保护

# 降低 OOM 保护（非关键进程）
echo 500 > /proc/<PID>/oom_score_adj

# 脚本：保护多个关键进程
protect_procs=("mysqld" "redis-server" "nginx" "knot-cli")
for proc in "${protect_procs[@]}"; do
    PID=$(pgrep -x "$proc" | head -1)
    if [[ -n "$PID" ]]; then
        echo -500 > /proc/$PID/oom_score_adj
        echo "Protected: $proc (PID=$PID)"
    fi
done

# 全局 overcommit 策略
sysctl vm.overcommit_memory   # 0=启发式(默认), 1=总是允许, 2=严格
# 建议保持默认 0，或改为 1（允许 overcommit，适合大多数应用）
# ⚠️ overcommit_memory=2 会导致很多应用启动失败，慎用

# 内存限制（用 systemd-run 包裹）
systemd-run --scope -p MemoryMax=2G ./high_mem_app

# 验证 OOM 频率是否下降
watch -n 2 'dmesg | grep -c "Out of memory"'
```

---

## 4. 透明大页 THP

```bash
# 查看当前状态
cat /sys/kernel/mm/transparent_hugepage/enabled
# [always] madvise never

# 何时关闭 THP：
# - MySQL / PostgreSQL / Oracle（官方建议关闭）
# - Redis（官方建议关闭）
# - 延迟敏感的实时应用
# - 出现内存碎片或 khugepaged CPU 占用高时

# 临时关闭
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 持久化（写入启动脚本）
cat > /etc/systemd/system/disable-thp.service << 'EOF'
[Unit]
Description=Disable Transparent Huge Pages
After=network.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"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now disable-thp.service

# 验证
cat /sys/kernel/mm/transparent_hugepage/enabled   # 应显示 never

# 仅对特定进程启用 THP（madvise 模式）
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
# 在代码中使用 madvise(addr, len, MADV_HUGEPAGE)
```

---

## 5. HugePage 配置

```bash
# 查看 HugePage 状态
grep -i huge /proc/meminfo

# 适用场景：数据库 SGA（Oracle/DB2）、Java 大堆、内存密集型计算

# 配置 HugePage 数量（2MB per page）
# 计算：如需 10GB HugePage → 10*1024/2 = 5120 pages
sysctl -w vm.nr_hugepages=5120

# 持久化
echo "vm.nr_hugepages=5120" >> /etc/sysctl.d/99-performance-mastery.conf

# 查看 HugePage 使用情况
cat /proc/meminfo | grep -i huge
# HugePages_Total: 5120
# HugePages_Free:  4096   ← 未使用的页数

# 透明大页 vs 静态 HugePage：
# - 静态 HugePage：需预分配，性能更稳定，适合数据库
# - THP：动态分配，更灵活，但可能导致延迟毛刺

# Java 使用 HugePage
java -XX:+UseLargePages -XX:LargePageSizeInBytes=2m -jar app.jar
```

---

## 6. 脏页回写调优

```bash
# 查看当前脏页状态
grep -E "Dirty|Writeback" /proc/meminfo

# 查看参数
sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_expire_centisecs vm.dirty_writeback_centisecs

# 参数说明：
# dirty_background_ratio：脏页超过此比例时后台回写开始（默认10%）
# dirty_ratio：脏页超过此比例时写操作被阻塞（默认20-40%）
# dirty_expire_centisecs：脏页超过此时间(cs)强制回写（默认3000 = 30s）
# dirty_writeback_centisecs：后台回写线程唤醒间隔（默认500 = 5s）

# 写密集场景（减少写回积压）
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_expire_centisecs=1500
sysctl -w vm.dirty_writeback_centisecs=500

# 高吞吐写场景（允许更多脏页积累）
sysctl -w vm.dirty_ratio=60
sysctl -w vm.dirty_background_ratio=40

# 绝对值控制（推荐用字节代替百分比，内存大时更精确）
sysctl -w vm.dirty_bytes=268435456        # 256MB 触发阻塞
sysctl -w vm.dirty_background_bytes=67108864  # 64MB 触发后台回写
# ⚠️ dirty_bytes 和 dirty_ratio 二选一，设置bytes时ratio失效

# 手动触发脏页回写（谨慎，会造成 I/O 尖峰）
sync; echo 1 > /proc/sys/vm/drop_caches   # 仅清页缓存
sync; echo 3 > /proc/sys/vm/drop_caches   # 清页缓存+dentries+inodes
```

---

## 7. 内存回收与 min_free_kbytes

```bash
# 查看内存水位
sysctl vm.min_free_kbytes

# 增大内核保留内存（防止因为瞬间分配导致 OOM）
# 建议：总内存 0.1%~1%，最少 64MB，最大 256MB
sysctl -w vm.min_free_kbytes=131072   # 128MB

# 内存紧张时策略
sysctl vm.vfs_cache_pressure   # 默认100，增大=更激进回收缓存，减小=保留更多缓存

# 主动触发内存回收（不影响应用，谨慎使用）
echo 1 > /proc/sys/vm/drop_caches   # page cache
echo 2 > /proc/sys/vm/drop_caches   # dentries & inodes
echo 3 > /proc/sys/vm/drop_caches   # all

# 查看各区域内存水位
cat /proc/zoneinfo | grep -A5 "Node 0, zone"
```

---

## 8. Slab 缓存优化

```bash
# 查看 Slab 使用
slabtop -o | head -20
cat /proc/slabinfo | sort -k3 -rn | head -20

# 查看 Slab 占用总量
grep Slab /proc/meminfo

# 如果 Slab 异常大（> 物理内存 20%），排查原因
# 常见原因：
# 1. dentries/inodes 过多（大量小文件）
# 2. TCP socket 泄漏
# 3. nf_conntrack 表满

# 清理 Slab 缓存
echo 2 > /proc/sys/vm/drop_caches   # 清 dentries/inodes slab
echo 3 > /proc/sys/vm/drop_caches   # 清所有可回收 slab

# 调整 slab 缩减策略
sysctl -w vm.vfs_cache_pressure=200   # 更积极地回收 VFS 缓存（默认100）
```

---

## 9. NUMA 内存优化

```bash
# 查看 NUMA 内存分布
numastat -m 2>/dev/null
numastat -p <PID> 2>/dev/null

# 检查 NUMA 命中率（numa_miss 高说明跨节点访存频繁）
numastat | grep -E "numa_hit|numa_miss|local_node|other_node"

# 开启 NUMA 自动均衡（多 NUMA 节点服务器默认开启）
sysctl -w kernel.numa_balancing=1

# 关闭 NUMA 均衡（延迟敏感场景，减少进程迁移）
sysctl -w kernel.numa_balancing=0

# 内存交错分配（适合均匀访问大内存的场景）
numactl --interleave=all ./app

# 绑定进程到指定 NUMA 节点
numactl --cpunodebind=0 --membind=0 ./app   # 绑定到 node0
```

---

## 10. 内存泄漏排查

```bash
# 监控进程内存趋势（每5秒）
watch -n 5 'ps -p <PID> -o pid,rss,vsz,comm'

# 详细内存映射
cat /proc/<PID>/smaps | awk '/Rss/{rss+=$2} END{print "RSS:", rss"KB"}'
cat /proc/<PID>/status | grep -E "VmRSS|VmSwap|VmPeak"

# Valgrind 内存泄漏检测（C/C++）
valgrind --leak-check=full --show-leak-kinds=all ./app

# AddressSanitizer（编译时开启，性能损耗约2x）
gcc -fsanitize=address -fno-omit-frame-pointer -g -O1 -o app_asan ./app.c
./app_asan   # 泄漏时会输出详细报告

# Java 堆分析
jmap -dump:format=b,file=heap.hprof <PID>
jhat heap.hprof   # 内置分析器
# 或使用 Eclipse MAT 分析 heap.hprof

# Python 内存分析
python3 -c "
import tracemalloc
tracemalloc.start()
# ... 运行代码 ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
    print(stat)
"
```

---

## 11. 容器内存限制排查

```bash
# 查看容器内存限制
cat /sys/fs/cgroup/memory/memory.limit_in_bytes
cat /sys/fs/cgroup/memory/memory.usage_in_bytes
cat /sys/fs/cgroup/memory/memory.failcnt          # 分配失败次数（高值说明频繁触碰上限）

# OOM Kill 记录
cat /sys/fs/cgroup/memory/memory.oom_control

# 计算实际可用内存
echo "限制: $(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024 / 1024 )) MB"
echo "使用: $(( $(cat /sys/fs/cgroup/memory/memory.usage_in_bytes) / 1024 / 1024 )) MB"

# Kubernetes Pod 内存
kubectl top pod <pod>
kubectl describe pod <pod> | grep -A5 "Limits\|Requests"
kubectl get events | grep OOMKilled

# 保护容器内关键进程
echo -500 > /proc/<PID>/oom_score_adj

# 运行高内存任务时限制（避免影响其他进程）
systemd-run --scope -p MemoryMax=512M python3 heavy_script.py
```


path: references/network.md
content: # 网络调优参考手册

## 目录
1. [快速诊断](#1-快速诊断)
2. [TCP 连接状态优化](#2-tcp-连接状态优化)
3. [TCP 缓冲区调优](#3-tcp-缓冲区调优)
4. [连接队列优化](#4-连接队列优化)
5. [端口与文件描述符](#5-端口与文件描述符)
6. [BBR 拥塞控制](#6-bbr-拥塞控制)
7. [conntrack 连接跟踪](#7-conntrack-连接跟踪)
8. [网卡多队列与 RPS/RFS](#8-网卡多队列与-rpsrfs)
9. [网络延迟排查](#9-网络延迟排查)
10. [高并发服务完整配置示例](#10-高并发服务完整配置示例)

---

## 1. 快速诊断

```bash
# 连接状态统计
ss -s

# TCP 连接状态分布
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn

# 网络错误统计（关注非0项）
netstat -s 2>/dev/null | grep -E "fail|error|drop|overflow|reject|retransmit" | grep -v "^    0"

# 网络接口统计（RX/TX 错误）
ip -s link | grep -A5 "eth0\|ens\|bond"
netstat -i

# 网络连接数量
ss -ant | wc -l

# 实时网络流量
sar -n DEV 1 5 2>/dev/null || ip -s link

# conntrack 状态
cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null
cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null
```

**关键指标解读：**
| 指标 | 正常 | 告警 |
|------|------|------|
| TIME_WAIT 数量 | < 5000 | > 10000（端口耗尽风险） |
| CLOSE_WAIT 数量 | < 100 | > 1000（代码未关闭连接） |
| 重传率 | < 0.1% | > 1% |
| conntrack 使用率 | < 60% | > 80% |

---

## 2. TCP 连接状态优化

```bash
# 查看当前参数
sysctl net.ipv4.tcp_tw_reuse
sysctl net.ipv4.tcp_fin_timeout
sysctl net.ipv4.tcp_keepalive_time

# TIME_WAIT 优化（高并发短连接场景）
# 启用 TIME_WAIT 连接重用
sysctl -w net.ipv4.tcp_tw_reuse=1       # 允许重用 TIME_WAIT socket（连接发起方）
# ⚠️ tcp_tw_recycle 在内核 4.12+ 已移除，勿使用

# 缩短 FIN_TIMEOUT（加速 TIME_WAIT 回收）
sysctl -w net.ipv4.tcp_fin_timeout=30   # 默认60s，缩短到30s

# TIME_WAIT bucket 数量（防止 TIME_WAIT 桶溢出）
sysctl -w net.ipv4.tcp_max_tw_buckets=262144   # 默认180000

# Keepalive 优化（长连接场景）
sysctl -w net.ipv4.tcp_keepalive_time=600      # 600s 无数据后发探测（默认7200s）
sysctl -w net.ipv4.tcp_keepalive_intvl=30      # 探测间隔30s
sysctl -w net.ipv4.tcp_keepalive_probes=5      # 发5次探测后断开

# CLOSE_WAIT 过多（通常是代码问题，应用层未调用 close()）
# 快速定位：查看哪个进程持有大量 CLOSE_WAIT
ss -antp state close-wait | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
EOF
```

---

## 3. TCP 缓冲区调优

```bash
# 查看当前缓冲区设置
sysctl net.core.rmem_max net.core.wmem_max
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem

# 高带宽场景优化（万兆网络 / 高延迟 WAN）
# BDP (带宽延迟积) = 带宽 × RTT
# 例：10Gbps × 50ms RTT → BDP = 62.5MB

# 增大 Socket 缓冲区
sysctl -w net.core.rmem_max=134217728     # 128MB
sysctl -w net.core.wmem_max=134217728     # 128MB
sysctl -w net.core.rmem_default=262144    # 256KB
sysctl -w net.core.wmem_default=262144    # 256KB

# TCP 自动调整缓冲区（最小/默认/最大）
sysctl -w net.ipv4.tcp_rmem="4096 131072 67108864"   # 4KB/128KB/64MB
sysctl -w net.ipv4.tcp_wmem="4096 131072 67108864"

# 启用 TCP 缓冲区自动调整
sysctl -w net.ipv4.tcp_moderate_rcvbuf=1

# 内存缓冲区总量（TCP 使用的总内存：最小/压力/最大，单位页）
sysctl -w net.ipv4.tcp_mem="262144 524288 1048576"

# 高并发低延迟场景（减小缓冲区，降低延迟）
sysctl -w net.ipv4.tcp_rmem="4096 32768 1048576"
sysctl -w net.ipv4.tcp_wmem="4096 32768 1048576"

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 131072 67108864
net.ipv4.tcp_wmem = 4096 131072 67108864
net.ipv4.tcp_moderate_rcvbuf = 1
EOF
```

---

## 4. 连接队列优化

```bash
# 查看当前队列设置
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
sysctl net.core.netdev_max_backlog

# 检查队列溢出（关注 "times the listen queue" 行）
netstat -s | grep -i listen
ss -lnt   # 查看各 LISTEN 端口的 Recv-Q（应接近0）

# 高并发服务优化
sysctl -w net.core.somaxconn=65535            # accept 队列大小（默认 4096（5.4+）/ 128（旧内核））
sysctl -w net.ipv4.tcp_max_syn_backlog=65535  # SYN 队列大小（默认1024）
sysctl -w net.core.netdev_max_backlog=65535   # 网卡接收队列（默认1000）

# 开启 SYN Cookie（防 SYN Flood 同时保证 SYN 队列不溢出）
sysctl -w net.ipv4.tcp_syncookies=1

# ⚠️ somaxconn 设置后，应用层 listen(fd, backlog) 的 backlog 也要同步调大
# Nginx: listen 80 backlog=65535;
# Java: new ServerSocket(port, 65535);

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_syncookies = 1
EOF
```

---

## 5. 端口与文件描述符

```bash
# 查看本地端口范围
sysctl net.ipv4.ip_local_port_range   # 默认：32768 60999（约28000个）

# 扩大端口范围（主动发起大量连接的服务）
sysctl -w net.ipv4.ip_local_port_range="1024 65535"   # 约64000个

# 查看文件描述符限制
ulimit -n          # 当前进程限制
cat /proc/sys/fs/file-max   # 系统全局限制
cat /proc/sys/fs/file-nr    # 已分配/空闲/最大

# 增大文件描述符（系统级）
sysctl -w fs.file-max=2097152

# 增大文件描述符（用户级，/etc/security/limits.conf）
cat >> /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
EOF

# 当前 session 临时生效
ulimit -n 65535

# 针对特定服务（systemd unit）
# [Service]
# LimitNOFILE=65535

# 验证服务的文件描述符限制
cat /proc/<PID>/limits | grep "open files"

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
fs.file-max = 2097152
net.ipv4.ip_local_port_range = 1024 65535
EOF
```

---

## 6. BBR 拥塞控制

```bash
# 查看当前拥塞控制算法
sysctl net.ipv4.tcp_congestion_control
cat /proc/sys/net/ipv4/tcp_available_congestion_control

# 开启 BBR（内核 4.9+，显著提升高延迟/丢包网络性能）
modprobe tcp_bbr 2>/dev/null
echo tcp_bbr >> /etc/modules-load.d/modules.conf

sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq   # BBR 推荐搭配 fq 队列

# 验证
sysctl net.ipv4.tcp_congestion_control   # 应显示 bbr
lsmod | grep bbr

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF

# BBR 效果最显著的场景：
# - 广域网高延迟（跨地域）
# - 有一定丢包率（1-5%）的网络
# - 大文件传输

# 回滚
sysctl -w net.ipv4.tcp_congestion_control=cubic
```

---

## 7. conntrack 连接跟踪

```bash
# 查看 conntrack 使用情况
cat /proc/sys/net/netfilter/nf_conntrack_count   # 当前连接数
cat /proc/sys/net/netfilter/nf_conntrack_max     # 最大连接数

# 使用率计算
count=$(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)
max=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null)
echo "conntrack 使用率: $((count * 100 / max))% ($count/$max)"

# 扩大 conntrack 表
sysctl -w net.netfilter.nf_conntrack_max=1048576

# 缩短 conntrack 超时（减少表项占用）
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=600   # 默认432000s(5天)→600s
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=60      # 默认120s→60s
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_close_wait=60
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_fin_wait=60

# 查看 conntrack 表内容
conntrack -L 2>/dev/null | head -20
conntrack -L 2>/dev/null | wc -l   # 统计条数

# ⚠️ conntrack 耗尽会导致新连接被拒绝，症状：
# kernel: nf_conntrack: table full, dropping packet.
# 监控：
dmesg | grep "nf_conntrack: table full" | tail -5

# 持久化
cat >> /etc/sysctl.d/99-performance-mastery.conf << 'EOF'
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 600
EOF
```

---

## 8. 网卡多队列与 RPS/RFS

```bash
# 查看网卡队列数
ls /sys/class/net/eth0/queues/
ethtool -l eth0 2>/dev/null | head -10

# 设置网卡多队列（需网卡支持）
ethtool -L eth0 combined 8   # 8个收发合并队列

# RPS（接收端包处理分发，软件模拟多队列）
# 将接收到的包分发到所有 CPU 处理
for rxq in /sys/class/net/eth0/queues/rx-*/rps_cpus; do
    echo ff > $rxq   # 所有CPU参与（ff=8核，ffff=16核）
done

# RFS（接收端流向目标，让数据包在发起进程的 CPU 上处理）
sysctl -w net.core.rps_sock_flow_entries=32768
for rxq in /sys/class/net/eth0/queues/rx-*/rps_flow_cnt; do
    echo 4096 > $rxq
done

# XPS（发送端分发，将不同流的包分配到不同 CPU）
for txq in /sys/class/net/eth0/queues/tx-*/xps_cpus; do
    echo ff > $txq
done

# 检查网卡中断绑核状态
cat /proc/interrupts | grep eth0

# 网卡 Ring Buffer 大小（减少丢包）
ethtool -g eth0 2>/dev/null     # 查看
ethtool -G eth0 rx 4096 tx 4096  # 设置4096
```

---

## 9. 网络延迟排查

```bash
# 基础延迟测量
ping -c 100 <target_ip> | tail -3   # 查看 avg/mdev

# 路由追踪（发现中间节点瓶颈）
traceroute -n <target_ip>
mtr --report --report-cycles 100 <target_ip>   # 更详细

# TCP 连接延迟（包含 DNS + TCP 握手 + TLS）
curl -o /dev/null -s -w "\n\
DNS:       %{time_namelookup}s\n\
Connect:   %{time_connect}s\n\
TLS:       %{time_appconnect}s\n\
TTFB:      %{time_starttransfer}s\n\
Total:     %{time_total}s\n" https://example.com

# 丢包测量
ping -c 1000 -i 0.01 <target_ip> | tail -3   # 快速ping 1000次

# 查看 TCP 重传详情
ss -ti dst <target_ip>   # 查看特定连接的重传统计

# 网络延迟抖动（jitter）
ping -c 100 <target_ip> | awk -F/ '/avg/ {print "jitter(mdev):", $5 "ms"}'

# 检查本地网络队列延迟
tc qdisc show dev eth0   # 查看队列规则
```

---

## 10. 高并发服务完整配置示例

> 适用：Nginx/Go/Node.js HTTP 服务，QPS 5000+，短连接为主

```bash
cat > /etc/sysctl.d/99-highperf-network.conf << 'EOF'
# === 连接队列 ===
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_syncookies = 1

# === TIME_WAIT 优化 ===
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 262144

# === 端口范围 ===
net.ipv4.ip_local_port_range = 1024 65535

# === 文件描述符 ===
fs.file-max = 2097152

# === TCP 缓冲区 ===
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 131072 67108864
net.ipv4.tcp_wmem = 4096 131072 67108864
net.ipv4.tcp_moderate_rcvbuf = 1

# === Keepalive ===
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

# === BBR 拥塞控制 ===
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq

# === conntrack ===
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 600
EOF

sysctl -p /etc/sysctl.d/99-highperf-network.conf

# 验证生效
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_congestion_control
ss -s
```


path: references/nodejs_performance.md
content: # Node.js 性能分析与优化指南

## 目录
1. [1. 分析工具](#1-分析工具)
2. [2. V8 引擎与内存管理](#2-v8-引擎与内存管理)
3. [3. GC 调优](#3-gc-调优)
4. [4. 内存泄漏排查](#4-内存泄漏排查)
5. [5. 事件循环优化](#5-事件循环优化)
6. [6. 优化模式](#6-优化模式)
7. [7. HTTP/网络优化](#7-http网络优化)
8. [8. APM 与监控](#8-apm-与监控)
9. [9. 常见问题速查](#9-常见问题速查)

---

## 1. 分析工具

```bash
# Node.js 内置 profiler
node --prof app.js
node --prof-process isolate-*.log > profile.txt

# Chrome DevTools（推荐交互式分析）
node --inspect app.js
# 打开 chrome://inspect 连接

# clinic.js（最推荐，自动诊断）
npx clinic doctor -- node app.js       # 自动诊断瓶颈类型
npx clinic flame -- node app.js        # CPU 火焰图
npx clinic bubbleprof -- node app.js   # I/O 异步分析
npx clinic heapprofiler -- node app.js # 堆内存分析

# 0x 火焰图
npx 0x app.js

# autocannon（HTTP 压测）
npx autocannon -c 100 -d 30 http://localhost:3000
```

---

## 2. V8 引擎与内存管理

### V8 内存结构

```text
V8 堆内存
├── 新生代（Young Generation）— 短生命周期对象
│   ├── Semi-space From（活跃区）
│   └── Semi-space To（GC 时交换）
├── 老生代（Old Generation）— 长生命周期对象
│   ├── Old Pointer Space（含指针的对象）
│   └── Old Data Space（纯数据对象）
├── 大对象空间（Large Object Space）— > 页大小的对象
├── 代码空间（Code Space）— JIT 编译后的代码
└── Map Space — Hidden Class / Map 对象
```

### 关键内存参数

```bash
# 查看默认堆大小（64 位系统通常 ~1.5GB）
node -e "console.log(v8.getHeapStatistics())"

# 调整最大堆内存（OOM 时首先考虑）
node --max-old-space-size=4096 app.js    # 设为 4GB
node --max-semi-space-size=64 app.js     # 新生代半空间 64MB（默认 16MB）

# 查看内存使用
node -e "
const m = process.memoryUsage();
console.log({
  rss: (m.rss / 1024 / 1024).toFixed(1) + 'MB',
  heapTotal: (m.heapTotal / 1024 / 1024).toFixed(1) + 'MB',
  heapUsed: (m.heapUsed / 1024 / 1024).toFixed(1) + 'MB',
  external: (m.external / 1024 / 1024).toFixed(1) + 'MB',
  arrayBuffers: (m.arrayBuffers / 1024 / 1024).toFixed(1) + 'MB'
});
"
```

### V8 优化杀手（Deoptimization）

```javascript
// ❌ 避免：改变对象形状（Hidden Class 变化）
const obj = {};
obj.a = 1;
obj.b = 2;  // 每次添加属性都会创建新 Hidden Class

// ✅ 推荐：预先定义所有属性
const obj = { a: 1, b: 2 };

// ❌ 避免：delete 操作符（触发去优化）
delete obj.prop;

// ✅ 推荐：设为 undefined
obj.prop = undefined;

// ❌ 避免：try-catch 包裹大段代码（阻止优化）
// ✅ 推荐：只包裹可能抛异常的最小代码段

// ❌ 避免：混合类型数组
const arr = [1, 'two', 3.0, null];  // V8 退化为通用数组

// ✅ 推荐：保持类型一致
const nums = [1, 2, 3, 4];  // V8 使用 SMI 或 Double 数组
```

---

## 3. GC 调优

### GC 类型

| GC 类型 | 作用域 | STW 时间 | 触发条件 |
|---------|--------|----------|----------|
| Scavenge | 新生代 | 1-5ms | 新生代半空间满 |
| Mark-Sweep | 老生代 | 10-100ms+ | 老生代空间不足 |
| Mark-Compact | 老生代 | 较长 | 老生代碎片化严重 |
| Incremental Marking | 老生代 | 分步 | 渐进式标记 |

### GC 诊断命令

```bash
# 输出 GC 日志
node --trace-gc app.js
# 输出示例: [12345:0x...] 42 ms: Scavenge 8.2 (10.0) -> 4.1 (10.0) MB, 1.2 / 0.0 ms

# 详细 GC 日志
node --trace-gc --trace-gc-verbose app.js

# 暴露 GC 手动触发（仅调试用）
node --expose-gc -e "global.gc(); console.log(process.memoryUsage())"

# 限制 GC 暂停时间（实验性）
node --max-old-space-size=4096 --optimize-for-size app.js
```

### GC 优化策略

```javascript
// 1. 减少短生命周期对象分配
// ❌ 每次请求创建新对象
app.get('/', (req, res) => {
  const config = { timeout: 5000, retries: 3 };  // 每次请求都分配
});

// ✅ 复用对象
const CONFIG = Object.freeze({ timeout: 5000, retries: 3 });
app.get('/', (req, res) => {
  // 直接使用 CONFIG
});

// 2. 对象池模式
class ObjectPool {
  constructor(factory, size = 100) {
    this.factory = factory;
    this.pool = Array.from({ length: size }, factory);
  }
  acquire() { return this.pool.pop() || this.factory(); }
  release(obj) { this.pool.push(obj); }
}

// 3. Buffer 复用
const bufferPool = Buffer.allocUnsafe(64 * 1024);  // 预分配
// 而非每次 Buffer.alloc(64 * 1024)
```

---

## 4. 内存泄漏排查

### 常见泄漏源

```javascript
// 1. 事件监听器未清理
emitter.on('data', handler);  // 累积
// 修复：
emitter.removeListener('data', handler);
// 或使用 once：
emitter.once('data', handler);

// 2. 闭包引用
function createLeak() {
  const bigData = new Array(1000000).fill('x');
  return function() {
    // bigData 被闭包引用，永远不会被 GC
    console.log(bigData.length);
  };
}

// 3. 全局缓存无上限
const cache = {};
function addToCache(key, value) {
  cache[key] = value;  // 永远增长
}
// 修复：使用 LRU 缓存
const LRU = require('lru-cache');
const cache = new LRU({ max: 500, ttl: 1000 * 60 * 5 });

// 4. 定时器未清理
const timer = setInterval(() => { /* ... */ }, 1000);
// 修复：
clearInterval(timer);

// 5. Promise 未处理
async function leak() {
  const promises = [];
  for (let i = 0; i < 100000; i++) {
    promises.push(fetch(url));  // 大量 pending Promise
  }
  // 修复：限制并发
}
```

### 排查工具

```bash
# heapdump 快照对比（生产环境推荐）
npm install heapdump
# 代码中：
# require('heapdump');
# kill -USR2 <pid>  → 生成 heapdump-*.heapsnapshot

# 使用 Chrome DevTools 对比两个快照
# Memory → Load → Comparison 视图

# 使用 memwatch-next 自动检测
npm install @airbnb/node-memwatch
# const memwatch = require('@airbnb/node-memwatch');
# memwatch.on('leak', (info) => console.log('Leak:', info));

# 进程级内存监控
node -e "
setInterval(() => {
  const m = process.memoryUsage();
  console.log(new Date().toISOString(),
    'RSS:', (m.rss/1024/1024).toFixed(1)+'MB',
    'Heap:', (m.heapUsed/1024/1024).toFixed(1)+'MB');
}, 5000);
"
```

---

## 5. 事件循环优化

### 事件循环阶段

```text
   ┌───────────────────────────┐
┌─>│         timers             │  setTimeout / setInterval
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks      │  I/O 回调
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare        │  内部使用
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │         poll               │  新 I/O 事件（最重要）
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │         check              │  setImmediate
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │    close callbacks         │  socket.on('close')
│  └─────────────┬─────────────┘
└─────────────────┘
```

### 监控事件循环延迟

```javascript
// 方法 1: monitorEventLoopDelay（Node.js >= 11.10）
const { monitorEventLoopDelay } = require('perf_hooks');
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
setInterval(() => {
  console.log(`EL delay: min=${h.min/1e6}ms p50=${h.percentile(50)/1e6}ms p99=${h.percentile(99)/1e6}ms max=${h.max/1e6}ms`);
  h.reset();
}, 5000);

// 方法 2: 简单的事件循环延迟检测
let lastCheck = Date.now();
setInterval(() => {
  const now = Date.now();
  const delay = now - lastCheck - 1000;  // 预期 1000ms
  if (delay > 50) console.warn(`Event loop delay: ${delay}ms`);
  lastCheck = now;
}, 1000);
```

### 避免阻塞事件循环

```javascript
// ❌ 同步 JSON 解析大文件
const data = JSON.parse(fs.readFileSync('huge.json'));

// ✅ 流式解析
const JSONStream = require('JSONStream');
fs.createReadStream('huge.json')
  .pipe(JSONStream.parse('*'))
  .on('data', item => process(item));

// ❌ CPU 密集型计算在主线程
function fibonacci(n) { /* ... */ }

// ✅ 移到 Worker Thread
const { Worker } = require('worker_threads');
const worker = new Worker('./fib-worker.js', { workerData: { n: 45 } });
worker.on('message', result => console.log(result));

// ❌ 大数组同步排序
bigArray.sort((a, b) => a - b);

// ✅ 分批处理（避免长时间占用事件循环）
async function sortInChunks(arr, chunkSize = 10000) {
  for (let i = 0; i < arr.length; i += chunkSize) {
    arr.slice(i, i + chunkSize).sort((a, b) => a - b);
    await new Promise(resolve => setImmediate(resolve));  // 让出事件循环
  }
}
```

---

## 6. 优化模式

### 1. 不阻塞事件循环

```javascript
// 差：同步 I/O 阻塞
const data = fs.readFileSync('large.json');

// 好：异步
const data = await fs.promises.readFile('large.json');
```

### 2. 流式处理大文件

```javascript
// 好：恒定内存
const stream = fs.createReadStream('huge.csv');
stream.pipe(transform).pipe(output);

// 差：全部载入内存
const data = fs.readFileSync('huge.csv');
```

### 3. Worker Threads 处理 CPU 密集

```javascript
const { Worker, isMainThread, parentPort } = require('worker_threads');

if (isMainThread) {
    const worker = new Worker(__filename, { workerData: input });
    worker.on('message', result => console.log(result));
} else {
    const result = heavyComputation(workerData);
    parentPort.postMessage(result);
}
```

### 4. 连接池

```javascript
// MySQL
const pool = mysql.createPool({
    connectionLimit: 10,
    host: 'localhost',
    user: 'root',
    database: 'mydb'
});

// PostgreSQL (pg)
const pool = new Pool({ max: 20 });
```

### 5. JSON 序列化优化

```javascript
// 大对象用 fast-json-stringify（快 2-5x）
const fastJson = require('fast-json-stringify');
const stringify = fastJson({
    type: 'object',
    properties: {
        name: { type: 'string' },
        age: { type: 'integer' }
    }
});
const json = stringify({ name: 'test', age: 30 });
```

### 6. 缓存

```javascript
// 简单内存缓存
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 });

// Redis 缓存
const Redis = require('ioredis');
const redis = new Redis();
```

### 7. 集群模式

```javascript
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isPrimary) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    // 工作进程
    require('./app');
}
```

---

## 7. HTTP/网络优化

### HTTP Keep-Alive

```javascript
const http = require('http');
const agent = new http.Agent({
  keepAlive: true,
  keepAliveMsecs: 30000,
  maxSockets: 100,
  maxFreeSockets: 10
});

// 使用 undici（比 http 模块快 2-3x）
const { request } = require('undici');
const { statusCode, body } = await request('http://api.example.com/data');
```

### HTTP/2 服务器

```javascript
const http2 = require('http2');
const server = http2.createSecureServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
});
server.on('stream', (stream, headers) => {
  stream.respond({ ':status': 200 });
  stream.end('Hello HTTP/2');
});
```

### 响应压缩

```javascript
// Express
const compression = require('compression');
app.use(compression({ threshold: 1024 }));  // > 1KB 才压缩

// Fastify（推荐，比 Express 快 2-3x）
const fastify = require('fastify')({ logger: true });
await fastify.register(require('@fastify/compress'));
```

---

## 8. APM 与监控

### Prometheus + Grafana

```javascript
// prom-client（Node.js Prometheus 客户端）
const client = require('prom-client');

// 收集默认指标（GC、事件循环、内存等）
client.collectDefaultMetrics({ timeout: 5000 });

// 自定义指标
const httpDuration = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration',
  labelNames: ['method', 'route', 'status'],
  buckets: [0.01, 0.05, 0.1, 0.5, 1, 5]
});

app.use((req, res, next) => {
  const end = httpDuration.startTimer();
  res.on('finish', () => {
    end({ method: req.method, route: req.route?.path, status: res.statusCode });
  });
  next();
});

app.get('/metrics', async (req, res) => {
  res.set('Content-Type', client.register.contentType);
  res.end(await client.register.metrics());
});
```

### PM2 生产部署

```bash
# 集群模式启动（自动利用所有 CPU）
pm2 start app.js -i max --name myapp

# 监控面板
pm2 monit

# 查看日志
pm2 logs myapp --lines 100

# 内存限制自动重启
pm2 start app.js --max-memory-restart 1G

# 生态系统配置文件 ecosystem.config.js
# module.exports = {
#   apps: [{
#     name: 'myapp',
#     script: 'app.js',
#     instances: 'max',
#     exec_mode: 'cluster',
#     max_memory_restart: '1G',
#     env: { NODE_ENV: 'production' }
#   }]
# };
```

---

## 9. 常见问题速查

| 问题 | 诊断 | 解决 |
|------|------|------|
| 事件循环阻塞 | `clinic doctor` | 异步化或移到 Worker |
| 内存泄漏 | `clinic heapprofiler` / heapdump 对比 | 检查闭包、事件监听器、全局缓存、定时器 |
| CPU 热点 | `clinic flame` / `0x` | 优化算法或移到 Worker Thread |
| 高 GC 暂停 | `--trace-gc` | 减少短生命周期对象分配、对象池、预分配 |
| OOM Crash | `--max-old-space-size` | 增大堆限制、排查泄漏、流式处理 |
| 连接耗尽 | `ss -ant` + `wc -l` | 连接池、Keep-Alive、限制并发 |
| 启动慢 | `node --trace-warnings` | 延迟加载模块、减少同步 require |
| HTTP 吞吐低 | `autocannon` | 换 Fastify、启用 cluster、HTTP/2 |

### 性能参考基准

| 场景 | 框架 | 典型 QPS (单核) |
|------|------|:-:|
| Hello World | Express | ~15,000 |
| Hello World | Fastify | ~45,000 |
| Hello World | uWebSockets.js | ~100,000+ |
| JSON 序列化 | 原生 JSON.stringify | ~2M ops/s |
| JSON 序列化 | fast-json-stringify | ~8M ops/s |


path: references/python_performance.md
content: # Python 性能分析与优化指南

> Python 因 GIL（全局解释器锁）和动态类型的特性，在性能调优上有独特的挑战和方法。本文档覆盖 CPython 性能分析工具链、常见瓶颈优化、并发模型选择及生产环境最佳实践。

---


## 目录

- [1. 性能分析工具链](#1-性能分析工具链)
- [2. 常见性能瓶颈与优化](#2-常见性能瓶颈与优化)
- [3. 并发模型选择](#3-并发模型选择)
- [4. 高性能替代方案](#4-高性能替代方案)
- [5. Web 应用性能优化](#5-web-应用性能优化)
- [6. 性能诊断快速参考](#6-性能诊断快速参考)
- [7. 生产环境最佳实践](#7-生产环境最佳实践)
## 1. 性能分析工具链

### 1.1 cProfile / profile（CPU 分析）

**内置 CPU 分析器（推荐 cProfile，C 实现，开销小）：**

```bash
# 命令行直接分析
python -m cProfile -s cumulative myapp.py

# 输出到文件（供 pstats/snakeviz 分析）
python -m cProfile -o profile.out myapp.py
```

**代码内嵌分析：**
```python
import cProfile
import pstats

profiler = cProfile.Profile()
profiler.enable()
# ... 待分析代码 ...
profiler.disable()

stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats(20)  # 前20热点
```

**可视化工具：**
```bash
# snakeviz（交互式火焰图）
pip install snakeviz
snakeviz profile.out

# gprof2dot（调用图）
pip install gprof2dot
gprof2dot -f pstats profile.out | dot -Tpng -o output.png
```

### 1.2 line_profiler（逐行分析）

```bash
pip install line_profiler
```

```python
# 装饰目标函数
@profile
def slow_function():
    result = []
    for i in range(10000):
        result.append(i ** 2)
    return sum(result)
```

```bash
# 运行
kernprof -l -v myapp.py
# 输出每行的执行次数、总耗时、单次耗时
```

### 1.3 memory_profiler（内存分析）

```bash
pip install memory_profiler
```

```python
from memory_profiler import profile

@profile
def memory_heavy():
    a = [i for i in range(1000000)]
    b = {i: i*2 for i in range(500000)}
    del a
    return b
```

```bash
# 运行
python -m memory_profiler myapp.py

# 内存随时间变化图
mprof run myapp.py
mprof plot
```

### 1.4 py-spy（生产环境采样分析）

**无需修改代码、无需重启进程，直接附加到运行中的 Python 进程：**

```bash
pip install py-spy

# 实时 top 视图
py-spy top --pid <PID>

# 生成火焰图
py-spy record -o flamegraph.svg --pid <PID> --duration 30

# 生成 speedscope 格式（推荐，交互更好）
py-spy record -o profile.speedscope --format speedscope --pid <PID>

# 采样子线程
py-spy record --pid <PID> --threads

# 采样 native C 扩展
py-spy record --pid <PID> --native
```

### 1.5 tracemalloc（内存分配追踪）

```python
import tracemalloc

tracemalloc.start()

# ... 业务代码 ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

print("[ Top 10 内存分配 ]")
for stat in top_stats[:10]:
    print(stat)
```

**对比两个时间点的内存变化：**
```python
tracemalloc.start()
snapshot1 = tracemalloc.take_snapshot()

# ... 执行一段代码 ...

snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')

for stat in top_stats[:10]:
    print(stat)
```

### 1.6 timeit（微基准测试）

```bash
# 命令行
python -m timeit -n 1000000 '"hello" + " " + "world"'
python -m timeit -n 1000000 'f"hello world"'
```

```python
import timeit

# 代码内
result = timeit.timeit(
    stmt='sum(range(1000))',
    number=10000
)
print(f"耗时: {result:.4f}s")
```

---

## 2. 常见性能瓶颈与优化

### 2.1 数据结构与算法优化

```python
# ❌ 列表查找 O(n)
if item in my_list:  # 大列表很慢
    pass

# ✅ 集合查找 O(1)
my_set = set(my_list)
if item in my_set:
    pass

# ❌ 频繁列表头部插入 O(n)
my_list.insert(0, item)

# ✅ 使用 deque O(1)
from collections import deque
d = deque()
d.appendleft(item)

# ❌ 计数用字典手动实现
counts = {}
for item in items:
    counts[item] = counts.get(item, 0) + 1

# ✅ 使用 Counter
from collections import Counter
counts = Counter(items)

# ❌ 排序后取 Top-K（全排序 O(n log n)）
sorted(items)[:k]

# ✅ heapq 取 Top-K O(n log k)
import heapq
heapq.nlargest(k, items)
```

### 2.2 循环与计算优化

```python
# ❌ Python 循环（慢）
result = 0
for i in range(1000000):
    result += i * i

# ✅ 使用内置函数 / 生成器表达式
result = sum(i * i for i in range(1000000))

# ✅ NumPy 向量化（数值计算场景，快 10-100x）
import numpy as np
arr = np.arange(1000000)
result = np.sum(arr * arr)

# ❌ 逐行处理 CSV
with open('data.csv') as f:
    for line in f:
        parts = line.strip().split(',')
        # ...

# ✅ pandas 批量处理
import pandas as pd
df = pd.read_csv('data.csv')
# 向量化操作
```

### 2.3 字符串处理优化

```python
# ❌ 字符串拼接（每次创建新对象）
s = ""
for item in items:
    s += str(item) + ","

# ✅ join（一次分配）
s = ",".join(str(item) for item in items)

# ✅ f-string（Python 3.6+，最快的格式化方式）
name, age = "Alice", 30
s = f"{name} is {age} years old"

# ❌ 正则表达式未编译（每次重新编译）
import re
for line in lines:
    re.search(r'\d+', line)

# ✅ 预编译正则
pattern = re.compile(r'\d+')
for line in lines:
    pattern.search(line)
```

### 2.4 I/O 优化

```python
# ❌ 逐行写文件（频繁系统调用）
with open('output.txt', 'w') as f:
    for line in lines:
        f.write(line + '\n')

# ✅ 批量写入
with open('output.txt', 'w') as f:
    f.writelines(line + '\n' for line in lines)

# ✅ 使用更大的缓冲区
with open('output.txt', 'w', buffering=64*1024) as f:
    for line in lines:
        f.write(line + '\n')

# ✅ JSON 大文件流式处理
import ijson  # pip install ijson
with open('large.json', 'rb') as f:
    for item in ijson.items(f, 'item'):
        process(item)
```

### 2.5 内存优化

```python
# ❌ 大列表全部加载到内存
data = [process(line) for line in open('huge.txt')]

# ✅ 生成器惰性求值
def process_lines(filename):
    with open(filename) as f:
        for line in f:
            yield process(line)

# ❌ 类实例默认使用 __dict__（每个实例约 200+ 字节开销）
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# ✅ __slots__（减少 40-50% 内存，访问也更快）
class Point:
    __slots__ = ('x', 'y')
    def __init__(self, x, y):
        self.x = x
        self.y = y

# ✅ namedtuple（不可变，内存更小）
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])

# ✅ dataclass + slots（Python 3.10+）
from dataclasses import dataclass

@dataclass(slots=True)
class Point:
    x: float
    y: float
```

---

## 3. 并发模型选择

### 3.1 GIL 影响与对策

Python 的 GIL（全局解释器锁）限制了 CPU 密集型任务的多线程并行：

| 场景 | 推荐方案 | 说明 |
|------|---------|------|
| CPU 密集型 | `multiprocessing` / `ProcessPoolExecutor` | 多进程绕过 GIL |
| I/O 密集型 | `asyncio` / `ThreadPoolExecutor` | GIL 在 I/O 等待时释放 |
| CPU + I/O 混合 | 多进程 + 异步 I/O | 进程内用 asyncio |
| 数值计算 | NumPy/Pandas（C 扩展自动释放 GIL） | 无需额外并发 |

### 3.2 asyncio（异步 I/O）

```python
import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as resp:
        return await resp.text()

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
    return results

asyncio.run(main())
```

**asyncio 性能要点：**
- 避免在 async 函数中调用阻塞 I/O（用 `run_in_executor` 包装）
- 控制并发数量（`asyncio.Semaphore`）
- 使用 `uvloop` 替代默认事件循环（性能提升 2-4x）

```bash
pip install uvloop
```
```python
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
```

### 3.3 multiprocessing（CPU 密集型）

```python
from concurrent.futures import ProcessPoolExecutor
import os

def cpu_heavy(n):
    return sum(i * i for i in range(n))

with ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
    results = list(executor.map(cpu_heavy, [10**6] * 100))
```

**注意事项：**
- 进程间数据传递有序列化开销（pickle）
- 避免传递大对象，使用共享内存（`multiprocessing.shared_memory`）
- 子进程数量不要超过 CPU 核数

---

## 4. 高性能替代方案

### 4.1 Cython（C 扩展编译）

```python
# mymodule.pyx
def compute(int n):
    cdef int i
    cdef double result = 0.0
    for i in range(n):
        result += i * i
    return result
```

```bash
# 编译
cythonize -i mymodule.pyx
```

### 4.2 Numba（JIT 编译）

```python
from numba import jit

@jit(nopython=True)
def compute(n):
    result = 0.0
    for i in range(n):
        result += i * i
    return result

# 首次调用编译，后续调用接近 C 速度
compute(10000000)
```

### 4.3 PyPy（替代解释器）

```bash
# 直接替换 CPython（大部分纯 Python 代码兼容）
pypy3 myapp.py
# 通常 3-10x 加速，无需修改代码
```

**适用场景：** 纯 Python 逻辑密集型代码
**不适用：** 依赖大量 C 扩展的项目（NumPy/Pandas 等）

---

## 5. Web 应用性能优化

### 5.1 WSGI/ASGI 服务器选择

| 服务器 | 类型 | 适用场景 | 性能 |
|--------|------|---------|------|
| gunicorn + sync workers | WSGI | Django/Flask 传统同步 | ★★★ |
| gunicorn + uvicorn workers | ASGI | FastAPI/Starlette | ★★★★ |
| uvicorn | ASGI | FastAPI/Starlette | ★★★★★ |
| hypercorn | ASGI | HTTP/2 + WebSocket | ★★★★ |

**gunicorn 生产配置：**
```bash
# 同步 worker（CPU 密集型）
gunicorn app:app -w $(( $(nproc) * 2 + 1 )) -b 0.0.0.0:8000

# 异步 worker（I/O 密集型）
gunicorn app:app -w $(nproc) -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000

# 关键参数
# --timeout 30          # worker 超时
# --max-requests 1000   # worker 处理 N 个请求后重启（防内存泄漏）
# --max-requests-jitter 50  # 防止所有 worker 同时重启
# --preload             # 预加载应用（节省内存，fork-safe 时使用）
```

### 5.2 数据库查询优化

```python
# ❌ N+1 查询问题
for user in User.objects.all():
    print(user.profile.bio)  # 每次循环查一次 DB

# ✅ select_related（JOIN）/ prefetch_related（子查询）
users = User.objects.select_related('profile').all()

# ❌ 查询全部字段
User.objects.all()

# ✅ 只查需要的字段
User.objects.values('id', 'name')
User.objects.only('id', 'name')

# ✅ 使用连接池
# pip install sqlalchemy
from sqlalchemy import create_engine
engine = create_engine(
    'postgresql://user:pass@host/db',
    pool_size=20,
    max_overflow=10,
    pool_recycle=3600,
)
```

### 5.3 缓存策略

```python
# functools.lru_cache（函数级缓存）
from functools import lru_cache

@lru_cache(maxsize=1024)
def expensive_compute(n):
    return sum(i**2 for i in range(n))

# Redis 缓存（分布式）
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)

def get_user(user_id):
    cache_key = f"user:{user_id}"
    cached = r.get(cache_key)
    if cached:
        return json.loads(cached)
    user = db.query_user(user_id)
    r.setex(cache_key, 300, json.dumps(user))  # 缓存5分钟
    return user
```

---

## 6. 性能诊断快速参考

### 6.1 诊断决策树

```text
性能问题
├── CPU 高
│   ├── py-spy top → 定位热点函数
│   ├── 热点在纯 Python 循环 → 向量化/Numba/Cython → 见 2.2, 4.x
│   ├── 热点在 GC → 减少对象创建 → 见 2.5
│   └── 多核利用不足 → multiprocessing → 见 3.3
├── 内存高
│   ├── tracemalloc → 定位分配热点
│   ├── memory_profiler → 逐行内存分析
│   ├── 大列表/字典 → 生成器/迭代器 → 见 2.5
│   └── 类实例过多 → __slots__ / namedtuple → 见 2.5
├── I/O 慢
│   ├── 网络 I/O → asyncio + aiohttp → 见 3.2
│   ├── 文件 I/O → 缓冲/批量写入 → 见 2.4
│   └── 数据库 → 连接池 + 查询优化 → 见 5.2
└── Web 响应慢
    ├── cProfile → 定位慢接口
    ├── N+1 查询 → select_related → 见 5.2
    ├── 缺少缓存 → Redis/lru_cache → 见 5.3
    └── worker 不足 → 调整 gunicorn workers → 见 5.1
```

### 6.2 关键指标告警阈值

| 指标 | 正常 | 警告 | 严重 |
|------|------|------|------|
| 单请求响应时间 | < 200ms | > 500ms | > 2s |
| Python 进程 RSS | 基线±20% | 基线×2 | 持续增长 |
| GC 频率（gc.get_stats()） | 基线 | 基线×3 | 基线×10 |
| 线程数 | < 100 | > 500 | > 1000 |
| 文件描述符 | < 1000 | > 5000 | 接近 ulimit |
| gunicorn worker 重启 | 偶尔 | 频繁 | 持续 |

---

## 7. 生产环境最佳实践

### 7.1 启动优化

```bash
# 使用 -O 跳过 assert 和 __debug__
python -O myapp.py

# 预编译 .pyc 文件
python -m compileall /path/to/project

# 延迟导入（减少启动时间）
def heavy_function():
    import pandas as pd  # 仅在需要时导入
    # ...
```

### 7.2 内存泄漏检测

```python
# objgraph（对象引用图）
import objgraph

# 查看增长最快的对象类型
objgraph.show_growth(limit=10)

# 查看特定对象的引用链
objgraph.show_backrefs(
    objgraph.by_type('MyClass')[:3],
    filename='refs.png'
)
```

### 7.3 性能优化检查清单

- [ ] 使用了合适的数据结构（set/dict 查找 vs list）
- [ ] 热路径避免了不必要的对象创建
- [ ] 大数据集使用生成器而非列表
- [ ] 正则表达式已预编译
- [ ] 数值计算使用了 NumPy 向量化
- [ ] I/O 密集型任务使用了 asyncio 或线程池
- [ ] CPU 密集型任务使用了多进程
- [ ] Web 应用配置了合适的 worker 数量
- [ ] 数据库查询避免了 N+1 问题
- [ ] 热点数据使用了缓存（lru_cache/Redis）
- [ ] 生产环境启用了 py-spy 或 pprof endpoint
- [ ] gunicorn 配置了 --max-requests 防内存泄漏
- [ ] 类使用了 __slots__（大量实例场景）


path: references/rust_performance.md
content: # Rust 性能分析与优化指南

> Rust 凭借零成本抽象、无 GC 的所有权系统和编译期优化，天然具备高性能基因。本文档覆盖 Rust 性能分析工具链、编译优化、内存布局优化、并发模式及生产环境最佳实践。

---


## 目录

- [1. 性能分析工具链](#1-性能分析工具链)
- [2. 编译优化](#2-编译优化)
- [3. 常见性能瓶颈与优化](#3-常见性能瓶颈与优化)
- [4. 性能诊断快速参考](#4-性能诊断快速参考)
- [5. 生产环境最佳实践](#5-生产环境最佳实践)
## 1. 性能分析工具链

### 1.1 perf + 火焰图（Linux 首选）

```bash
# 编译时保留符号信息
# Cargo.toml
[profile.release]
debug = true          # 保留调试符号（不影响优化等级）
strip = false

# perf 采样
perf record -g --call-graph dwarf -p <PID> -- sleep 30

# 生成火焰图
perf script | inferno-flamegraph > flamegraph.svg
# 或使用 FlameGraph 工具
perf script | stackcollapse-perf.pl | flamegraph.pl > flamegraph.svg

# perf stat（硬件计数器）
perf stat -e cycles,instructions,cache-misses,branch-misses -p <PID> -- sleep 10
```

### 1.2 cargo-flamegraph（一键火焰图）

```bash
# 安装
cargo install flamegraph

# 直接生成火焰图
cargo flamegraph --bin myapp
cargo flamegraph --bench mybench

# 带参数运行
cargo flamegraph -- --arg1 value1
```

### 1.3 criterion（基准测试框架）

```toml
# Cargo.toml
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]
name = "my_benchmark"
harness = false
```

```rust
// benches/my_benchmark.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn bench_my_function(c: &mut Criterion) {
    c.bench_function("my_func", |b| {
        b.iter(|| {
            my_function(black_box(1000))
        })
    });
}

// 对比两种实现
fn bench_comparison(c: &mut Criterion) {
    let mut group = c.benchmark_group("comparison");
    group.bench_function("impl_a", |b| b.iter(|| impl_a(black_box(1000))));
    group.bench_function("impl_b", |b| b.iter(|| impl_b(black_box(1000))));
    group.finish();
}

criterion_group!(benches, bench_my_function, bench_comparison);
criterion_main!(benches);
```

```bash
# 运行基准测试（自动统计对比）
cargo bench

# 生成 HTML 报告
# 输出在 target/criterion/report/index.html
```

### 1.4 DHAT / Valgrind（堆分析）

```bash
# DHAT（堆分配分析，Rust 内置支持）
# 需要 nightly
cargo +nightly run --features dhat-heap

# 或使用 Valgrind
valgrind --tool=massif ./target/release/myapp
ms_print massif.out.<PID>

# Valgrind cachegrind（缓存分析）
valgrind --tool=cachegrind ./target/release/myapp
cg_annotate cachegrind.out.<PID>
```

**dhat-rs 集成：**
```toml
# Cargo.toml
[dependencies]
dhat = { version = "0.3", optional = true }

[features]
dhat-heap = ["dhat"]
```

```rust
#[cfg(feature = "dhat-heap")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;

fn main() {
    #[cfg(feature = "dhat-heap")]
    let _profiler = dhat::Profiler::new_heap();

    // ... 业务代码 ...
    // 退出时自动生成 dhat-heap.json，用 DHAT viewer 打开
}
```

### 1.5 tracing + tokio-console（异步运行时分析）

```toml
# Cargo.toml
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"
console-subscriber = "0.4"   # tokio-console 支持
```

```rust
// 启用 tokio-console
fn main() {
    console_subscriber::init();  // 替代 tracing_subscriber::init()
    // ... tokio 运行时代码
}
```

```bash
# 安装并运行 tokio-console
cargo install tokio-console
tokio-console
# 实时查看：task 数量、poll 耗时、waker 统计、资源争用
```

### 1.6 cargo-asm / cargo-show-asm（汇编分析）

```bash
# 查看函数生成的汇编
cargo install cargo-show-asm
cargo asm my_crate::my_function

# 查看 LLVM IR
cargo asm --llvm my_crate::my_function

# Compiler Explorer 在线版
# https://godbolt.org — 选择 Rust 编译器
```

---

## 2. 编译优化

### 2.1 Release Profile 配置

```toml
# Cargo.toml

[profile.release]
opt-level = 3          # 最高优化等级（默认3）
lto = "fat"            # 全量 LTO（最慢编译，最优性能）
codegen-units = 1      # 单 codegen unit（更好的优化机会）
panic = "abort"        # 不生成 unwind 表（减小二进制，略快）
strip = true           # 去除符号（减小二进制）
# ⚠️ target-cpu 不是 Cargo profile 有效字段，需通过 RUSTFLAGS 或 .cargo/config.toml 设置：
#   RUSTFLAGS="-C target-cpu=native" cargo build --release
#   或在 .cargo/config.toml 中：
#   [build]
#   rustflags = ["-C", "target-cpu=native"]

# 折中方案（编译速度 vs 运行性能）
[profile.release-fast]
inherits = "release"
lto = "thin"           # Thin LTO（比 fat 快，性能接近）
codegen-units = 4      # 折中

# 性能测试 profile
[profile.bench]
debug = true           # 保留符号便于 profiling
```

### 2.2 编译器标志

```bash
# 指定目标 CPU（利用 AVX2/AVX-512 等）
RUSTFLAGS="-C target-cpu=native" cargo build --release

# 启用特定 CPU 特性
RUSTFLAGS="-C target-feature=+avx2,+fma" cargo build --release

# PGO（Profile-Guided Optimization）
# 第一步：生成插桩二进制
RUSTFLAGS="-Cprofile-generate=/tmp/pgo-data" cargo build --release
# 第二步：运行典型工作负载
./target/release/myapp  # 执行代表性操作
# 第三步：合并 profile 数据
llvm-profdata merge -o /tmp/pgo-data/merged.profdata /tmp/pgo-data
# 第四步：使用 profile 数据重新编译
RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" cargo build --release

# BOLT（二进制优化，Facebook 开源）
# 对热路径进行二进制级重排，可额外提升 5-15%
```

### 2.3 编译时间优化（开发体验）

```toml
# .cargo/config.toml

# 使用 mold 链接器（Linux，比 ld 快 5-10x）
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

# 开发模式优化
[profile.dev]
opt-level = 1          # 开发时也做基本优化（调试更接近生产行为）

[profile.dev.package."*"]
opt-level = 2          # 依赖库用更高优化等级
```

---

## 3. 常见性能瓶颈与优化

### 3.1 内存分配优化

```rust
// ❌ 频繁小分配
fn bad() -> Vec<String> {
    let mut result = Vec::new();
    for i in 0..10000 {
        result.push(format!("item_{}", i));  // 多次扩容
    }
    result
}

// ✅ 预分配容量
fn good() -> Vec<String> {
    let mut result = Vec::with_capacity(10000);
    for i in 0..10000 {
        result.push(format!("item_{}", i));
    }
    result
}

// ✅ 使用 SmallVec（栈上小数组，避免堆分配）
use smallvec::SmallVec;
let mut v: SmallVec<[u32; 8]> = SmallVec::new();  // ≤8 个元素在栈上

// ✅ 使用 bumpalo（Arena 分配器，批量释放）
use bumpalo::Bump;
let bump = Bump::new();
let s = bump.alloc_str("hello");
let v = bump.alloc_slice_copy(&[1, 2, 3]);
// bump drop 时一次性释放所有内存

// ✅ 字符串优化
// 避免不必要的 String 分配，优先使用 &str
fn process(input: &str) -> &str { /* ... */ }  // 零拷贝

// 小字符串优化
use compact_str::CompactString;  // ≤24 字节不堆分配
```

### 3.2 数据布局优化（缓存友好）

```rust
// ❌ AoS（Array of Structs）— 缓存不友好
struct Particle {
    x: f64, y: f64, z: f64,
    vx: f64, vy: f64, vz: f64,
    mass: f64,
    name: String,  // 只有位置计算时 name 浪费缓存行
}
let particles: Vec<Particle> = vec![...];

// ✅ SoA（Struct of Arrays）— 缓存友好
struct Particles {
    x: Vec<f64>, y: Vec<f64>, z: Vec<f64>,
    vx: Vec<f64>, vy: Vec<f64>, vz: Vec<f64>,
    mass: Vec<f64>,
    name: Vec<String>,
}

// ✅ 减小结构体大小（注意字段排列顺序）
// Rust 默认会重排字段以最小化 padding
// 但 #[repr(C)] 会保持声明顺序
struct Compact {
    a: u64,   // 8 bytes
    b: u32,   // 4 bytes
    c: u16,   // 2 bytes
    d: u8,    // 1 byte  → 总共 15 bytes + 1 padding = 16 bytes
}

// ✅ 使用 Box<[T]> 替代 Vec<T>（不需要动态增长时，少 8 字节）
let data: Box<[u32]> = vec![0u32; 1000].into_boxed_slice();
```

### 3.3 迭代器与零成本抽象

```rust
// ❌ 手动循环 + 索引（可能有边界检查开销）
let mut sum = 0;
for i in 0..data.len() {
    sum += data[i];  // 每次访问都有边界检查
}

// ✅ 迭代器（编译器消除边界检查 + 自动向量化）
let sum: i64 = data.iter().sum();

// ✅ 链式迭代器（零分配）
let result: Vec<_> = data.iter()
    .filter(|&&x| x > 0)
    .map(|&x| x * 2)
    .collect();

// ✅ 手动消除边界检查（性能关键路径）
let slice = &data[..known_len];  // 一次边界检查
for &item in slice {
    // 无边界检查
}

// 或使用 unsafe（确保安全时）
unsafe { *data.get_unchecked(i) }
```

### 3.4 并发与异步优化

```rust
// ✅ Rayon 数据并行（CPU 密集型）
use rayon::prelude::*;
let sum: i64 = data.par_iter().sum();
let results: Vec<_> = data.par_iter()
    .filter(|&&x| x > 0)
    .map(|&x| expensive_compute(x))
    .collect();

// ✅ 无锁并发数据结构
use crossbeam::queue::ArrayQueue;
use dashmap::DashMap;

let map: DashMap<String, i64> = DashMap::new();
// 自动分片，读写并发安全

// ✅ 原子操作（简单计数器）
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
COUNTER.fetch_add(1, Ordering::Relaxed);

// ✅ tokio 异步运行时调优
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
    // I/O 密集型任务
}

// ✅ 避免在 async 中阻塞
// 使用 spawn_blocking 包装阻塞操作
let result = tokio::task::spawn_blocking(|| {
    heavy_cpu_work()
}).await?;
```

### 3.5 SIMD 优化

```rust
// 自动向量化（编译器自动应用）
// 确保：循环简单、无分支、数据对齐、使用迭代器
fn dot_product(a: &[f64], b: &[f64]) -> f64 {
    a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}

// 手动 SIMD（std::simd，nightly）
#![feature(portable_simd)]
use std::simd::f64x4;

fn dot_product_simd(a: &[f64], b: &[f64]) -> f64 {
    let mut sum = f64x4::splat(0.0);
    for (chunk_a, chunk_b) in a.chunks_exact(4).zip(b.chunks_exact(4)) {
        let va = f64x4::from_slice(chunk_a);
        let vb = f64x4::from_slice(chunk_b);
        sum += va * vb;
    }
    sum.reduce_sum()
}

// 稳定版 SIMD（使用 packed_simd2 或 wide crate）
```

### 3.6 减小二进制体积

```toml
# Cargo.toml
[profile.release]
opt-level = "z"        # 优化体积（而非速度）
lto = true
codegen-units = 1
panic = "abort"
strip = true

[profile.release.build-override]
opt-level = "z"
```

```bash
# 使用 UPX 进一步压缩
upx --best target/release/myapp

# 分析二进制体积组成
cargo install cargo-bloat
cargo bloat --release -n 20  # 最大的20个函数
cargo bloat --release --crates  # 按 crate 统计
```

---

## 4. 性能诊断快速参考

### 4.1 诊断决策树

```text
性能问题
├── CPU 高
│   ├── perf + 火焰图 → 定位热点函数
│   ├── 热点在 alloc/dealloc → 内存分配过多 → 见 3.1
│   ├── 热点在 memcpy/memmove → 数据拷贝过多 → 减少 clone()
│   ├── 热点在 hash/compare → HashMap 热点 → 换 FxHashMap/ahash
│   └── 热点在业务逻辑 → 算法优化 / SIMD → 见 3.3, 3.5
├── 内存高
│   ├── DHAT → 分配热点分析
│   ├── Valgrind massif → 堆使用时间线
│   ├── 大量小分配 → Arena/SmallVec → 见 3.1
│   └── 内存碎片 → jemalloc/mimalloc → 见 5.1
├── 延迟高
│   ├── tokio-console → 异步任务分析
│   ├── async 任务中有阻塞调用 → spawn_blocking → 见 3.4
│   ├── 锁竞争 → DashMap/无锁结构 → 见 3.4
│   └── 系统调用过多 → io_uring/批量操作
└── 编译慢
    ├── cargo-timings → 编译时间分析
    ├── 链接慢 → mold 链接器 → 见 2.3
    └── 依赖过多 → cargo-udeps 清理无用依赖
```

### 4.2 关键指标

| 指标 | 参考值 | 说明 |
|------|--------|------|
| 缓存未命中率 | < 5% | perf stat cache-misses |
| 分支预测失败率 | < 2% | perf stat branch-misses |
| IPC（指令/周期） | > 1.0 | < 0.5 说明内存/I/O 瓶颈 |
| 堆分配频率 | 越低越好 | DHAT 分析 |
| async task poll 时间 | < 10μs | tokio-console 监控 |

---

## 5. 生产环境最佳实践

### 5.1 全局分配器选择

```toml
# Cargo.toml
[dependencies]
tikv-jemallocator = "0.6"  # jemalloc（多线程友好，减少碎片）
# 或
mimalloc = { version = "0.1", default-features = false }
```

```rust
// 使用 jemalloc
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

// 或 mimalloc
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
```

**分配器选择：**
| 分配器 | 适用场景 | 特点 |
|--------|---------|------|
| 系统默认（glibc） | 通用 | 无需额外依赖 |
| jemalloc | 多线程服务 | 减少碎片，线程缓存 |
| mimalloc | 高性能计算 | 极低延迟，小内存开销 |

### 5.2 性能优化检查清单

- [ ] 使用 `--release` 编译（切勿用 debug 模式上线）
- [ ] 开启了 LTO（至少 thin LTO）
- [ ] codegen-units 设为 1（最优性能）或合理值
- [ ] 设置了 target-cpu=native（或目标平台 CPU）
- [ ] Vec/HashMap 预分配了合理容量
- [ ] 避免了不必要的 `.clone()` 和 `.to_string()`
- [ ] 热路径使用迭代器而非索引访问
- [ ] CPU 密集型并行使用 Rayon
- [ ] I/O 密集型使用 tokio 异步
- [ ] 异步代码中无阻塞调用（或用 spawn_blocking 包装）
- [ ] 考虑了 jemalloc/mimalloc 替代系统分配器
- [ ] 基准测试覆盖了核心路径（criterion）
- [ ] 使用了火焰图确认优化效果


path: evals/advanced-scenarios.yaml
content: # Evaluation: 高级场景 — eBPF / 工具输出解读 / 基准测试 / 编译优化 / Service Mesh
# 验证 AI 是否能正确应用高级性能分析知识

tests:
# --- eBPF ---
- name: "ebpf-syscall-trace"
  input: "怎么用 bpftrace 追踪某个进程的系统调用延迟分布？"
  expected_keywords:
    - "bpftrace"
    - "tracepoint"
    - "syscalls"
    - "hist"
    - "nsecs"
  expected_not:
    - "strace"

- name: "ebpf-tcp-retransmit"
  input: "线上 TCP 重传率偏高，怎么用 BCC 工具定位是哪些连接在重传？"
  expected_keywords:
    - "tcpretrans"
    - "BCC"
    - "bpfcc"
    - "源IP"
    - "目的IP"
  expected_not:
    - "tcpdump"

- name: "ebpf-io-latency"
  input: "怎么用 eBPF 工具分析磁盘 I/O 延迟的分布情况？"
  expected_keywords:
    - "biolatency"
    - "直方图"
    - "BCC"
    - "延迟"
  expected_not:
    - "dd"

# --- 工具输出解读 ---
- name: "interpret-vmstat"
  input: "vmstat 1 输出中 si/so 列持续有值，wa 列也很高，这说明什么问题？"
  expected_keywords:
    - "swap"
    - "内存不足"
    - "I/O 等待"
    - "swappiness"
    - "free -h"
  expected_not:
    - "CPU 密集"

- name: "interpret-iostat"
  input: "iostat -x 输出中某块磁盘 await 200ms、%util 98%，但 r/s 和 w/s 不高，是什么情况？"
  expected_keywords:
    - "磁盘饱和"
    - "队列"
    - "调度器"
    - "await"
    - "I/O"
  expected_not:
    - "网络"

- name: "interpret-ss"
  input: "ss -s 显示大量 TIME-WAIT 连接（超过 5 万），这正常吗？怎么处理？"
  expected_keywords:
    - "tcp_tw_reuse"
    - "短连接"
    - "连接池"
    - "TIME_WAIT"
    - "keepalive"
  expected_not:
    - "重启服务器"

# --- 基准测试 ---
- name: "benchmark-disk-iops"
  input: "怎么用 fio 测试 NVMe SSD 的随机读 IOPS？"
  expected_keywords:
    - "fio"
    - "randread"
    - "libaio"
    - "direct=1"
    - "iodepth"
  expected_not:
    - "dd"

- name: "benchmark-http"
  input: "怎么对 HTTP API 做压力测试？需要测量延迟分布和吞吐量。"
  expected_keywords:
    - "wrk"
    - "p99"
    - "QPS"
    - "并发"
  expected_not:
    - "curl"

# --- 编译优化 ---
- name: "compile-optimization-lto"
  input: "C++ 项目编译出来的二进制性能不理想，听说 LTO 和 PGO 能提升性能，具体怎么用？"
  expected_keywords:
    - "LTO"
    - "PGO"
    - "-flto"
    - "fprofile"
    - "链接时优化"
  expected_not:
    - "strip"

# --- Service Mesh ---
- name: "service-mesh-latency"
  input: "接入 Istio 后服务延迟增加了 5-10ms，有什么优化方案？"
  expected_keywords:
    - "sidecar"
    - "Envoy"
    - "mTLS"
    - "资源"
  expected_not:
    - "重启"


path: evals/container-k8s.yaml
content: # Evaluation: 容器与 K8s 性能场景
# 验证 AI 是否能正确应用容器/K8s 性能调优知识

tests:
- name: "k8s-cpu-throttling"
  input: "我的 K8s Pod 延迟很不稳定，kubectl top 显示 CPU 使用率不高，但业务反馈很慢，可能是什么原因？"
  expected_keywords:
    - "throttling"
    - "cpu.stat"
    - "nr_throttled"
    - "cfs_quota"
    - "limit"
  expected_not:
    - "扩容节点"

- name: "container-oom-kill"
  input: "Pod 频繁被 OOM Kill 重启，但应用日志没有报错，怎么排查？"
  expected_keywords:
    - "memory.events"
    - "memory.max"
    - "dmesg"
    - "oom"
    - "cgroup"
  expected_not:
    - "重启服务器"

- name: "k8s-resource-config"
  input: "K8s 中 requests 和 limits 应该怎么设置？有什么最佳实践？"
  expected_keywords:
    - "requests"
    - "limits"
    - "QoS"
    - "Guaranteed"
    - "Burstable"

- name: "go-container-oom"
  input: "Go 服务跑在容器里，GOMAXPROCS 默认值不对导致性能差，怎么解决？"
  expected_keywords:
    - "GOMAXPROCS"
    - "automaxprocs"
    - "cgroup"
    - "CPU 配额"

- name: "java-container-memory"
  input: "Java 应用在容器中经常 OOM，但 -Xmx 设的比 memory limit 小很多，为什么？"
  expected_keywords:
    - "堆外内存"
    - "Metaspace"
    - "DirectByteBuffer"
    - "MaxRAMPercentage"
    - "UseContainerSupport"

- name: "cgroup-v1-v2"
  input: "怎么判断容器用的是 cgroup v1 还是 v2？两者有什么区别？"
  expected_keywords:
    - "stat -fc"
    - "cgroup2fs"
    - "tmpfs"
    - "cpu.max"
    - "cpu.cfs_quota_us"


path: evals/language-optimization.yaml
content: # Evaluation: 编程语言性能优化
# 验证 AI 是否能正确应用各语言的性能优化知识

tests:
# --- Python ---
  - name: "python-slow-lookup"
    input: "我的 Python 程序有一个循环检查元素是否在一个大列表中，很慢，怎么优化？"
    expected_keywords:
      - "set"
      - "O(1)"
      - "dict"
    expected_not:
      - "多线程"

  - name: "python-string-concat"
    input: "Python 中大量字符串拼接很慢，怎么办？"
    expected_keywords:
      - "join"
      - "StringIO"
      - "列表"
      - "f-string"
    expected_not:
      - "+="

  - name: "python-profiling"
    input: "怎么找到 Python 程序的性能瓶颈？"
    expected_keywords:
      - "cProfile"
      - "py-spy"
      - "line_profiler"

# --- Go ---
  - name: "go-slice-allocation"
    input: "我的 Go 程序 pprof 显示大量 alloc_objects，该怎么优化？"
    expected_keywords:
      - "make"
      - "预分配"
      - "sync.Pool"
      - "capacity"

  - name: "go-gc-container"
    input: "Go 服务跑在 Kubernetes 容器里经常 OOM kill，怎么调 GC？"
    expected_keywords:
      - "GOMEMLIMIT"
      - "80%"
      - "90%"

# --- Java ---
  - name: "java-gc-latency"
    input: "Java 服务延迟抖动严重，怀疑是 GC 暂停导致的，该用什么 GC？"
    expected_keywords:
      - "ZGC"
      - "Shenandoah"
      - "低延迟"

  - name: "java-profiling"
    input: "生产环境的 Java 服务怎么做 CPU 性能分析？"
    expected_keywords:
      - "async-profiler"
      - "JFR"
      - "火焰图"

# --- Rust ---
  - name: "rust-unnecessary-clone"
    input: "Rust 代码中有大量 .clone() 调用导致性能差，有什么替代方案？"
    expected_keywords:
      - "借用"
      - "&str"
      - "Cow"
      - "Arc"
      - "引用"

# --- C++ ---
  - name: "cpp-cache-friendly"
    input: "C++ 程序处理大量 Point 对象，性能不好，可能是什么原因？"
    expected_keywords:
      - "缓存"
      - "vector"
      - "连续内存"
      - "指针追逐"
      - "数据布局"

# --- Node.js ---
  - name: "nodejs-event-loop-block"
    input: "Node.js 服务在高并发时响应变慢，怀疑事件循环被阻塞了，怎么排查和优化？"
    expected_keywords:
      - "clinic"
      - "event loop"
      - "Worker"
      - "异步"
      - "CPU 密集"
    expected_not:
      - "多线程锁"

  - name: "nodejs-memory-leak"
    input: "Node.js 应用运行一段时间后内存持续增长不释放，怎么定位内存泄漏？"
    expected_keywords:
      - "heapdump"
      - "Chrome DevTools"
      - "--inspect"
      - "内存快照"


path: evals/linux-system.yaml
content: # Evaluation: Linux 系统性能分析
# 验证 AI 是否能正确应用 linux-perf 和 sysctl-tuning 的知识

tests:
  - name: "diagnose-high-cpu"
    input: "服务器 CPU 使用率持续 95%+ 但 top 看不到明显的用户进程，该怎么排查？"
    expected_keywords:
      - "perf top"
      - "softirq"
      - "ksoftirqd"
      - "mpstat"
      - "中断"
    expected_not:
      - "重启"

  - name: "diagnose-high-load-low-cpu"
    input: "服务器 load average 很高但 CPU 利用率很低，可能是什么原因？"
    expected_keywords:
      - "I/O"
      - "vmstat"
      - "iostat"
      - "await"
      - "磁盘"
    expected_not:
      - "CPU 优化"

  - name: "sysctl-web-server"
    input: "我有一个 Nginx Web 服务器，连接数经常打满，有什么内核参数可以调优？"
    expected_keywords:
      - "somaxconn"
      - "tcp_max_syn_backlog"
      - "tcp_tw_reuse"
      - "bbr"
      - "file-max"

  - name: "io-scheduler-selection"
    input: "数据库服务器用的 NVMe SSD，I/O 调度器应该选什么？"
    expected_keywords:
      - "none"
      - "noop"
      - "NVMe"
      - "硬件自调度"

  - name: "perf-flamegraph"
    input: "怎么用 perf 生成火焰图找到 CPU 热点？"
    expected_keywords:
      - "perf record"
      - "perf script"
      - "stackcollapse"
      - "flamegraph.pl"
      - "svg"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)