Karp

Cannot assign requested address 踩坑及解决方案
curl: (7) Failed to connect to 192.168.xxx.xx: Cannot ass...
扫描右侧二维码阅读全文
14
2019/11

Cannot assign requested address 踩坑及解决方案

curl: (7) Failed to connect to 192.168.xxx.xx: Cannot assign requested address

今天让阿里大神教育了一波 改下 不提倡发脾气.
还是上面的问题 . 事情很简单 客户端 -> API 服务 -> slb -> 后端服务

111.png
问题就是 curl slb 出问题. curl 后端服务IP 成功ok 的!.

我copy 下聊天记录:

大神:这个是客户端问题
大神:需要看下客户端
大神:客户端收集下sysctl -a | grep port
大神:netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
大神:上面的命令也收集下
Me:我就一个问题 直连为什么可以
Me:我slb 后面 就一台机器
大神:这个报错是在API服务这台设备上报错的吧
大神:上面收集的内容是在API服务这台设备上收集的吗
Me:我就一个问题 直连为什么可以 多余的 不要说什么 端口沾满 过不去
大神:您需要理解什么是 Cannot assign requested address,先理解这个报错,自然能回答为什么到后端ECS不会有问题
大神:1. 连接是需要占用端口的,SLB的IP和目的端口不变,客户端的IP不变,只有客户端的源端口是变化的
大神:每一个新的连接就是新的四元组 客户端ip+客户端端口+目的IP+目的端口
大神:这4元组里面可以看到,变量只有客户端端口,其他都是固定的
大神:客户端端口是一个范围,如您所示是3w-6w,所以一共最多建立3w个连接
大神:目前您已经有2w多个连接,如果偶尔连接数突发,那服务器本身就没有额外的端口,就无法建立新的连接
大神:但是如果您更换为ECS的IP,那这个变量里面(客户端ip+客户端端口+目的IP+目的端口 )
大神:目的IP就变了,目的IP从SLB的IP变为ECS的IP,这时候ECS的连接又新增了3W个,所以少量和ECS的连接是不会出问题的,因为和ECS的直连连接占不满3W个端口
大神:问题本质就是:短连接过多,导致timewait连接过多,消耗的本地端口过多,当新连接建立的时候服务器本身无法分配新端口就有 Cannot assign requested address 的日志
大神:Cannot assign requested address 这个报错可以百度或者google,这个报错信息是Linux定义的
Me:哦 感谢解惑 
那 是不是说 slb 后面目标机器只有1台 那 最多就 3w 左右连接 
如果后面增多 就会是 n *3w
大神:不是的
大神:因为你的API客户端是跟SLB的IP连接的,跟SLB后端的ECS多少无关
大神:在客户端IP看来,我的连接就是指向的SLB的IP和目的端口
Me:那 需要APi 客户端增加机器 [捂脸哭]
Me:SLB 升级是没有用的 对吧
大神:对的,跟SLB完全没关系,是客户端端口分配光了,所以无法分配新的端口,所以就建立不了新的TCP连接
大神:net.ipv4.ip_local_port_range = 32768    60999
大神:这个您可以尝试把端口范围该大一些,目前是3w-6w范围,一个就3w个端口
Me:非常感谢 解惑
大神:可以更改为1w-6w,那就有5w个端口
大神:但是如果连接数超过5w,还是有问题。 那就只能添加一下API网关的客户端数量 或者 减少timewait的连接的状态数量,减少占用端口的连接数

在遇到上面问题 Cannot assign requested address 先查询是否存在大量 time_wait

netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

再检查下 端口开放范围

sysctl -a | grep port

// net.ipv4.ip_local_port_range = 32768    60999

实际上我们一般线上服务都是开放 6w 个端口 . 这台机器仅有3w个端口 .
经过指点我们端口开放至 6w 如果不足则增加 api 服务器

最后修改:2020 年 12 月 02 日 04 : 10 PM

发表评论