【问题标题】:Linux - Too many closed connectionsLinux - 关闭的连接太多
【发布时间】:2016-12-14 17:33:20
【问题描述】:

我正在使用 Netty (async nio) 在单个 linux 机器上以 1800 个连接/分钟编写一个应用程序打开。一个连接会存活几秒钟,然后关闭,或者如果没有收到应答,它会在 20 秒后超时。此外,读/写超时为 30 秒,请求头包含connection=close。 过了一段时间(2-3 小时),我在日志中发现了很多异常,因为 Netty 由于缺乏资源而无法创建新连接。 我将limits.conf中打开文件的最大数量增加为:

root            hard    nofile           200000
root            soft    nofile           200000

这是netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n的输出:

   1 established)
   1 FIN_WAIT2
   1 Foreign
   2 TIME_WAIT
   6 LISTEN
  739 SYN_SENT
 6439 LAST_ACK
 6705 CLOSE_WAIT
12484 ESTABLISHED

这是ss -s 命令的输出:

Total: 194738 (kernel 194975)
TCP:   201128 (estab 13052, closed 174321, orphaned 6477, synrecv 0, timewait 3/0), ports 0

Transport Total     IP        IPv6
*         194975    -         -
RAW       0         0         0
UDP       17        12        5
TCP       26807     8         26799
INET      26824     20        26804
FRAG      0         0         0

ls -l /proc/2448/fd | wc -l 也提供大约 199K。

也就是说,问题是关于ss -s 命令输出中报告的关闭连接:

1)它们到底是什么?

2)为什么它们一直悬空而不被摧毁?

3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限制范围内?

【问题讨论】:

  • 什么是exact 错误信息和堆栈跟踪,netstat 显示什么?
  • 这是某种网络命名空间环境(docker host / docker container / ...)吗?这些数字只是没有加起来。
  • @Roman 不,它是一台没有虚拟化的真实机器。它们可能会有所不同,因为它们是在应用程序运行时在不同时间获得的(只是以短序列执行命令,但不是在同一时刻)并且因为 fd 包括所有打开的文件描述符而不仅仅是套接字(我猜)。
  • 尝试运行sudo lsof -n -p pid(用实际值替换pid)并检查输出中最常见的条目(并与我们分享结果)。

标签: linux sockets netty


【解决方案1】:

1)它们到底是什么?

它们是从未连接或断开连接且不是closed 的套接字。

在 Linux 中,传出 TCP 套接字(大致)经历以下阶段:

  1. create套接字(未连接),内核为其分配一个文件描述符。
  2. connect()它到远端,建立网络连接。
  3. 您进行数据传输(读/写)。
  4. 读/写完成后,shutdown() 用于读写的套接字,关闭网络连接。
  5. close()套接字,内核释放文件描述符。

因此,ss 报告为已关闭的那些 174K 连接是未超过第 1 阶段(可能connect() 失败甚至从未调用过)或通过第 4 阶段但未通过第 5 阶段的套接字。实际上,它们是具有底层打开文件描述符,但没有任何网络绑定(所以netstat / ss 列表没有显示它们)。

2)为什么它们一直悬空而不被摧毁?

因为没有人给他们打电话close()。我将其称为“文件描述符泄漏”或“套接字描述符泄漏”。

3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限制范围内?

从 Linux 的角度来看,没有。您必须在它们上显式调用close()(或终止拥有它们的进程,以便内核知道它们不再被使用)。

从 Netty/Java 的角度来看,也许,我不知道。

本质上,这是您的代码、Netty 代码(不太可能)或 JRE 代码(不太可能)中的错误。你没有在应该的时候释放资源。如果您显示代码,也许有人可以发现错误。

【讨论】:

    【解决方案2】:

    正如 Roman 正确指出的那样,关闭的连接确实存在,并且是从未正确关闭的套接字。 就我而言,我有一些关于出了什么问题的线索,我在下面报告:

    1)ss -s 显示奇怪的值,特别是很多关闭连接

    2)ls -l /proc/pid/fd | wc -l 显示了很多打开的描述符

    3)netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n 中的数字与之前的不匹配

    4)sudo lsof -n -p pid(罗马建议)显示了很多带有无法识别协议的条目。

    在网络上环顾四周,我发现了一篇有趣的帖子 (https://idea.popcount.org/2012-12-09-lsof-cant-identify-protocol/),它解释了第 4 点的真正含义以及 netstat 数字不匹配的原因(另请参阅此处https://serverfault.com/questions/153983/sockets-found-by-lsof-but-not-by-netstat)。

    我很惊讶,因为我使用 netty 4.1.x(带有 Spring)的通用模式是每个连接都应该正确关闭,所以我花了几天时间才弄明白到底哪里出了问题。

    微妙的问题出现在 netty IO 线程中,其中消息体被复制并放入阻塞队列(作为我的代码的一部分)。当队列已满时,这会减慢速度,引入一些延迟并导致我端未检测到连接超时,从而导致 FD 泄漏。

    我的解决方案是引入一种池化队列,以防止队列已满时的 netty 请求。

    【讨论】:

      【解决方案3】:

      您仍然没有提供我要求的确切错误消息,但据我所知,问题应该是关于 CLOSE_WAIT 状态的六万个连接,而不是“那些关闭的连接”。

      您没有关闭对等方已断开连接的套接字。

      也就是说,问题是关于那些关闭的连接。

      什么关闭了连接?您的netstat 显示不显示任何关闭的连接。并且没有证据表明您的资源耗尽问题与关闭的连接有关。

      1)它们到底是什么?

      他们不是。

      2)为什么它们一直悬空而不被摧毁?

      他们没有。

      3)是否有任何设置(超时或其他)可以帮助将它们保持在合理的限制范围内?

      由于它们不存在,所以这个问题毫无意义。

      【讨论】:

      • 如前所述,目前硬限制和软限制设置在 200K 打开文件/套接字上,因此 6K CLOSE_WAIT 连接应该不是问题。此外,应用程序每分钟生成 1.8K 连接,考虑到超时和处理它们的某些延迟,我想说几个小时后 6K close_wait 连接不是真正的问题。无论如何,您没有回答我的 3 个问题中的任何一个,并且需要一段时间收集整个堆栈跟踪(我需要添加一些日志,重新启动应用程序并等待问题出现)。
      • 你也没有回答我的问题。不应该有任何 CLOSE_WAIT 连接,或者只有几个。 “关闭的连接”计数是 TCP 已关闭的连接数。这不是问题。关闭的连接不会导致资源耗尽,因为它们不是资源,因为它们不再存在。问题在于确实存在,尤其是您泄露的 6.5K CLOSE_WAIT 连接。但是,除非您提供我一直要求的确切错误消息,否则无法进一步帮助您。
      • 好吧,我还不清楚。 ss -s 只是报告 /proc/app-id/fd 内容的总数。运行ls -l /proc/2448/fd | wc -l 给出199670 和ss -s 显示TCP: 199289 (estab 5079, closed 192835, orphaned 330, synrecv 0, timewait 1/0), ports 0,所以我猜关闭的连接仍然存在。
      • 在您提供我现在已经要求四次的确切错误消息和堆栈跟踪之前,永远不会清楚。很明显,您正在泄漏连接。您不会通过关闭套接字来对流结束做出反应,
      • 再一次,我的问题不是为什么我缺少连接,而是那些关闭的连接是什么。而且您需要的堆栈跟踪不会帮助您这么说。
      猜你喜欢
      • 1970-01-01
      • 2014-01-08
      • 2013-05-09
      • 1970-01-01
      • 2014-08-27
      • 2013-08-18
      • 1970-01-01
      • 2018-06-10
      • 2016-04-04
      相关资源
      最近更新 更多