Linux 服务器性能优化基础实践
性能优化从来不是“一招鲜”,而是一套分层、优先级明确的系统性动作。 以下内容聚焦真正能带来 30%~300% 提升、性价比最高的基础实践,按照“投入产出比”从高到低排序,适合绝大多数中小型业务服务器(8–64 核,32–256GB 内存,NVMe SSD 或云盘)。
优化优先级排序原则(建议严格按此顺序执行)
- 解决最明显的资源瓶颈(iowait、swap、脏页、连接堆积)
- 调整最容易改、收益最大的系统参数
- 优化日志与写模式(往往能下降 50–90% 的 IO 压力)
- 数据库/缓存基础调优
- 应用层小幅调整(线程池、GC、连接池)
- 容器/虚拟化层隔离与限流
- 硬件/架构升级(最后考虑)
一、最高优先级:消除“假高负载”与最明显瓶颈(通常能提升 50–300%)
| 优化项 | 为什么有效(常见提升幅度) | 推荐操作(按重要性排序) | 预期效果(经验值) | 注意事项 / 风险点 |
|---|---|---|---|---|
| 日志级别从 debug → info/warn | 日志占 IO 50–90% 的极端案例极多 | 所有组件统一改成 info 或 warn(nginx、应用、java log4j2/logback、spring boot) | iowait 下降 30–80%,延迟降低 20–70% | 确认业务关键日志已输出到单独通道 |
| 异步日志 / 缓冲日志 | 同步写日志是最大元凶之一 | log4j2 AsyncAppender、logback AsyncAppender、nginx access_log buffer=64k flush=5s | 写 IO 下降 70–95% | 极端情况可能丢少量日志 |
| dirty page 回写策略优化 | 脏页堆积导致 kswapd / pdflush 阻塞 | vm.dirty_ratio=10–20 vm.dirty_background_ratio=5–10 vm.dirty_expire_centisecs=3000 | iowait 下降 20–60%,毛刺减少 | 过小会导致频繁小写,IO 更碎 |
| innodb_flush_log_at_trx_commit / sync_binlog | MySQL 最经典的 IO 杀手 | 业务可接受最终一致性 → 设为 2 / 0 或 1000 | TPS 提升 2–10 倍,延迟降低 50–90% | 极端宕机可能丢 1 秒数据 |
| Redis appendfsync | Redis AOF 同步写最常见瓶颈 | 改为 everysec(默认)或 no(看业务容忍度) | 写延迟从 ms 级 → μs 级 | no 模式宕机可能丢较多数据 |
二、系统参数调优(性价比极高,改完立即生效)
| 参数 | 默认值 | 推荐值(中小型服务器) | 适用场景 | 风险 / 副作用 |
|---|---|---|---|---|
| vm.swappiness | 60 | 1–10(有 swap 分区) 0–1(无 swap) | 几乎所有服务器 | 过低可能导致 OOM 更激进 |
| vm.dirty_ratio / dirty_background_ratio | 20 / 10 | 5–15 / 3–8 | 高写负载服务器 | 过小导致频繁小写 IO |
| net.core.somaxconn | 128–4096 | 4096–16384 | 高并发 HTTP/gRPC 服务 | 几乎无风险 |
| net.ipv4.tcp_max_syn_backlog | 1024–4096 | 8192–32768 | 高并发短连接场景 | 内存消耗略增 |
| net.ipv4.tcp_fin_timeout | 60 | 15–30 | 高并发短连接,TIME_WAIT 堆积严重 | 极端网络抖动可能导致连接异常关闭 |
| net.ipv4.tcp_tw_reuse | 0 | 1(配合 tcp_timestamps=1) | TIME_WAIT 占用端口过多 | 需配合 tcp_timestamps,否则可能连接错乱 |
| vm.vfs_cache_pressure | 100 | 50–200(小文件多调低) | 高并发小文件读写场景 | 过低会挤占应用内存 |
一键查看当前值与推荐对比:
Bash
sysctl -a | grep -E 'swappiness|dirty_|somaxconn|tcp_max_syn|tcp_fin_timeout|tcp_tw_reuse|vfs_cache'三、数据库 / 缓存基础优化(第二波收益最大)
| 组件 | 优化项 | 推荐值(中小型服务器) | 预期提升 | 注意事项 |
|---|---|---|---|---|
| MySQL | innodb_buffer_pool_size | 总内存 50–75% | 命中率提升,随机读 IO 下降 50–90% | 留足操作系统 page cache 空间 |
| MySQL | innodb_flush_log_at_trx_commit | 2(可接受 1 秒数据丢失) | TPS 提升 3–10 倍 | 金融/强一致性场景慎用 |
| MySQL | sync_binlog | 1000 或 0 | binlog 写 IO 下降 80–95% | 0 最激进,宕机丢 binlog |
| Redis | appendfsync | everysec | 写延迟从 ms → μs | always 模式慎用 |
| Redis | maxmemory + maxmemory-policy | 总内存 50–70%,volatile-lru/allkeys-lru | 防止 OOM,淘汰效率高 | 一定要设 maxmemory |
四、其他高性价比小调整(锦上添花)
- Nginx / 反向代理 access_log off 或 buffer=64k flush=5s proxy_buffering on + 适当增大 buffers
- Java 应用 -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=200(或 G1/ZGC/Shenandoah) -Xmx 设为总内存 50–60%
- 容器化场景 –memory=4g –memory-swap=4g(限制 swap) –cpuset-cpus=”0-7″(绑核减少上下文切换)
- 监控与告警先行 没有监控的优化是盲人摸象。至少要覆盖:
- load1 / load5 per core
- iowait > 20% 持续 3min
- MemAvailable < 15% 持续 5min
- D 状态进程数 > 5 持续 1min
- 单个盘 %util > 85% 持续 5min
一句话总结优化心法:
先把写日志和数据库同步写降下来(收益最大、改动最小)→ 再调脏页回写和 swappiness → 最后调网络 backlog 和应用层 GC/线程池。