https://my.oschina.net/u/4087916/blog/3051356
 

0. 手把手教你做中间件、高性能服务器、分布式存储技术交流群

手把手教你做中间件、高性能服务器、分布式存储等 (redis、memcache、nginx、大容量 redis pika、rocksdb、mongodb、wiredtiger 存储引擎、高性能代理中间件),git 地址如下:

git 地址:https://github.com/y123456yz/middleware_development_learning

1. time_wait 状态产生条件

只有在正常四次挥手关闭连接的情况下,在主动关闭连接的一方会出现一段时间的 time_wait。如果启用了快速回收功能,回收时间和网络延迟状况有关,正常情况下小于 1s,如果没有开启 time_wait 快速回收功能,则 time_wait 回收时间默认 60s。

三次挥手过程(FIN+ACK, FIN+ACK,ACK)的情况,例如杀掉一段进程,第一个发送 FIN+ACK 的一端也会产生 time_wait。

2.  Time_wait 状态相关参数说明

TCP 中有和 time_wait 状态相关的参数有以下四个:

tcp_tw_recycle

表示开启 TCP 连接中 time_wait 的快速回收功能,默认为 0,表示关闭;生效前提是必须启用本端和对端 tcp_timestamps 配置。

tcp_timestamps

时间戳选项,只有在该选项置 1 的时候 tcp_tw_recycle 才会生效。

tcp_max_tw_buckets

表示系统同时保持 time_wait 的最大数量,如果超过这个量,time_wait 将打印警告信息。超限的时候后面产生的 time_wait 直接不处理,释放资源。注意:是新的连接直接释放资源,老的连接还是处于 time_wait 状态。

Tcp_tw_reuse

客户端大量 time_wait 状态存在时,端口被占用,当有新的连接,如果没有可用端口,则会连接失败。启用该功能后,可以复用 time_wait 状态的连接。客户端 tcp_tw_reuse 生效前提是启用本端和对端 tcp_timestamp。

Tcp_tw_reuse 端口重用功能一般只针对客户端,因为服务端一般都是监听固定端口,端口数是固定的,端口不会用完。而客户端每次连接端口一般都是由协议栈自动分配。

3. Time_wait 快速回收

3.1 快速回收功能失效前提

Time_wait 快速回收功能生效前提:启用 tcp_tw_recycle,并启动本端和对端 tcp_timestamps 配置。启用 timestamps 功能时,报文中会携带时间戳选项信息,抓包如下:

3.2 启用 time_wait 快速回收功能副作用

如果启用了 tcp_tw_recycle 和 tcp_timestamps,如果接收报文四层选项字段带有时间戳信息,则会对时间戳进行检查,对不满足条件的包会直接丢弃,可能会造成客户端连接建立不成功。例如网络路由信息反复变化,移动 cmwap 网络发来的包的时间戳乱跳,同一局域网通过路由器做 NAT 访问服务器 (因为做 NAT 后,源 IP 就变为路由器的 IP 了,如果局域网内各个电脑系统时间不一致,则会出现) 等情况有可能会出现部分连接异常。原因是 tcp_tw_recycle/tcp_timestamps 以及对端 tcp_timestamps 都开启的条件下,60s 内同一源 ip 主机的 socket connect 请求中的 timestamp 必须是递增的。不同主机经过路由器做 NAT 后,报文的源 IP 地址就变为路由器的 IP 地址了。

3.3 内核协议栈相关主要源码

Time_wait 状态生成及快速回收相关代码:

开启 timestamps 引起的丢包相关源码如下:

4. 客户端端口重用

4.1 客户端大量 time_wait,端口重用前提

启用 tcp_tw_reuse,并启动本端和对端 tcp_timestamps 配置。

4.2 内核协议栈相关主要源码

5. 大量 timewait 对客户端、服务端影响

5.1 客户端大量 time_wait 影响

  1. 大量 time_wait 会造成连接资源不释放,内存无法回收。
  2. 由于客户端端口一般采用协议栈随机分配的方式,协议栈会给每个客户端连接分配一个未使用的端口,因此如果客户端同一 IP 对应的 time_wait 数量超过 ip_local_port_range 设置的最大值(也就是 65000),端口将被用完,连接会无法建立。

5.2 服务端大量 time_wait 影响

由于服务端只占用监听端口,因此不存在端口用完的现象。服务端大量 time_wait 唯一影响是:资源不释放,内存无法回收。

6. 测试验证

本次测试结果采用 sysbench.short 来压测 cobar 来验证,客户端物理设备和服务端物理设备的 ip_local_port_range (1024~65000) 和 tcp_max_tw_buckets (81920) 参数都是默认值,测试结果如下:

  1. 当 cobar 服务端 time_wait 数达到 81920 的时候,任然可以继续接收客户端连接,能够正常提供连接服务。
  2. 当客户端测试工具 sysbench.short 服务器上的 time_wait 数达到 60000 多的时候,客户端连接失败,无法连接,因为端口用完。打印:Cannot assign requested address; Cobar 服务器 time_wait 超限时打印:

Cobar 服务器 time_wait 超限的情况下,客户端 sysbench 压测结果基本不受影响,如下:

从上面测试可以看出,服务端 time_wait 不会影响客户端建链,只是占用内存。如果是客户端出现大量 time_wait 状态,此时端口用完,则无法建立连接。以上测试结论符合理论、代码分析。

 

7. 三种解决 time_wait 方法总结

Time_wait 快速回收

端口重用

限制 Tcp_max_tw_buckets

配置方法

在需要进行 time_wait 快速回收的一端进行一下配置:

tcp_tw_recycle:1

本端 tcp_timestamps:1

对端 tcp_timestamps:1

在需要进行 time_wait 快速回收的一端进行一下配置:

tcp_tw_reuse:1

本端 tcp_timestamps:1

对端 tcp_timestamps:1

配置 Tcp_max_tw_buckets

的值在 60000 以下。例如配置为 30000

副作用

在某些情况下可能引起用户建连接失败(例如需要直接返回给用户信息的服务器)

比较暴力,不符合 TCP 协议规范

在某些情况下可能引起用户建连接失败(例如需要直接返回给用户信息的服务器)

部署复杂,需要同时改服务端,而服务端比较多。

服务器时间戳会带出 IDC,经过中间各种网络设备,尤其是运营商的无线设备等,如果某个设备对时戳有校验,则会产生丢包问题。

比较暴力,不符合 TCP 协议规范

应急的处理,立竿见影。

建议这种。

[转帖]linux 内核协议栈 TCP time_wait 原理、配置、副作用的更多相关文章

  1. TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现

    题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ...

  2. Linux 内核协议栈之TCP连接关闭

    Close行为: 当应用程序在调用close()函数关闭TCP连接时,Linux内核的默认行为是将套接口发送队列里的原有数据(比如之前残留的数据)以及新加入 的数据(比如函数close()产生的FIN ...

  3. CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

    CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

  4. Linux内核的TCP协议栈和内核旁路的选择?

    [前言]最近在实习公司用到了solarflare的万兆网卡,用到了网卡的openonload技术还有TCPDirect模式代码的编写,其理论基础都是内核旁路.网上关于内核旁路技术的介绍基本就两篇,我结 ...

  5. Linux 内核协议栈 学习资料

    终极资料 1.<Understanding Linux Network Internals> 2.<TCP/IP Architecture, Design and Implement ...

  6. 写在学习linux内核协议栈之前

    一直很喜欢内核,但是新手,非常的痛苦啊.现在看一本linux内核协议栈源码解析一书,将自己学习的经历以及 理解记录下来,以备将来回头查漏补缺,同时校正自己的理解错误,自勉

  7. Linux内核中TCP SACK机制远程DoS预警通告

    漏洞描述 2019年6月18日,RedHat官网发布报告:安全研究人员在Linux内核处理TCP SACK数据包模块中发现了三个漏洞,CVE编号为CVE-2019-11477.CVE-2019-114 ...

  8. Linux内核[CVE-2016-5195] (dirty COW)原理分析

    [原创]Linux内核[CVE-2016-5195] (dirty COW)原理分析-二进制漏洞-看雪论坛-安全社区|安全招聘|bbs.pediy.com https://bbs.pediy.com/ ...

  9. [转帖]Linux内核系统体系概述

    Linux内核系统体系概述 https://www.cnblogs.com/alantu2018/p/8447369.html Linux 内核主要由 5 个模块构成,它们分别是: 进程调度模块 用来 ...

  10. [转帖]Linux内核为大规模支持100Gb/s网卡准备好了吗?并没有

    Linux内核为大规模支持100Gb/s网卡准备好了吗?并没有 之前用 千兆的机器 下载速度 一般只能到 50MB 左右 没法更高 万兆的话 可能也就是 200MB左右的速度 很难更高 不知道后续的服 ...

随机推荐

  1. Mysql在sql中截取时间类型字段的年月日和时间

    DATE_FORMAT() 函数 DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据. 下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式.我们使用 NOW() 来获得当 ...

  2. 2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在

    2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在 ...

  3. c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?

    vlc.exe.lnk双击这个文件,能正常打开vlc,但是用System.Diagnostics.Process.Start(Path.GetFullPath("vlc.exe.lnk&qu ...

  4. 华为云AOM 2.0版本发布

    摘要:AOM作为华为云面向租户的统一运维门户,将在7月1日重磅发布2.0版本. 本文分享自华为云社区<华为云AOM发布2.0版本,3大特性亮相>,作者:华为云PaaS小助手. 6月16日华 ...

  5. JPEG/Exif/TIFF格式解读(1):JEPG图片压缩与存储原理分析

    JPEG文件简介 JPEG的全称是JointPhotographicExpertsGroup(联合图像专家小组),它是一种常用的图像存储格式, jpg/jpeg是24位的图像文件格式,也是一种高效率的 ...

  6. ByteHouse:基于ClickHouse的实时数仓能力升级解读

     更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   ByteHouse是火山引擎上的一款云原生数据仓库,为用户带来极速分析体验,能够支撑实时数据分析和海量数据离 ...

  7. IIS 设置超时时间

    高级设置 => 限制 => 连接超时(秒),默认120秒,根据实际情况调整

  8. Jmeter软件测试

    1.1. 性能测试是什么 基于协议模拟用户发出请求,对服务器形成一定负载,来测试服务器的性能指标是否满足要求 性能指标关注点:时间性能.空间性能 性能测试与页面无关 性能测试定义:指通过自动化的测试工 ...

  9. 多图预警,DreamBooth 微调黑客松结果发布啦!

    去年 12 月底,我们面向全球的开发者举办了 DreamBooth 编程马拉松活动.通过 DreamBooth,你可以使用少量的图像对文生图模型进行微调,将你「喂给」模型的图片信息进行命名,就可以通过 ...

  10. termius macos 破解版,激活版下载,永久激活,亲测可用

    termius 是一款非常值得推荐的 SSH/SFTP 跨平台终端工具,其十分亮眼的功能是可以上传文件夹,这是其他几款终端工具都不具备的,比如说 macOS 自带的终端.号称 21 世纪最强终端的 w ...