Cannot assign requested address 和 SO_REUSEADDR 参数
1. 错误
今天项目中出现了大量的java.net.ConnectException: Cannot assign requested address (connect failed)
错误。
刚开始以为是服务提供方的服务器报出来的错误,还和对方怼了几句。但是之后在网上搜索之后发现,这个是客户端机器的问题:
这个错误的报出是由于客户端服务器的出口socket
端口被占用完了,没有办法对新的请求进行分配端口,就会出现这种错误。
排查当时的情况,确实有大量的依赖服务调用出现。
但是这种情况不是每天都有,而是偶发性的。所以和我们自己的服务有关系,由于业务原因导致了端口被占用完了。
2. 原因
google 之后发现了一个大致的原因:建立TCP连接之后,断开连接的一方会进入 TimeWait
状态,此时这个连接是不可以
复用的。而连接是由4元组(localIP/port,serverIp/port)来唯一确定一个连接,对于一个客户端来说,server端的都确定了(单台服务情况),
而本机ip不会变化,所以能变化的只有服务器提供的临时端口。
我们知道端口是由2个字节描述的,也就是范围是65525.再加上服务器有一些默认端口被占用,可供临时分配的端口大概会在2w+左右ref。
当短时间大量请求出现的时候,端口是有占满的可能,此时就会报错误,ref.
既然请求都结束了,为什么还需要占用端口呢,有没有办法复用这些端口呢?
3. 一种解决途径
答案是肯定的,unix 有一个参数 SO_REUSEADDR
设置 处于 Time_wait
状态的端口可以被复用,如下是翻译:
这个socket 参数是用来告诉内核,当一个端口处于Time_wait 状态的时候,依然可以使用这个端口。但是如果端口不是这个状态,那么还是会
得到一个错误:地址被占用。这个参数可以很方便的使用在很快结束并又重新建立连接的服务。
但是你需要知道,如果有其他不可预知的数据进来时,会破坏你的服务。但是这个可能性很低。
Michael Hunter (mphunter@qnx.com) 指出过:网络5元组用于确定连接唯一性。这个参数仅仅说明你可以复用本地的地址。连接还需要保证
网络连接的唯一性。也就是说如果你访问的目标服务器还是同一台,那么连接还会是同一个;如果不是同一台,那么不是同一个连接。
危险仅出现在当一个断开的连接还是在使用中,同一台客户端调用了同一个服务端,此时就会出现使用同一个连接的情况。也就得到意想不到的数据。
这也就是为什么有
Time_wait
状态出现的原因,为了保证短时间内连接不可复用。
原文如下
What exactly does SO_REUSEADDR do?
This socket option tells the kernel that even if this port is busy (in
the TIME_WAIT state), go ahead and reuse it anyway. If it is busy,
but with another state, you will still get an address already in use
error. It is useful if your server has been shut down, and then
restarted right away while sockets are still active on its port. You
should be aware that if any unexpected data comes in, it may confuse
your server, but while this is possible, it is not likely.
It has been pointed out that "A socket is a 5 tuple (proto, local
addr, local port, remote addr, remote port). SO_REUSEADDR just says
that you can reuse local addresses. The 5 tuple still must be
unique!" by Michael Hunter (mphunter@qnx.com). This is true, and this
is why it is very unlikely that unexpected data will ever be seen by
your server. The danger is that such a 5 tuple is still floating
around on the net, and while it is bouncing around, a new connection
from the same client, on the same system, happens to get the same
remote port. This is explained by Richard Stevens in ``2.7 Please
explain the TIME_WAIT state.''.
Cannot assign requested address 和 SO_REUSEADDR 参数的更多相关文章
- Cannot assign requested address出现的原因及解决方案
今天使用python多线程请求服务时,出现Cannot assign requested address错误 网上找了下原因,大致上是由于客户端频繁的连服务器,由于每次连接都在很短的时间内结束,导致很 ...
- TIME_WAIT引起Cannot assign requested address报错
1. 问题描述 有时候用redis客户端(php或者java客户端)连接Redis服务器,报错:"Cannot assign requested address." 原因是客户端 ...
- php连接memcahed出现Cannot assign requested address (99)的解决方法
今天在将服务器合并后,发现php偶尔会报出 Server *.*.*.* (tcp *****) failed with: Cannot assign requested address (99) 的 ...
- Dubbo广播模式下报错:Can't assign requested address解决办法
原因: 尝试使用Dubbo的multicast模式,发现一运行就报Can't assign requested address的错误,造成这种原因的主要是系统中开启了IPV6协议(比如window7) ...
- Cannot assign requested address (connect failed)
压测时,应用服务器报错:Cannot assign requested address (connect failed) 经检查,由于应用服务器,频繁发起http请求,由于每次连接都在很短的时间内结束 ...
- [译]Python - socket.error: Cannot assign requested address
原文来源: https://stackoverflow.com/questions/48306528/python-socket-error-cannot-assign-requested-addre ...
- 使用Java进行udp-demo编程时碰到的consumer和producter无法连接并报出“java.net.SocketException: Can't assign requested address”问题
在用Java编写了一个udp生产者和消费者的demo时,在生产者启动的时候会抛出异常 java.net.SocketException: Can't assign requested address ...
- Cannot assign requested address的解决办法
今天想试一下redis,写了个程序,对redis连续进行100000访问,却出现以了Cannot assign requested address的问题,我起先是以为是redis的问题(可能承受不了这 ...
- Nginx无法监听虚拟VIP的问题报:99: Cannot assign requested address
99: Cannot assign requested address #本地网卡上没有10.0.0.3这个IPNginx就会报错: [root@lb01 conf]# /application/ng ...
随机推荐
- 【mq读书笔记】消息消费过程(钩子 失败重试 消费偏移记录)
在https://www.cnblogs.com/lccsblog/p/12249265.html中,PullMessageService负责对消息队列进行消息拉取,从远端服务器拉取消息后将消息存入P ...
- 关于热力图的loss的一点感想
网络的输出的热力图和gt相减的差矩阵,求其最大特征值的平方作为loss. 若图像h w不相等,可以使用奇异值代替特征值.奇异值往往对应着矩阵中隐含的重要信息,且重要性和奇异值大小正相关.每个矩阵A都可 ...
- VS Code C++ 项目快速配置模板
两个月前我写过一篇博客 Windows VS Code 配置 C/C++ 开发环境 ,主要介绍了在 VS Code 里跑简单 C 程序的一些方法.不过那篇文章里介绍的方法仅适用于单文件程序,所以稍微大 ...
- BloomFilte布隆过滤器简介
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...
- 老猿学5G扫盲贴:3GPP规范中与计费相关的主要规范文档列表及下载链接
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在<老猿学5G扫盲贴:3GPP规范中部分与计 ...
- Python基础教程目录
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python部分代码样例 老猿Python重难点知识博文汇总 老猿Python博客地址 第1章 Python学习环境构建目 ...
- Python匹配对象的groups、groupdict和group之间的关系
匹配对象的groups()方法返回一个包含所有参与匹配的子组(不含组0)的匹配到的搜索文本子串的元组,groupdict返回一个包含所有匹配到的命名组的组名为键值和命名组匹配到的搜索文本子串为值作为元 ...
- PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法
对于Model/View中视图的数据编辑后怎么能实时获取编辑的数据变动位置和变动情况查阅了一些资料,终于基本弄明白必须重写Model的setData方法才能截获.setData方法是视图中各种角色数据 ...
- PHP代码审计分段讲解(14)
30题利用提交数组绕过逻辑 本篇博客是PHP代码审计分段讲解系列题解的最后一篇,对于我这个懒癌患者来说,很多事情知易行难,坚持下去,继续学习和提高自己. 源码如下: <?php $role = ...
- AcWing 326. XOR和路径
大型补档计划 题目链接 如果整体来做,发现既有加法,也有整体异或,这样不容易搞. 考虑异或,各个位置互不干扰,按位考虑一下. 枚举每一位 \(k\) 发现如果设 \(f[u]\) 为这一位的期望结果还 ...