Linux TCP优化

优化方面

Listen状态下的半连接队列以及全连接队列
TCP挥手快速回收,心跳机制调优
异常状态下TCP处理逻辑,超时重传次数

阐述:
服务端收到客户端发起的SYN握手请求后,内核会把该连接存储到半连接队列,并响应客户端SYC+ACK(此时服务端状态SYN_RECV),接着客户端会返回ACK。
服务端收到ACK后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到全连接队列,等待进程调用accept函数时把连接取出来。

非Listen状态
Send-Q:全连接队列,send queue中bytes数值
Recv-Q:半连接队列,receive queue中bytes数值

Listen状态
Send-Q:全连接队列,min(backlog, somaxconn) somaxconn默认为128(笔者虚拟机),backlog由listen时传入
Recv-Q:半连接队列,完成连接的数量 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) tcp_max_syn_backlog默认128

  • 统计分析
统计半连接连接个数
netstat -natp|grep -i 'syn_recv' |wc -l

统计半连接队列已满造成的失败次数,这是累计值
netstat -s |grep -i 'syns to listen'

统计TCP socket连接因为全连接队列、半连接队列满了而被丢弃
netstat -s |grep -i 'listen'
      189000 times the listen queue of a socket overflowed  代表 189000 次全连接队列溢出
       30150000 SYNs to LISTEN sockets dropped 代表 30150000 次半连接队列溢出

如果这两个值一段时间内相关数值一直上升,则表明半连接队列、全连接队列有溢出情况


ss -lnt
ss命令可快速查看网络连接状态

注意,调整参数笔者建议修改 /etc/sysctl.conf 文件

  • 全连接、半连接队列相关参数优化
TCP 连接队列相关解释,如果半连接或者全连接队列超过长度大小限制,内核会丢弃或者返回RST报文。

1.超出队列大小后内核对于握手报文的处理
cat /proc/sys/net/ipv4/tcp_abort_on_overflow
0(默认,建议)
参数值为 0: 全连接队列满了,server扔掉client发送的ack
客户端认为服务端并未收到ACK,然后重传,服务端继续扔掉ACK,然后重传SYN+ACK直到客户端加入全连接队列或者达到双方重传上限次数。
会造成客户端 connection time out错误,errno=110

参数值为 1:全连接队列满了,新的连接不能加入,server发送reset包给client
TCP全连接队列溢出,会造成客户端connection reset by peer的错误,errno=104

2. 调整全连接队列大小
全连接队列的最大值取值 min(somaxconn, bakclog)
cat /proc/sys/net/core/somaxconn
128(默认)

echo 1024 > cat /proc/sys/net/core/somaxconn
backlog是listen(int sockfd, int backlog)中backlog的大小,如果是Nginx
listen 8080 default backlog=1024 (如果已经调整了上面两个参数1024,nginx默认启动后全连接队列就是511)

不同的Web服务配置不同,看看源码是什么参数

将 tcp_abort_on_overflow 设置为 1 ,如果客户端收到很多 reset 报文,则全连接队列可能太小了。
调整完全连接队列后,tcp_abort_on_overflow  还是建议为 0 ,以应对突发情况。因为不会立即返回 reset,会给客户端重试机会。

3. 调整半连接队列大小
单纯增大半连接没有用处,得全连接队列也增大。
/proc/sys/net/ipv4/tcp_max_syn_backlog
128(默认)


4. 系统同时保持tw状态的连接数量
系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数量,TIME_WAIT套接字会被立即清楚并打印警告信息
cat /proc/sys/net/ipv4/tcp_max_tw_buckets
16384(默认)


5. client端syn重传次数
cat /proc/sys/net/ipv4/tcp_syn_retries
6(默认)
重传的时间周期:(1s后重传->2s后重传->4s->8s->16S->32s->64s)
建议调整
调整为1的示例:
echo 1 > /proc/sys/net/ipv4/tcp_syn_retries

6.server端syn+ack重传次数
cat /proc/sys/net/ipv4/tcp_synack_retries
5(默认)
重传的时间周期:(1s后重传->2s后重传->4s->8s->16S->32s)


7.开启syncookies
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
  • 预防SYN攻击
预防SYN攻击===> 笔者认为内网应该很少遇见

1.增加半连接队列的大小
++ tcp_max_syn_backlog
++ somaxconn
++ backlog

2.开启tcp_syncookies
cat /proc/sys/net/ipv4/tcp_syncookies
1
默认是1 ,表示在syn backlog(tcp_max_syn_backlog)队列满员时会开启此功能

调整为2,表视无条件开启syncookies功能

3.减少SYN+ACK 重传次书
echo 1 >  /proc/sys/net/ipv4/tcp_synack_retries
  • TCP挥手优化
TCP挥手优化

1.开启syncookies
cat /proc/sys/net/ipv4/tcp_syncookies
1
建议调整为1

2.调整TCP回收时间, 新的连接可以立即使用TIME-WAIT状态下的连接
cat /proc/sys/net/ipv4/tcp_tw_reuse
1
建议调整为1

3.开启TCP连接中TIME-WAIT的快速回收
cat /proc/sys/net/ipv4/tcp_tw_recyle
1
建议调整为1

注意:2和3建议开启2网上推荐的。笔者自测发现开启3就能快速回收TIME_WAIT。


4.调整tcp fin wait 2状态的超时时间
cat /proc/sys/net/ipv4/tcp_fin_timeout
60
注意:这个参数在Linux中并非2MSL,而是fin-wait-2 状态超时时间。
要调整TIME_WAIT参数,linux中需要修改内核宏定义重新编译,windows可以在注册表中修改。

大家可以调整这个参数,然后再看Timer等待的时间。
无论改成多少,笔者测试还是从60秒开始计时。

netstat -ntpo 查看timer值
  • TCP其他参数优化项

TCP 接收和发送缓冲区大小的默认值和最大值
net.core.wmen_default
net.core.wmen-max
net.core.rmem_default
net.core.rmem-max

TCP保活机制 (以下数值单位均为秒)

TCP保活机制中发送探测报文前的空闲时间
cat /proc/sys/net/ipv4/tcp_keepalive_time
7200(默认)

TCP保活机制中连续发送探测报文的间隔时间
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
30(默认)

TCP保活机制中发送探测报文的次数
cat /proc/sys/net/ipv4/tcp_keepalive_probes
9(默认)

net.ipv4.tcp_keepalive = 120
net.ipv4.tcp_keepalive_intval = 30
net.ipv4.tcp_keepalive_probes = 3
  • 汇总优化项目
注意:以下内容仅为笔者总结,并未全部长期测试,建议自测后使用。
汇总所有优化项目 ==> 个人虚拟机食用
vi /etc/sysctl.conf

# 超时重传的次数 ==> 建议减少重试次数, 以太网环境下
net.ipv4.tcp_syn_retries = 3
net.ipv4.tcp_synack_retries = 3

# 队列满员情况下处理机制 ==> 建议保持默认
net.ipv4.tcp_abort_on_overflow = 0

# 半、全连接队列大小设置 ==> 建议适当增大
net.ipv4.tcp_max_syn_backlog = 1024
net.core.somaxconn = 1024

# 默认就开启的  ==>非外层设备也可以考虑关闭
net.ipv4.tcp_syncookies = 1

# 快速回收连接 ==> 建议减少超时时间
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

# tcp 心跳保持 ==> 纯TCP服务建议调整
net.ipv4.tcp_keepalive = 120
net.ipv4.tcp_keepalive_intval = 30
net.ipv4.tcp_keepalive_probes = 3

# time wait 保持个数 ==> 建议适当增大
net.ipv4.tcp_max_tw_buckets = 30000 

sysctl -p
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容