• 你所不知道的端口耗尽(一)


    问题背景

    有同事联系我说,在生产环境上,访问不了我负责的common服务,然后我去检查common服务的health endpoint, 没问题,然后我问了下异常,timeout导致的System.OperationCanceledException。那大概率是客户端的问题,会不会是端口耗尽,用netstat看下是不是有大量的端口占用,果然如此,大概如图:

    image

    什么是端口耗尽

    端口耗尽(Port Exhaustion)是指当系统中可用的TCP/IP端口号被全部占用,而无法建立新的网络连接时产生的一种情况。例如,在进行大量的网络连接,如客户端与服务器之间频繁地建立和断开连接时,可能会发生端口耗尽。如果客户端在短时间内打开了大量的短暂连接,并且由于TCP协议的TIME_WAIT状态,这些端口不能立即被重用,就可能出现端口耗尽的现象。此时,新的出站连接可能会失败,因为找不到可用的源端口号。

    端口是有限的

    每个TCP或UDP连接由一个四元组唯一标识:源IP地址、源端口号、目的IP地址以及目的端口号。在一个给定的源IP地址中,端口号是有限的,通常是从1024到65535(0到1023保留给系统和知名端口)。

    拓展阅读,如何查看Linux中的可用端口范围

    cat /proc/sys/net/ipv4/ip_local_port_range
    

    什么是TIME_WAIT状态

    在TCP/IP网络中,TIME_WAIT状态是TCP连接结束过程的一部分。这是一个正常的状态,发生在一个连接关闭的准备阶段,此时通常是客户端已经发送了一个FIN(结束)数据包来表示它没有更多数据要发送,并且也已经收到了另一侧(通常是服务器)的确认。

    下面是TIME_WAIT状态在TCP连接终止过程中的作用:

    • 主动关闭:客户端向服务器发送一个FIN数据包,表示它已经完成数据发送。
    • 服务器接收到FIN,发送一个ACK(确认),并进入CLOSE_WAIT状态,表示它已经确认了客户端结束连接的请求。
    • 服务器在发送完所有剩余的数据后,发送自己的FIN数据包。
    • 客户端接收到服务器的FIN,发送回一个ACK,并进入TIME_WAIT状态。

    image

    TIME_WAIT状态会持续一个时间段,这个时间是最大报文生命周期(MSL)的两倍,这是一个确保连接相关的所有数据包不再存在于网络中的定义期间。这个时间通常被设置为2分钟,因此TIME_WAIT状态的持续时间通常是4分钟

    TIME_WAIT状态的主要原因有:

    • 确保网络上延迟的数据包被丢弃,避免可能干扰后续新的连接。
    • 允许TCP连接可靠地结束,确保FIN-ACK握手过程正确结束。
    • 确保如果客户端到服务器的最后一个ACK丢失,客户端仍处于TIME_WAIT状态,这样如果服务器因为没有收到ACK而重新发送FIN,客户端可以重新发送ACK。

    在高流量的服务器中,TCP连接经常地开启和关闭,TIME_WAIT状态以及它的持续时间可能导致大量的套接字处于这个状态,从而可能耗尽可用的端口。

    如何解决

    • 改变TIME_WAIT时间,即减少端口被占用的时间;不推荐,尽量使用默认设置
    • 启用端口重用,例如TCP端口复用(SO_REUSEADDR)选项;
    • 增加可用的端口范围。
    • 保证端口尽早尽快的释放

    👇欢迎扫码关注我的公众号👇
    image

  • 相关阅读:
    C语言--每日五道选择题--Day8
    亚马逊、Shopee、美客多店铺出单量如何提高?有何方法?
    【Jmeter】生成html格式接口自动化测试报告
    Flink的单机部署方式
    java基于ssm的汽车维修保养管理系统
    已更新!c++第四章知识点合集(自定义函数的格式和使用方法详解, #include,函数的嵌套 递归,局部变量与全局变量的区别等等)
    【夯实算法基础】 并查集
    微服务简单实现最终一致性
    opencv控制鼠标事件
    JetBrains系列工具,配置PlantUML绘图
  • 原文地址:https://www.cnblogs.com/kyo-lynn/p/18039079