NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

TCP 连接的 99 号和 110 号错误

  • 2019-11-25
  • 本文字数:2566 字

    阅读完需:约 8 分钟

TCP连接的99号和110号错误

当客户端频繁的采用短链接时候,经常会遇到[110][connection time out]和[99][could not assigned requested address]的错误。以下是对两种错误的分析以及优化建议,希望对大家有所帮助。

短链接常见的两种错误

当客户端频繁的采用短链接时候,经常会遇到[110][connection time out]和[99][could not assigned requested address]的错误。前段时间我们的存储服务就遇到了这样的一拨报警,经过调研分析,基本确定以上这两个错误与客户端端口的 TIME-WAIT 状态以及服务端的 listen 队列有关(当然也有其它可能的原因,这里只分析这两种)。


从客户端来看,在我们的应用场景中,因为频繁的使用端连接,而且在同一台机上的客户端的数量比较多,造成了大量的 TIME-WAIT 状态的端口,当 TIME-WAIT 状态端口的数量铺满了整个 port_range(由 ip_local_port_range 内核参数指定)范围后,就会产生 99 号错误;从服务端来看,因为频繁大量的 accept 短链接,到达一定量后,服务端口的 listen 队列会出现溢出,这个时候,新的连接请求会被丢弃,连接建立失败,客户端也就产生了 110 号错误。

两种错误产生的原因

[99][could not assigned requested address]

TIME-WAIT 状态是连接一端主动关闭并发送完最后一个 ACK 之后所处的状态,这个状态一般会存在 2MSL(Max Segment Lifttime,即一个包在传输过程中的最大生存时间)时间(所以又叫 2MSL 状态),之所以要有这个状态,是为了让前一个连接的包不影响后面的链接,并且可以被有效的应答,以保证 TCP 连接的可靠性。


为了避免混淆在 TIME-WAIT 状态连接上的处理的包是前一个连接迟到的包还是新连接的包,TCP 协议规定在整个 TIME-WAIT 状态下,不能再建立同样的连接(即四元组一样的连接,但是可以利用处于 TIME-WAIT 的端口建立四元组不一样的连接)Linux 的 TCP/IP 协议栈在判断一个处于 TIME-WAIT 状态的本地端口是否可以作为一个新连接的本地绑定端口时,需要对这个端口做一个是否可用的的判断(在四员组符合之后)。


下面是 linux.2.6.32.70 内核中这一部分逻辑的代码片段



在上面的逻辑中返回 1 表示可以用,返回 0 表示不可用,不可用后报的错是"EADDRNOTAVAIL", 也就是“[99][could not assigned requested address]”。从上面的代码逻辑中可以看出,当 tcp_tw_resuse 对能否重用处于 TIME-WAIT 状态的端口至关重要


1.若 tcp_tw_resuse 未打开,且没有空闲的窗口使用时,则会报“[99][could not assigned requested address]”的错误


2.若 tcp_tw_reuse 打开了,且处于 TIME_WAIT 状态端口的连续两次连接使用间隔要小于等于 1 秒,也会报“[99][could not assigned requested address]”的错误


验证:1 的情况好理解,现在验证 2 的情况,这也是我们线上的客户端的情况,设定系统的 port_range 只有一个元素


$cat "net.ipv4.ip_local_port_range = 1024 1024" >> /etc/sysctl.conf && sysctl -p
复制代码


然后客户端果然返回"[99][could not assigned requested address]"错误,验证成功。

[110][connection time out]

Linux 的服务端从 listen 的端口建立的连接要经过两个队列的过渡,分别是 SYN 队列和 ACCEPT 队列。服务端接受到 SYN 请求后,会发送 SYNACK,并把这个 request sock 存在 SYN 队列内;等到三次握手完成后,再存放到 ACCEPT 队列内;然后再由 accept 系统调用,从 ACCEPT 队列内拿出,交给用户使用。


SYN 队列和 ACCEPT 队列都是有长度限制的,这个长度限制与以下三个参数有关:


a. 调用 listen 接口,传递给 back_log 参数;


b. 内核参数 somaxconn; //与 ACCEPT 队列相关


c.内核参数 tcp_max_syn_backlog; //与 SYN 队列相关


我们线上的问题主要是 ACCEPT 队列出现溢出造成的,所以这里主要分析 ACCEPT 队列长度限制的情况 。


在调用 listen 接口的时候,内核会用系统的 somaxconn 参数去截断传递给 listen 的 back_log 参数。下面是 linux2.6.32-70 的相关代码片段



上面的 sk_max_ack_backlog 就是 listen 端口的 ACCEPT 队列的最大长度


当短链接的量太大,accept 系统调用接口处理来不及时,ACCEPT 队列就可能会阻塞溢出,这个时候,Linux 的 TCP/IP 协议栈的做法是把新来的 SYN 请求丢弃掉( Accept backlog is full. If we have already queued enough of warm entries in syn queue, drop request. It is better than clogging syn queue with openreqs with exponentially increasing timeout.),这样当客户端设定的连接超时不够发送第二次 SYN 请求时,就会收不到服务端 ack,连接建立失败,这个时候报的错误是 ETIMEDOUT,也就是“[110][connection time out]“。


下面是 linux.2.6.32-70 的相关代码片段



在上面的代码段中,sk_acceptq_is_full(sk)是判断 ACCEPT 队列是否满了(队列长度限制已经在 listen 系统调用中被截断了,这也是为什么我们修改内核 somaxconn 内核参数,对当前应用程序的已经 listen 的端口的 ACCEPT 队列长度限制不产生影响的原因,需要重起,才能够使用新的内核参数),如果满了,而且 SYN 队列中又有新的没有完成握手的连接请求,则丢弃当前这个链接请求,这个时候的如果客户端设置的链接超时只够它发送一次 SYN 请求,则链接失败,发生“[110][connection time out]“报错。


验证:


1.按照线上情况,设置 somaxconn 为 128,listen 接口的 back_log 为 8192 运行一定数量的客户端,频繁的向服务端建立 TCP 链接,然后释放,观察情况 。


2.设置 somaxconn 为 8192, 同时设置 listen 的接口的 back_log 参数也为 8192,重复 1 的步骤。



上面是单个客户端的代码逻辑,很简单。

somaxconn 为 128

客户端大量报错



服务端



从上面的结果可以看出,被丢弃的 SYNs 在不断的增加

somaxconn 为 8192

客户端没有报错


服务端



可以看出,这段时间内没有被丢弃的 SYNs

总结

验证的结果和内核代码以及我们的预想是吻合的

解决办法

1.提高客户端的链接超时限制。当前是 300ms,比如可以提升到 3s 等;


2.提高服务端的 somaxconn 限制,这是个指标不治本的方法,只能是一定程度的缓解。(修改内核的其他的网络参数也是一样,只能是缓解,并不能解决根本问题)。


3.在客户端使用连接缓冲池,将短链接转换成长链接来使用(个人认为这个才是更好的办法,一劳永逸)。


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/umQTPgYC7UVtOGCbVjRnyA


2019-11-25 10:45913

评论

发布
暂无评论
发现更多内容

思考:数字卫星可视化如何实现?

DevOps和数字孪生

仿真建模 数字卫星

多云管理平台有哪些?大家推荐哪家好用?

行云管家

云计算 多云 云管理 云管

18款iPad绘画软件推荐!iPad必备生产力工具。

彭宏豪95

ipad 效率工具 苹果 绘图软件 在线绘图

中小企业建设数字化工厂,选择集成老路还是整体重构?

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

EDS从小白到专家丨打造你的专属“数据物流”系统

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

百亿规模京东实时浏览记录系统的设计与实现 | 京东云技术团队

京东科技开发者

数据 离线 企业号 7 月 PK 榜 浏览记录

24款数据可视化工具介绍

2D3D前端可视化开发

数据分析 web前端 数据可视化工具 可视化看板 数据可视化软件

如何看待互联网大厂加班文化?

程序员小毕

程序员 互联网 后端 架构师 java面试

DevSecOps:软件安全捍卫者

DevOps和数字孪生

DevSecOps

浅析本地缓存技术-Guava Cache | 京东物流技术团队

京东科技开发者

Java 缓存 Guava Cache Guava 企业号 7 月 PK 榜

基于50W携程出行攻略构建事件图谱(含码源):交通工具子图谱、订酒店吃饭事件图谱等

汀丶人工智能

人工智能 自然语言处理 知识图谱

电商企业需要堡垒机吗?采购堡垒机选择哪家好?

行云管家

网络安全 信息安全 电商 堡垒机 等级保护

2023京津冀(北京)广告印刷技术与设备博览会

吹吹晚风

Ubuntu 20.04系统编译安装Redis教程。

百度搜索:蓝易云

redis 云计算 Linux ubuntu 运维

浅议实时操作系统RTOS

DevOps和数字孪生

RTOS 实时操作系统

【航遥 × ModelWhale】AI for Science 科研范式改革

ModelWhale

人工智能 云计算 算力 遥感 地球科学

多种应用场景下的大数据传输解决方案,让企业数据高效同步

镭速

大数据传输

这些大数据传输解决方案保证了企业快速传输和数据可靠性

镭速

高速传输 大数据传输 快速文件传输

社区征文 | 记一次“雪花算法”造成的生产事故的排查记录

悟空聊架构

架构 雪花算法 生产事故 悟空聊架构 年中技术盘点

监控系统 Prometheus 的原理 | 社区征文

悟空聊架构

运维 监控 Prometheus 悟空聊架构 年中技术盘点

m7s Console架构解析

不卡科技

vite 流媒体 控制台 Vue 3 #go

Ubuntu 20.04系统编译安装Memcached教程。

百度搜索:蓝易云

memcached 云计算 Linux ubuntu 运维

网络带宽利用率不够?这些大数据传输解决方案来帮你

镭速

数据传输 大数据传输

柏睿数据作为湖仓一体数据平台代表厂商入选IDC报告

新消费日报

构建网站利器!体验高速稳定的香港云主机服务!

一只扑棱蛾子

云主机 香港云主机

大语言模型的预训练[6]:思维链(Chain-of-thought,CoT)定义原理详解、Zero-shot CoT、Few-shot CoT 以及在LLM上应用| 社区征文

汀丶人工智能

人工智能 大语言模型 LLM模型 年中技术盘点 思维链

极客时间架构实战营模块一作业

Geek_6361c3

#架构实战营

2023中国(北京)国际数字标牌展览会

吹吹晚风

跟着核心开发者聊聊大模型应用、框架开源那些事儿

飞桨PaddlePaddle

人工智能 百度 paddle 飞桨 百度飞桨

混战源起ChatGPT,中国的AI产业怎么样了? | 社区征文

向阳花

人工智能 AI 马斯克 前沿技术 年中技术盘点

什么是 JSON:一个简洁易懂的入门指南

Apifox

Java json 程序员 开发 Postman

TCP连接的99号和110号错误_文化 & 方法_吴晓飞_InfoQ精选文章