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 ...
随机推荐
- 企业安全06-Fastjson-CNVD-2017-02833
Fastjson-CNVD-2017-02833 一.漏洞概述 fastjson在解析json的过程中,支持使用@type字段来指定反序列化的类型,并调用该类的set/get方法来访问属性,当组件开启 ...
- @Transactional自调用问题
- IdentityServer4系列 | 授权码模式
一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...
- 大白话详解大数据HBase核心知识点,老刘真的很用心(3)
老刘目前为明年校招而努力,写文章主要是想用大白话把自己复习的大数据知识点详细解释出来,拒绝资料上的生搬硬套,做到有自己的理解! 01 HBase知识点(3) 第13点:HBase表的热点问题 什么是热 ...
- 阻止brew自动更新
export HOMEBREW_NO_AUTO_UPDATE=true
- moviepy音视频剪辑:使用VideoFileClip、AudioFileClip和write_videofile、write_audiofile进行音视频的加载和输出
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在本地进行音视频处理时,首先要从视频文件 ...
- 第10.8节 Python包的导入方式详解
一. 包导入与模块导入的关系 由于包本质上是模块,其实对模块的许多导入方法都适用于包,但由于包的结构与模块有差异,所以二者还是有些区别的: 对包的导入,实际上就是包目录下的__init__.py文件的 ...
- PyQt(Python+Qt)学习随笔:QTreeWidgetItem项下子项的指示符展示原则childIndicatorPolicy
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件QTreeWidget中的QTreeWidgetItem项下可以有子项,如果存在子项,则父项 ...
- uniapp vue 购车计算器,贷款计算器,保险计算器
基于vue开发的买车计算器,支持uniapp 概述 项目为工作中开发,感觉比较有意思,而且能够帮助其他人快速开发功能,我就发上来了,大佬勿喷吧,没什么技术含量! uniapp打包多端[小程序类]可能会 ...
- THE BUG 队第一次团队作业
1.队名: THE BUG 队 2.队员学号: 杨梓琦 3118005115(队长) 温海源,3118005109 陈杰才,3118005089 李华,3118005097 钟明康,311800512 ...