zhangguanzhang's Blog

server 端的 cannot assign requested address

字数统计: 684阅读时长: 2 min
2022/03/16

由来

今天碰到了这个问题,但是最终结果出乎意料

过程

项目相关部分

客户的 OA 对接我们的应用,使用过程中会调用我们的接口,我们的接口再回调客户的回调地址。调用流是:

1
客户 OA 后端 ----> 我们应用 A 的后端 -----> 我们应用 B 后端  -----> 客户写的回调地址

然后我们接口 A 返回 B 访问回调的报错:

1
"Get http://10.192.xxx.xxx/xxxxinfo?...: dial tcp 10.192.xxx.xxx:80: connect: cannot assign requested address"

排查过程

一开始看到这个报错的时候就知道,这个报错是 TCP 四元组哪个组不够用都会报错这个的,但是最优先和最常见的就是 client 的端口耗尽,也就是 client 端的 port range 不够用了,一般是这个 B 服务机器上 client 的端口达到上限了,可以通过下面参数调整下:

1
sysctl -a |& grep port | grep range

结果实际上上去 B 服务上 curl 这个 url 能返回 http 状态码。起初以为真的是我们服务 B 在瞬间有端口没释放的 bug,但是 curl 能返回 http 状态码(但是内容是空的),说明 tcp 层面没问题。因为 http 返回信息是空的,我们初步怀疑到是客户的回调服务偷偷更新了后导致的。后面让客户取消掉他们回调 url 的后端校验 token 逻辑。他们换了后还是一样,然后他们把这个接口的逻辑代码截图了,以及把回调服务的日志发过来的。

看了下日志,发现报错信息里有 token 校验过的和没有校验成功的,校验失败的那些原因都是过期了。询问了下发现回调的 IP 后面有好几个服务副本,让客户他们去检查机器时间试试,然后客户下班了,另一个同事说可以单独修改我们服务 B 的设置,指向单台副本绕过负载均衡试试,最后发现 5 个每个单独都正常,指向负载均衡的 IP 就不行,询问后发现是硬件负载均衡。最后第二天客户排查到是硬件负载均衡的连接数异常。是深信服的硬件负载均衡。

结论和学习

其实一开始的 curl 正常能返回 http 状态码就说明 tcp 没问题,不过这次也算是见识到了,server 端的端口不够也会返回 cannot assign requested address 的报错,也就是主动打开还是被动打开,这个错误的信息都是一样的。

CATALOG
  1. 1. 由来
  2. 2. 过程
    1. 2.1. 项目相关部分
    2. 2.2. 排查过程
  3. 3. 结论和学习