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 参数的更多相关文章

  1. Cannot assign requested address出现的原因及解决方案

    今天使用python多线程请求服务时,出现Cannot assign requested address错误 网上找了下原因,大致上是由于客户端频繁的连服务器,由于每次连接都在很短的时间内结束,导致很 ...

  2. TIME_WAIT引起Cannot assign requested address报错

    1.  问题描述 有时候用redis客户端(php或者java客户端)连接Redis服务器,报错:"Cannot assign requested address." 原因是客户端 ...

  3. php连接memcahed出现Cannot assign requested address (99)的解决方法

    今天在将服务器合并后,发现php偶尔会报出 Server *.*.*.* (tcp *****) failed with: Cannot assign requested address (99) 的 ...

  4. Dubbo广播模式下报错:Can't assign requested address解决办法

    原因: 尝试使用Dubbo的multicast模式,发现一运行就报Can't assign requested address的错误,造成这种原因的主要是系统中开启了IPV6协议(比如window7) ...

  5. Cannot assign requested address (connect failed)

    压测时,应用服务器报错:Cannot assign requested address (connect failed) 经检查,由于应用服务器,频繁发起http请求,由于每次连接都在很短的时间内结束 ...

  6. [译]Python - socket.error: Cannot assign requested address

    原文来源: https://stackoverflow.com/questions/48306528/python-socket-error-cannot-assign-requested-addre ...

  7. 使用Java进行udp-demo编程时碰到的consumer和producter无法连接并报出“java.net.SocketException: Can't assign requested address”问题

    在用Java编写了一个udp生产者和消费者的demo时,在生产者启动的时候会抛出异常 java.net.SocketException: Can't assign requested address ...

  8. Cannot assign requested address的解决办法

    今天想试一下redis,写了个程序,对redis连续进行100000访问,却出现以了Cannot assign requested address的问题,我起先是以为是redis的问题(可能承受不了这 ...

  9. Nginx无法监听虚拟VIP的问题报:99: Cannot assign requested address

    99: Cannot assign requested address #本地网卡上没有10.0.0.3这个IPNginx就会报错: [root@lb01 conf]# /application/ng ...

随机推荐

  1. 深圳-2020-java面试题分享

    记录一下最近面试接触的面试题. 深圳掌众传媒: union 和union all区别 union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序: union All:对两个结果集进行 ...

  2. 微服务架构下 CI/CD 如何落地

    本文系云原生应用最佳实践杭州站活动演讲稿整理.杭州站活动邀请了 Apache APISIX 项目 VP 温铭.又拍云平台开发部高级工程师莫红波.蚂蚁金服技术专家王发康.有赞中间件开发工程师张超,分享云 ...

  3. 深度学习基础 Probabilistic Graphical Models | Statistical and Algorithmic Foundations of Deep Learning

    目录 Probabilistic Graphical Models Statistical and Algorithmic Foundations of Deep Learning 01 An ove ...

  4. UnityEditorWindow做一个TimeLine的滑动块

    UnityEditorWindow做一个TimeLine的滑动块 最近在做一个基于TimeLine的动画编辑器,在制作TineLine滑动条时遇到问题,网上查了好久,试了好多GUI组件都不满意.最后在 ...

  5. Spring Cloud 学习 (九) Spring Security, OAuth2

    Spring Security Spring Security 是 Spring Resource 社区的一个安全组件.在安全方面,有两个主要的领域,一是"认证",即你是谁:二是& ...

  6. cJSON的使用

    1 安装cJSON github地址:https://github.com/DaveGamble/cJSON.git 下载完成后进入cJSON目录,执行下面命令生成Makefile文件 mkdir b ...

  7. moviepy音视频剪辑:视频基类VideoClip子类VideoFileClip、CompositeVideoClip、ImageSequenceClip介绍

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<moviepy音视频剪辑:moviepy中的剪辑相关类及关系>介绍了VideoClip主要有六个直接子类(VideoFileClip ...

  8. 第8.32节 Python中重写__delattr__方法捕获属性删除

    一. 引言 上节介绍了__delattr__方法在Python清除实例属性时被捕获执行,本节结合例子介绍重写__delattr__方法,并说明__delattr__方法执行的触发逻辑. 二. 重写__ ...

  9. mysql中table schema的基本操作

    我们通常对数据库进行的增删插检操作,是针对数据库中的文件.mysql数据库中还有一些表(是view,只能做select操作)记录了现有表的meta data,比如某个column的名字,它的定义是什么 ...

  10. 网鼎杯2020 AreUSerialz

    0x00 前言 ...有一说一,赵总的BUUCTF上的这道题目并没有复现到精髓.其实感觉出题人的题目本身没有那么简单的,只不过非预期实在是太简单惹. 涉及知识点: 1.php中protected变量反 ...