feign调用不成功没有任何提示(端口均被占用了)

作者简介:大厂一线资深开发。从crud开发到资深开发,再到研究员兼技术经理。《资深开发讲技术》 从一线实战中总结有故事,有背景的案例,希望带给大家一系列技术盛宴。

欢迎大家 评论,关注,欢迎技术交流。友情提醒,往期的文章也精彩。

问题现象

项目上线后,通过正常流程, 处理存量数据。预期QPS 2K,持续时间大约1天。但是调用方的QPS开始的时候满足需求,很快过了一段时间,QPS就降下来了,而且不再升起来了。

排查过程

我负责服务器端项目,因此我们双方一起联合排查这个问题。

按照上线之前的压测结果,服务端部署4台虚机,QPS 4K是可以轻松满足的。我也挺奇怪的,登录服务器,看了下响应日志,响应速度很快。而且我的work线程,连接数开的挺足的。

我登录到调用方的系统,看了下日志,出现比较多的,下面的异常信息。

feign调用不成功没有任何提示(端口均被占用了)(1)

cannot assign requested address executing,表示没有有效的端口也已分配了。

控制台执行,netstat -anp|grep TIME_WAIT,发现大量tcp连接处在 TIME_WAIT,大约5w多。

feign调用不成功没有任何提示(端口均被占用了)(2)

我吓了一跳,一个系统的端口总共6w多。怎么这么多处于待关闭状态。和调用方的同学沟通后, 了解到,他们使用的是fegin客户端。我猜测是没有使用http连接池或者连接池配置的有问题。

沟通后发现,调用方使用的是默认的feign配置,并没有配置http连接池。所以需要看下源码,需要了解feign是如何处理http请求的。

feign调用不成功没有任何提示(端口均被占用了)(3)

如上面截图,feign默认的会使用java.net.HttpURLConnection 创建连接,处理完请求就关闭连接。

至此我就明白了,当调用方持续大量发起调用的时候,每次请求都会创建一个连接,然后主动销毁,但是连接关闭是需要时间的(2MSL),而处于TIME_WAIT的tcp连接是不会释放端口的。所以导致端口被大量占用,系统中的连接很多处于TIME_WAIT中

feign调用不成功没有任何提示(端口均被占用了)(4)

处理过程

给feign增加了一个Http连接池,重新上线后,开启存量数据处理请求,服务正常,连接状态平稳。

结论

1. TIME_WAIT状态结束之前,tcp连接会一直占用的本地端口号无法释放。高并发并且采用短连接方式,运行一段时间后,就常常会出现做为客户端的程序,无法向服务端建立新的连接的情况。此时用"netstat-anp"命令查看系统将会发现机器上存在大量处于TIME_WAIT状态的并且占用大量的本地端口号。最后该机器上的,可用本地端口号均被占完。

2. 目前很多团队在做微服务化,采用spring cloud体系。基本上都会使用feign,但是默认的配置,并不支持高负载的场景,您踩到这个坑了吗?

往期文章:

增加消费能力,导致的线上故障

一次限速,导致的线上故障

日志中的连接异常信息,你get到了吗?

听过限流熔断,但是对于超时你重视了吗?

cpu 负载过高,服务抗不住了?

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页