一、本地端口有哪些可用

首先,需要了解到TCP协议中确定一条TCP连接有4要素:local IPlocal PORTremote IPremote PORT。这个四元组应该是唯一的。

在我们发送HTTP请求的时候,local IP remote IP remote PORT是固定的,只有local PORT是可变的,可用的local PORT的数量就限制了client和server之间TCP连接数的数量。

TCP协议中PORT部分是用两个字节来表示的,也就是说可用的端口数量肯定不能超过65536个。

  1. sysctl -a|grep net.ipv4.ip_local_port_range
  2.  
  3. net.ipv4.ip_local_port_range =

表示client可用的端口是[32768, 61000],共28233个。那么这台机器和另外任意一台机器,同时只能建立28233个TCP连接。

可打开的最大文件数

ulimit -a

  1. core file size (blocks, -c)
  2. data seg size (kbytes, -d) unlimited
  3. scheduling priority (-e)
  4. file size (blocks, -f) unlimited
  5. pending signals (-i)
  6. max locked memory (kbytes, -l)
  7. max memory size (kbytes, -m) unlimited
  8. open files (-n)
  9. pipe size ( bytes, -p)
  10. POSIX message queues (bytes, -q)
  11. real-time priority (-r)
  12. stack size (kbytes, -s)
  13. cpu time (seconds, -t) unlimited
  14. max user processes (-u)
  15. virtual memory (kbytes, -v) unlimited
  16. file locks (-x) unlimited

/etc/security/limits.conf

  1. #Where:
  2. #<domain> can be:
  3. # - a user name
  4. # - a group name, with @group syntax
  5. # - the wildcard *, for default entry
  6. # - the wildcard %, can be also used with %group syntax,
  7. # for maxlogin limit
  8. #
  9. #<type> can have the two values:
  10. # - "soft" for enforcing the soft limits
  11. # - "hard" for enforcing hard limits
  12. #
  13. #<item> can be one of the following:
  14. # - core - limits the core file size (KB)
  15. # - data - max data size (KB)
  16. # - fsize - maximum filesize (KB)
  17. # - memlock - max locked-in-memory address space (KB)
  18. # - nofile - max number of open file descriptors
  19. # - rss - max resident set size (KB)
  20. # - stack - max stack size (KB)
  21. # - cpu - max CPU time (MIN)
  22. # - nproc - max number of processes
  23. # - as - address space limit (KB)
  24. # - maxlogins - max number of logins for this user
  25. # - maxsyslogins - max number of logins on the system
  26. # - priority - the priority to run user process with
  27. # - locks - max number of file locks the user can hold
  28. # - sigpending - max number of pending signals
  29. # - msgqueue - max memory used by POSIX message queues (bytes)
  30. # - nice - max nice priority allowed to raise to values: [-, ]
  31. # - rtprio - max realtime priority
  32. #
  33. #<domain> <type> <item> <value>
  34. #
  35.  
  36. #* soft core
  37. #* hard rss
  38. #@student hard nproc
  39. #@faculty soft nproc
  40. #@faculty hard nproc
  41. #ftp hard nproc
  42. #@student - maxlogins
  43.  
  44. # End of file
  45. root soft nofile
  46. root hard nofile
  47. * soft nofile
  48. * hard nofile

二、短连接并不会同时存在大量TCP连接,端口为什么还是耗尽了?

上一步我们分析到,client和server之间只能同时存在28233个TCP连接,但是我们的压测用的是短连接,连接用完就释放掉了,端口应该也会释放掉,为啥还会产生端口耗尽的问题呢?

这就需要提到TIME_WAIT这个状态了,TCP连接断开的时候,主动发起连接断开操作的一方,最后会停留在TIME_WAIT状态,会持续2*MSL的时长,

这个状态的端口是不能被使用的,准确的说是当新的TCP连接的local IP remote IPremote PORT和TIME_WAIT状态的连接一致时这个端口不能被使用。

  1. sysctl -a|grep net.ipv4.tcp_fin_timeout
  2.  
  3. net.ipv4.tcp_fin_timeout =

可以推论:

  1. 如果client机器有28233端口可用,TIME_WAIT 60秒,短连接的方式发起请求,那么这个client发起的请求的QPS是不能超过28233/60的。

三、为什么有TIME_WAIT状态

想象这么一个场景:

  1. A和B建立了一个TCP连接,A向B发送消息包1 2 3,消息包3传给B的时候延迟了,A又重传了消息包3,A和B完成通信断开连接,双方都很happy。

    2. A和B又建立一个TCP连接,用了相同的local IPlocal PORTremote IPremote PORT,A向B发送消息包1 2,B收到1 2之后

上一个连接延迟的消息包3来了,B无法区分这个消息包是上一个TCP连接的

TIME_WAIT状态主要就是为了解决这个问题:防止延迟的无效消息包被误认为是合法的。

TIME_WAIT状态持续2倍MSL之后,可以确保老的TCP连接逗留在网络上的消息包已经全部消失了。

四、单台机器发送请求每秒要超过(可用端口数/tcp_fin_timeout)怎么办

使用长连接或者打开tcp_tw_reuse

那么为什么打开tcp_tw_reuse就可以使用TIME_WAIT状态的端口呢?不怕延迟的消息包被误认为合法的么?

这里就需要提到另外一个选项了:tcp_timestamps,打开这个选项之后,TCP包里面会带上发包机器的当前时间戳。

可以这么想象一下:如果每个TCP包带上原始发包时的时间戳,如果一个延迟的消息包到达B,B可以拿这个消息包的时间和TCP连接建立的时间做一个对比,

如果消息包的时间比较早,那么这就是上一个TCP连接延迟的消息包,丢弃掉就好。

通过时间戳的比较,也可以解决延迟消息包被误认为合法的问题。因此同时打开tcp_timestampstcp_tw_reuse之后,client端的TIME_WAIT端口是可以被复用的。

但要注意的是:

1. tcp_timestamps需要client和server端同时打开才生效(我们这次遇到端口耗尽的问题就是因为server端没有打开tcp_timestamps选项)

2. tcp_timestamps精确到秒,也就是TIME_WAIT状态的端口也在下一秒才可以重用,如果继续使用短连接的话,发送请求的QPS是不能超过可用端口数的

参考:

端口占用问题

TCP首部的TimeStamp时间戳选项

解决端口耗尽问题: tcp_tw_reuse、tcp_timestamps的更多相关文章

  1. 避免 TCP/IP 端口耗尽

    转载:http://www.cnblogs.com/tianzhiliang/archive/2011/06/27/2091214.html 当客户端启动到服务器的 TCP/IP 套接字连接时,客户端 ...

  2. 系统 TIME_WAIT累积与端口耗尽的问题

    调整内核参数 net.ipv4.tcp_tw_reuse = net.ipv4.tcp_tw_recycle = 这两个参数可以让 tcp 连接回收.再利用. 摘录  『HTTP 权威指南』page ...

  3. Windows解决端口占用问题

    Windows解决端口占用问题 步骤 1. win + R,输入cmd回车进入dos界面 2. 输入netstat -ano|findstr 8080 查看占用8080端口的进程 3. 输入taskk ...

  4. 【Azure 应用服务】App Service/Azure Function的出站连接过多而引起了SNAT端口耗尽,导致一些新的请求出现超时错误(Timeout)

    问题描述 当需要在应用中有大量的出站连接时候,就会涉及到SNAT(源地址网络转换)耗尽的问题.而通过Azure App Service/Function的默认监控指标图表中,却没有可以直接查看到SNA ...

  5. tomcat 解决端口8080冲突

    这样的问题有时会因为eclipse等IDE使用bug导致. 解决方法: 使用dos 命令 运行---cmd--netstat -ano|findstr 8080 键入命令后,dos下会显示正在使用80 ...

  6. sping获取bean方法 解决资源耗尽

    // ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationCon ...

  7. windows和linux下杀死Tomcat进程,解决端口占用

    windows和linux下解决Tomcat进程 windows下启动Tomcat报错,8080端口号被占用,报错信息如下 两种解决方法,一种是关闭了这个端口号,另外一种是修改Tomcat下的serv ...

  8. Windows解决端口被占用问题

    第一种解决方法,以8080端口为例 打开命令行输入 cmd ,输入netstat -ano 会显示所有已经在运行的端口情况.PID为进程id 输入你想要查的正在占用的端口号,netstat -ano ...

  9. 解决端口被占用问题(端口timewait)

    当jmeter做千级并发时,有报错的接口,查看是不是本地端口被占用完了 netstat -an   查看是否有端口在 timewait timewait是知道用那个端口,但是端口被别人占用着 见tcp ...

随机推荐

  1. SQL Server 权限控制

    根据数据库Schema限制用户对数据库的操作行为 授予Shema dbo下对象的定义权限给某个用户(也就是说该用户可以修改架构dbo下所有表/视图/存储过程/函数的结构) use [Your DB N ...

  2. 你可能不知道的IDEA高级调试技巧

    一.条件断点 循环中经常用到这个技巧,比如:遍历1个大List的过程中,想让断点停在某个特定值. 参考上图,在断点的位置,右击断点旁边的小红点,会出来一个界面,在Condition这里填入断点条件即可 ...

  3. [转]用JAVA在读取EXCEL文件时如何判断列隐藏

    原文地址:https://www.cnblogs.com/OwenWu/archive/2012/01/03/2310620.html org.apache.poi.hssf.usermodel.HS ...

  4. 框架源码系列五:学习源码的方法(学习源码的目的、 学习源码的方法、Eclipse里面查看源码的常用快捷键和方法)

    一. 学习源码的目的 1. 为了扩展和调优:掌握框架的工作流程和原理 2. 为了提升自己的编程技能:学习他人的设计思想.编程技巧 二. 学习源码的方法 方法一: 1)掌握研究的对象和研究对象的核心概念 ...

  5. Linux 正则表达式_010

    Linux 正则表达式 标注:本教程只针对linux运维的三剑客命令awk,sed,grep正则表达式 什么是正则表达式? 简单的说,正则表达式就是为处理大量的字符串而定义的一套规则和方法通过定义的这 ...

  6. thinkphp5 composer

    前提:已安装composer 1.安装包 https://packagist.org/?query=thinkphp ,tp的各种安装包 2.安装 //安装命令, composer create-pr ...

  7. 外部访问docker容器(docker run -p/-P 指令)

    容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P(大写) 或 -p (小写) 参数来指定端口映射. (1)当使用 -P 标记时,Docker 会随机映射一个 49000~4990 ...

  8. TCP是如何保证可靠传输的

    TCP 协议如何保证可靠传输   一.综述 1.确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就重传. 2.数据校验 3.数据合理分片和排序: UDP:IP数据报大于1500字节 ...

  9. .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable

    项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示 读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示: 合并单元 ...

  10. LeetCode - 769. Max Chunks To Make Sorted

    Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into som ...