服务器上线跑了一阵,响应变慢、负载升高,很多时候不是硬件不行,是默认配置没改。下面几个方向是我实际调过的,效果比较明显。
内核网络参数
默认的 TCP 参数偏保守,高并发场景下很容易成为瓶颈。改 /etc/sysctl.conf:
# 增加 TCP 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
# 启用 TCP Fast Open
net.ipv4.tcp_fastopen = 3
# 拥塞控制换 BBR
net.ipv4.tcp_congestion_control = bbr
改完跑 sysctl -p 生效。BBR 对丢包率高的网络环境改善很明显,国内服务器基本都建议开。
用 systemd 限制资源
跑了好几个服务的机器,最怕一个进程把内存吃光、其他全挂。在 systemd 的 service 文件里加资源限制:
[Service]
MemoryLimit=2G
CPUQuota=50%
TasksMax=100
比手动写 cgroup 配置方便。出问题的时候 systemd 会自动杀掉超限的进程,不用你半夜爬起来处理。
透明大页(THP)
内存用量大的应用,比如跑数据库或 Java 服务,开 THP 能减少 TLB miss,内存访问快一些:
echo always > /sys/kernel/mm/transparent_hugepage/enabled
但 MongoDB 和 Redis 官方都建议关掉 THP,它们自己管内存分配,THP 反而会导致延迟抖动。所以看你跑的是什么。
磁盘 I/O 调度器
不同存储介质适合不同的调度策略:
- SSD / NVMe:用
none或mq-deadline,SSD 本身寻址快,复杂调度反而添乱 - 机械硬盘:用
bfq或deadline,需要调度器帮忙减少磁头移动
# 看当前调度器
cat /sys/block/sda/queue/scheduler
# 改调度器
echo mq-deadline > /sys/block/sda/queue/scheduler
cgroup 做资源隔离
跑容器的机器一般 Docker 会自动处理 cgroup,但如果是直接跑的进程,手动设一下也不麻烦:
# 创建 cgroup
cgcreate -g cpu,memory:/myapp
# 设置限制
cgset -r cpu.shares=512 myapp
cgset -r memory.limit_in_bytes=1G myapp
# 在 cgroup 中运行进程
cgexec -g cpu,memory:/myapp ./myapp
现在大多数场景用 systemd 的资源限制就够了,cgroup 手动操作更适合需要细粒度控制的情况。
监控工具
优化之前先得知道瓶颈在哪,几个常用的:
htop— 看进程和 CPU、内存iotop— 看哪个进程在疯狂读写磁盘nethogs— 按进程看网络流量perf— 深入分析性能热点,适合排查具体函数级别的问题
最后一点:别一上来就调参数,先用监控工具看看到底卡在哪里。CPU 满了去调磁盘调度器没用。先量再改。
评论
暂无评论