前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >靓仔! 能跳出TIME-WAIT的坑吗

靓仔! 能跳出TIME-WAIT的坑吗

作者头像
用户2825413
发布2019-12-02 22:41:17
1.3K0
发布2019-12-02 22:41:17
举报

1. 开篇语

在TCP断开连接四次挥手时, 主动发起关闭方会产生 TIME_WAIT, TIME_WAIT 是 TCP 协议可靠性设计的重要一个环节, 虽说增强了可靠性, 但是对于高并发场景下, 会产生大量的 TIME_WAIT, 导致高峰时段无端口可以使用.

本文只做简单学习测试, 不保证内容的全面性及正确性, 不要轻易修改正式环境内核配置

今天主要对两个 Linux 内核的配置 tcp_tw_reuse 和 tcp_tw_recycle 进行测试讲解

2. 搭建实验环境

为了方面模拟网络情况, 我们设置可用端口区间仅为81

代码语言:javascript
复制
sysctl -w "net.ipv4.ip_local_port_range=81 81"

3. 默认配置测试

访问本地nginx服务

代码语言:javascript
复制
curl http://127.0.0.1

curl http://127.0.0.1
curl: (7) Failed to connect to 127.0.0.1: Cannot assign requested address

查看网络状态

代码语言:javascript
复制
netstat -napo |grep 127.0.0.1

我们可以看到, 第一次正常, 在 2MSL 时间内, 再次访问将会出现无法分配请求地址错误. 在 Linux 中TIME_WAIT时间为60s,并且还无法修改

TIME_WAIT过期时间宏定义

代码语言:javascript
复制
//include/net/tcp.h
/* how long to wait to destroy TIME-WAIT
 * state, about 60 seconds   */
#define TCP_TIMEWAIT_LEN (60*HZ) 

验证时间

可以看到标红线的地方为 time_wait 的倒计时,到时间后将会自动释放端口.

4. 关于 TIME_WAIT 情况的配置指令

开启 tcp_tw_reuse
代码语言:javascript
复制
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

进行测试

我们可以观测到, 在 TIME_WAIT 状态的端口也可以继续完成请求, 但不会改变 TIME_WAIT 本身的状态和计时.

此结论证明, 当本地端口将耗尽时, 可以尝试开启 tcp_tw_reuse 进行端口重用.

It's not SO_REUSEADDR socket option. SO_REUSEADD is used for binding socket to LISTEN state even if it is in TIME_WAIT state.

开启 tcp_tw_recycle

开启 tcp_tw_recycle

代码语言:javascript
复制
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 

进行测试

结果很好, 同样完成了请求测试. 但是似乎跟 tcp_tw_reuse 哪里不太一样?

对比开启 tcp_tw_reuse 的netstat检测结果, 看看有什么差异.

我们发现这里简直就是暴力美学, 根本没有 TIME_WAIT 的状态呀

linux内核判定代码

当开启回收时,我们的 timeout 值为 rto, 这是一个非常短的一个时间, 否则为 TCP_TIMEWAIT_LEN , 还记得文章开头提到的宏定义的时间吗, 没错, 这里指的就是那个60s.

5. tcp_tw_reuse 与 tcp_tw_recycle 的区别

似乎这两个参数都能够很好的工作, 至少测试结果是很理想的.

参数

功能

tcp_tw_reuse

复用(reuse),不改变 TIMEWAIT 状态

tcp_tw_recycle

回收(recycle),最快时间回收

net.ipv4.tcp_timestamps 默认开启, 他是记录标记时间戳

tcp_tw_reuse 是怎么工作的

如果开启了 tcp_tw_reuse, 如果客户端发来的时间戳大于先前连接内核记录的最新时间戳, 则 Linux 将重新使用状态中的现有连接以 TIME-WAIT 用于新的对外请求连接, 状态中的传出连接 TIME-WAIT可在仅一秒之后重复使用.

tcp_tw_recycle 是怎么工作的

如果开启了 tcp_tw_recycle, 则内核会记住客户端上次发来数据包的时间戳, 如果发来的数据包时间戳小于内核记录的最后发来的数据包时间戳, 那么将会丢弃此数据包, 这种情况在 NAT 模式下多机器时间滞后或同时发送, 会有很大危险, 会造成难以排查的异常情况.

网上说 设置net.ipv4.tcp_timestamps=0, 可以不再检测时间戳, 未找到官方出处, 真实性无法保证.

6. 结论:

在服务器端,请勿启用net.ipv4.tcp_tw_recycle 除非你非常确定你的服务中永远不会有NAT设备。 启用net.ipv4.tcp_tw_reuse 对于发送请求 (outgoing connection) 的连接有效。

在客户端,启用 net.ipv4.tcp_tw_reuse 是另一个几乎安全的解决方案

而且,在设计协议时,不要先让客户关闭。客户端不必处理将TIME-WAIT状态推向更适合处理此问题的服务器的状态。

所以最终建议可以开启 tcp_tw_reuse, 禁用 tcp_tw_recycle.

7. 附TCP状态图

参考资料:

https://vincent.bernat.ch/en/blog/2014-tcp-time-wait-state-linux#netipv4tcp_tw_reuse

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 呆呆熊的技术路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2. 搭建实验环境
  • 3. 默认配置测试
  • 4. 关于 TIME_WAIT 情况的配置指令
    • 开启 tcp_tw_reuse
      • 开启 tcp_tw_recycle
      • 5. tcp_tw_reuse 与 tcp_tw_recycle 的区别
        • tcp_tw_reuse 是怎么工作的
          • tcp_tw_recycle 是怎么工作的
          • 6. 结论:
          • 7. 附TCP状态图
          相关产品与服务
          NAT 网关
          NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档