很多朋友兴冲冲买了香港云服务器CN2 GIA线路,心想这钱花到位了,总该飞起来了吧?结果一用,发现晚高峰该卡还是卡,网页加载转圈圈,SSH偶尔还断流。跑去问客服,客服只会说“亲,我们的线路是没问题的哦”。
其实客服可能没骗你,问题真不一定出在线路上。CN2 GIA确实是目前大陆到香港能买到的最顶级的线路了,全程走59.43开头的CN2骨干网节点,不经过163公共网络那摊浑水。但这玩意儿只保你路是通畅的,至于你的车(服务器)能不能跑起来,那是另一码事。
所以,别一卡就骂服务商,先看看你的系统内核参数是不是还在用“出厂设置”跑高速。这篇文章就把一套TCP调优方案拿出来,照着做,不说完全解决,至少能让你感觉这钱花得值了点。
先别急着动手,看看是不是假GIA
动手之前有个坑必须得先填了。你得确认你买的真的是CN2 GIA,而不是CN2 GT,甚至只是普通BGP线路冒充的。
怎么验证? 在服务器上跑一下路由追踪:
traceroute 你本地的公网IP
或者用mtr看更直观。重点看路由节点里有没有大量的59.43.x.x。真正的CN2 GIA,从你服务器出去,一路上应该都是59.43开头的节点。
如果在路线上看到了202.97.x.x(那是163骨干网的标志),那说明你买的其实是CN2 GT,也就是“半程高速”。这玩意儿去程可能走的CN2,回程给你切回163了,这种“非对称路由”是导致卡顿的隐形杀手。如果是这种情况,你调内核参数效果有限,得先找服务商撕逼换线路。
确认线路没毛病,或者虽然有点瑕疵但暂时换不了,那咱就开始调内核吧。
核心参数调整:让系统为跨境链路“定制”策略
Linux内核的网络参数都在/proc/sys/net/下面,我们通过sysctl这个工具来调。注意,以下操作都需要root权限。
1. 搞定TIME_WAIT,别让它把你的端口堵死
这是高并发、短连接服务最常遇到的问题。每次TCP连接断开后,主动关闭的一方会进入TIME_WAIT状态,默认要等60秒(2个MSL)才能彻底释放资源。如果你的业务是API接口、爬虫、或者频繁建连的Web服务,ss -s一看,发现几万个TIME-WAIT挂在那,端口资源都快耗尽了,新连接自然就慢或者连不上。
我的建议是两步走:
启用端口复用:net.ipv4.tcp_tw_reuse = 1。这允许系统在安全的情况下,把处于TIME_WAIT状态的socket拿来给新连接用(注意:这个只对客户端发起的连接有效,也就是你的服务器作为client去请求别人时有用,对NAT环境下的被动连接影响不大)。
缩短FIN-WAIT-2的超时时间:net.ipv4.tcp_fin_timeout = 15。让系统别在FIN_WAIT_2状态上磨蹭太久。
2. 扩大TCP缓冲区:让数据“装得多、跑得快”
跨境链路的特点是高带宽延迟积(BDP)。简单说,就是路又宽(带宽大),距离又远(延迟高)。默认的TCP缓冲区大小是按内网或者低延迟环境设计的,数据还没装满呢,就发出去等ACK了,效率极低。
我们需要手动调大内核允许的缓冲区上限:
# 接收和发送缓冲区的最大值(单位:字节)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# TCP层面的接收/发送缓冲区(最小、默认、最大)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
把这些值调到16MB甚至更大(268435456是256MB),能让TCP窗口自动扩大到适应高延迟链路,显著提升大文件传输和下载速度。
3. 开启BBR拥塞控制算法(近几年的“神优化”)
如果你用的是Linux 4.9及以上内核(现在基本都满足),强烈建议把默认的cubic算法换成Google家的BBR。BBR专门对付高延迟、有丢包的网络环境,通过探测链路带宽和往返时间来动态调整发包速率,比传统的靠丢包来判断拥塞的算法要聪明得多。
开启就两行:
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
设完重启或者加载后,可以用sysctl net.ipv4.tcp_congestion_control确认一下,看到输出bbr就成功了。
4. 把监听队列加长,别让连接在门口等着
默认的监听队列(net.core.somaxconn)通常是128。这在稍微有点流量的场景下就是个笑话。高并发下,新连接请求来得太快,队列一满,系统就直接把多余的连接请求给丢了,表现在你这就是Connection refused或者超时。
直接拉满:
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
但是注意! 光改内核没用,你的应用层(比如Nginx)在listen指令那里也得把backlog参数调成同样的大小,否则取两者最小值,白忙活。
完整配置脚本和操作流程
把上面这些参数汇总到一个配置文件里。别直接往/etc/sysctl.conf里乱加,容易搞乱。推荐在/etc/sysctl.d/目录下新建一个文件,比如99-tcp-optimize.conf,这样管理起来清晰,而且按字典序最后加载,不容易被覆盖。
# 使用vim或nano编辑这个文件
vim /etc/sysctl.d/99-tcp-optimize.conf
把下面这堆东西粘进去:
# 监听队列
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 10000
net.ipv4.tcp_max_syn_backlog = 65535
# TCP缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# TIME_WAIT优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 拥塞控制(BBR)
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 可选:开启TCP窗口缩放(默认基本都开了,这里显式确保)
net.ipv4.tcp_window_scaling = 1
# 安全:开启SYN Cookies(防SYN Flood攻击)
net.ipv4.tcp_syncookies = 1
保存退出后,执行下面命令让配置生效:
sysctl --system
这个命令会加载所有/etc/sysctl.d/*.conf和/etc/sysctl.conf里的配置,比-p更彻底。
验证调优效果:别凭感觉,看数据
改完参数,得确认它真的生效了,并且有效果。
1. 检查参数值:
# 抽查几个关键参数
sysctl net.ipv4.tcp_congestion_control
sysctl net.core.somaxconn
cat /proc/sys/net/ipv4/tcp_tw_reuse
输出和你设的一致,说明生效了。
2. 观察连接状态变化:
跑业务一阵子后,用这个命令看看TIME_WAIT的数量有没有降下来:
ss -tan state time-wait | wc -l
如果之前是几万,现在可能降到几千或者更少。
3. 实际速度测试:
在你本地电脑上,用支持多线程的下载工具(比如IDM)从服务器上下载一个大文件,或者用iperf3测一下带宽。如果之前跑不满,现在应该能感觉出明显提升。
最后再啰嗦一句,内核参数不是万能的。如果Nginx的worker_connections没调大,worker_processes没和CPU核数对应,或者PHP-FPM的进程数不够,那网络再好也是白搭。应用层的backlog参数一定得同步调整,这个坑很多人都踩过。另外,如果用了共享带宽,晚上邻居疯狂跑流量把你带宽抢光了,那调内核也救不了你,这是服务商超售的问题。
推荐文章