理解和处理Cannot assign requested address错误

原因

“Cannot assign requested address.”是由于linux分配的客户端连接端口用尽,无法建立socket连接所致,虽然socket正常关闭,但是端口不是立即释放,而是处于TIME_WAIT状态,默认等待60s后才释放。

Cannot assign requested address 这个报错信息是Linux定义的

  1. 连接是需要占用端口的,每一个新的连接就是新的四元组:客户端ip+客户端端口+目的IP+目的端口
  2. 目的IP和目的端口不变,客户端的IP不变,只有客户端的源端口是变化的
  3. 问题本质就是:短连接过多,导致timewait连接过多,消耗的本地端口过多,当新连接建立的时候服务器本身无法分配新端口就有 Cannot assign requested address 的日志

场景简述

简单的逻辑图如下

Client-ECS -> ELB --> Nginx-ECS

                                    +---------+
                               +--->|Nginx-ECS|
                               |    +---------+
+------------+       +-----+   |    +---------+
| Client-ECS +------>| ELB |---+--->|Nginx-ECS|
+------------+       +-----+   |    +---------+
                               |    +---------+
                               +--->|Nginx-ECS|
                                    +---------+

出问题的场景是:ClientECS有大量的脚本任务去访问ELB,导致大量的连接处于TIME_WAIT状态;

解决办法

可能解决方法1

调低time_wait状态端口等待时间:

  1. 调低端口释放后的等待时间,默认为60s,修改为15~30s

    sysctl -w net.ipv4.tcp_fin_timeout=30
    
  2. 修改tcp/ip协议配置, 通过配置/proc/sys/net/ipv4/tcp_tw_resue, 默认为0,修改为1,释放TIME_WAIT端口给新连接使用

    sysctl -w net.ipv4.tcp_tw_reuse=1
    
  3. 修改tcp/ip协议配置,快速回收socket资源,默认为0,修改为1

    sysctl -w net.ipv4.tcp_tw_recycle=1
    

可能解决办法2

增加可用端口port_range:

  1. 确认port_range范围

    # sysctl -a |grep port_range
    net.ipv4.ip_local_port_range = 50000    65000
    
  2. 修改配置

    # vi /etc/sysctl.conf
    net.ipv4.ip_local_port_range = 1024     65535
    

改完后,执行命令“sysctl -p”使参数生效。


参考:

posted @ 2020-07-21 17:47  That's_it  阅读(45121)  评论(0编辑  收藏  举报