四、压测环境搭建:Linux服务器参数调优、ulimit设置、网络参数优化
说实话,很多做压测的朋友,脚本写得贼溜,工具用得飞起,结果一上生产环境,压到一半连接断了、文件打不开了、网络卡死了。嗯,我当年也踩过这个坑。后来才明白——压测不只是测应用,更是测操作系统。服务器没调好,压测结果就是废纸。
这一章,我就带你过一遍Linux服务器上必须做的几项调优。说白了,就是给系统松松筋骨,让它能扛住高并发。
4.1 文件描述符限制:ulimit 设置
先问个问题:你知道一台Linux服务器默认能打开多少个文件吗?
答案是——1024。对,你没看错,就1024个。
你想想看,一个压测客户端可能就要开几百个连接,再加上日志文件、socket、管道……1024根本不够用。我在项目中遇到过,压测跑到一半,突然报错:Too many open files。查了半天,就是ulimit没改。
4.1.1 临时修改(当前会话有效)
ulimit -n 65535
这条命令只对当前shell窗口有效。你关掉终端再开,又变回1024。所以这只是临时救急用的。
4.1.2 永久修改(推荐)
修改 /etc/security/limits.conf 文件,在末尾加上:
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
这里 * 表示对所有用户生效,root 单独指定是因为root用户不受 * 限制。我曾经忘了加root那两行,结果用root跑压测时照样报错,折腾了半小时才反应过来。
ulimit -n 检查一下是否生效。如果没变,试试重新登录或者重启sshd服务。
4.1.3 系统级限制
除了用户级限制,还有个系统级限制在 /proc/sys/fs/file-max 里。这个值一般很大,但最好也确认一下:
cat /proc/sys/fs/file-max
# 如果太小,临时改:
echo 1000000 > /proc/sys/fs/file-max
# 永久改:编辑 /etc/sysctl.conf,添加:
fs.file-max = 1000000
4.2 网络参数优化
网络参数这块,我习惯把它分成三块:TCP连接层面、端口资源层面、内核参数层面。咱们一个一个说。
4.2.1 TCP TIME_WAIT 优化
压测时你会发现,大量连接处于 TIME_WAIT 状态。这是TCP主动关闭连接后的等待状态,默认60秒。如果并发高,端口很快就被占满了。
我建议做两件事:
- 开启TIME_WAIT复用:允许将TIME_WAIT状态的socket用于新连接
- 快速回收:缩短TIME_WAIT的等待时间
# 编辑 /etc/sysctl.conf,添加:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1 # 注意:NAT环境下慎用!
net.ipv4.tcp_fin_timeout = 30
tcp_tw_recycle 在NAT环境下会导致连接异常。如果你压测的服务器在云上或者有负载均衡,建议只开 tcp_tw_reuse。我吃过这个亏,压测时客户端连不上,查了半天是NAT惹的祸。
4.2.2 端口范围扩大
默认情况下,Linux本地端口范围是32768到60999。对于高并发压测,这个范围太小了。我一般会扩大到1024到65535:
# 编辑 /etc/sysctl.conf,添加:
net.ipv4.ip_local_port_range = 1024 65535
改完之后,可用端口从2.8万个变成了6.4万个,翻了一倍多。
4.2.3 TCP缓冲区调大
压测时如果网络延迟高,缓冲区太小会导致吞吐量上不去。我习惯把读写缓冲区都调大:
# 编辑 /etc/sysctl.conf,添加:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
这里的最小值、默认值、最大值分别对应三个数字。最大值设到16MB,基本够用了。
4.2.4 其他常用参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
| net.core.somaxconn | 65535 | 监听队列长度,高并发时调大 |
| net.ipv4.tcp_max_syn_backlog | 65535 | 半连接队列长度,防SYN洪水 |
| net.ipv4.tcp_syncookies | 1 | 开启SYN Cookie,防攻击 |
| net.ipv4.tcp_keepalive_time | 120 | TCP保活探测间隔(秒) |
4.3 内核参数生效与验证
改完 /etc/sysctl.conf 后,记得执行:
sysctl -p
这条命令会重新加载所有参数。我习惯再跑一遍 sysctl -a | grep 参数名 确认一下。
4.4 本章知识体系
下面这张图,是我自己画的一个压测环境调优的框架图。你可以把它当成一个检查清单:
4.5 避坑指南
- 改完参数不重启:大部分参数用
sysctl -p就能生效,但有些需要重启服务或系统。我建议改完后观察一段时间,别急着上生产。 - 一次性改太多:我曾经一次改了十几个参数,结果压测出问题,根本不知道是哪个参数导致的。现在我的习惯是——改一个,测一个,确认一个。
- 忽略非root用户:很多参数对非root用户有限制。如果你用普通用户跑压测,记得检查
limits.conf里有没有包含那个用户。 - 云服务器特殊处理:云上的虚拟化环境,有些内核参数可能被宿主机限制。比如
tcp_tw_recycle在云上经常失效。遇到这种情况,别硬改,换个思路。
好了,这一章的内容就这些。Linux服务器调优看起来琐碎,但每一条参数背后都是血泪教训。你把这些配好了,压测工具才能发挥真正的实力。下一章咱们聊聊压测脚本怎么写才高效——嗯,到时候见。