在高并发场景下,Linux 服务器的默认配置往往无法满足业务需求。从 C10K 到 C100K 再到 C1M,每一次并发量的跃升都需要对系统进行精细调优。本文将从内核参数、网络栈、文件系统到应用层,提供一套完整的高并发优化方案。
一、内核参数基础调优
Linux 内核提供了大量可调参数,其中与高并发关系最密切的主要在 /proc/sys 目录下。首先来看最核心的几个参数配置:
# /etc/sysctl.conf 高并发核心配置
# 最大文件描述符数
fs.file-max = 1048576
# TCP 连接队列长度
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
# TCP 读写缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# TCP 内存分配限制(页为单位)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# SYN 队列长度
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT 优化
net.ipv4.tcp_max_tw_buckets = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 本地端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 允许 TIME_WAIT sockets 重新用于新的 TCP 连接
net.ipv4.tcp_timestamps = 1
# 生效配置
# sysctl -p
这些参数中,somaxconn 控制监听队列长度,直接影响三次握手完成但未被 accept 的连接数;tcp_max_syn_backlog 控制 SYN_RECV 状态的连接数;tcp_tw_reuse 允许复用 TIME_WAIT 状态的连接,在高并发短连接场景中至关重要。
二、文件描述符与连接数限制
Linux 中一切皆文件,每个 TCP 连接都占用一个文件描述符。默认的限制远远不够高并发使用,需要在多个层级进行调整:
# /etc/security/limits.conf
# 用户级文件描述符限制
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 1048576
* hard nproc 1048576
# 当前会话临时修改
ulimit -n 1048576
# 查看当前限制
ulimit -a
# Systemd 服务需要额外配置
# /etc/systemd/system/your-service.service
# [Service]
# LimitNOFILE=1048576
# LimitNPROC=1048576
注意:对于通过 Systemd 管理的服务,limits.conf 的配置可能不生效,需要在 service 文件中单独设置 LimitNOFILE。
三、TCP 协议栈深度优化
在高并发场景下,TCP 协议栈的行为对性能有深远影响。以下是几个关键的调优点:
# TCP KEEPALIVE 配置
# 减少僵尸连接占用的资源
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# TCP 拥塞控制算法
# BBR 适合高延迟高带宽网络
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 启用 TCP Fast Open
net.ipv4.tcp_fastopen = 3
# 禁用不必要的特性
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_slow_start_after_idle = 0
BBR 拥塞控制算法是 Google 提出的替代传统 CUBIC 的方案,在高延迟、有丢包的网络环境中表现优异。tcp_slow_start_after_idle 设为 0 可以避免空闲连接重新进入慢启动阶段,对于长连接服务特别有效。
四、Nginx 高并发配置
作为最常用的高并发 Web 服务器,Nginx 的配置直接影响系统的承载能力:
# /etc/nginx/nginx.conf
worker_processes auto;
worker_rlimit_nofile 1048576;
events {
# 使用 epoll 事件模型
use epoll;
# 每个 worker 的最大连接数
worker_connections 65535;
# 允许 worker 一次性接受所有新连接
multi_accept on;
# 非阻塞模式
accept_mutex off;
}
http {
# 长连接优化
keepalive_timeout 65;
keepalive_requests 100000;
# 上游连接池
upstream backend {
server 127.0.0.1:8080;
keepalive 128; # 保持到后端的长连接数
}
server {
listen 80 backlog=65535;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
}
accept_mutex 在高并发场景下建议关闭,否则 worker 进程间争抢锁会带来额外开销。keepalive_requests 设为较大值可以减少连接重建频率。
五、内存与 CPU 调度优化
除了网络参数,内存和 CPU 调度也直接影响高并发性能:
# 内存相关
# 减少交换分区使用
vm.swappiness = 1
# 脏页回写策略
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
# CPU 调度
# 关闭 NUMA 自动平衡(在 NUMA 架构上)
# echo 0 > /proc/sys/kernel/numa_balancing
# 中断亲和性绑定
# 将网卡中断绑定到特定 CPU 核心
# irqbalance 服务在极高并发下可能需要关闭
# systemctl stop irqbalance
# 查看网卡中断分布
# cat /proc/interrupts | grep eth
vm.swappiness 设为 1 而非 0,是因为完全禁用 swap 在内存紧张时可能导致 OOM Killer 直接杀进程。设为 1 表示仅在内存严重不足时才使用交换分区。
六、监控与验证
调优之后需要一套完整的监控体系来验证效果:
# 实时监控连接状态
ss -s
ss -tlnp
# 监控 TCP 各状态连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 监控系统级指标
sar -n DEV 1 # 网络流量
sar -u 1 # CPU 使用率
sar -r 1 # 内存使用
sar -W 1 # 交换分区
# 压测验证
# 使用 wrk 或 ab 进行压力测试
wrk -t12 -c10000 -d60s http://your-server/
ab -n 100000 -c 5000 http://your-server/
建议在调优前后分别进行压力测试,对比关键指标的变化。重点关注 QPS、延迟分布(P50/P95/P99)、错误率和系统资源利用率。调优是一个迭代过程,每次只调整一组参数,观察效果后再决定下一步。
总结
Linux 高并发调优是一个系统工程,涉及内核参数、网络栈、应用配置和硬件调度的多个层面。核心思路是:消除瓶颈、减少不必要的开销、让系统资源最大化利用。调优没有放之四海皆准的标准配置,需要根据具体业务特征和硬件环境进行针对性调整。