select() 因资源耗尽而挂起 - 但是是什么资源?

select() 因资源耗尽而挂起 - 但是是什么资源?

通过 sftp 连接到我的服务器有时会导致此处挂起:

if (select(max+1, rset, wset, NULL, NULL) < 0) {

这是 openssh 5.2p1 的 sftp-server.c (sftp_server_main() 的主循环) 中的第 1428 行。

当通过 vanilla FTP 打开数据连接时,也会出现同样的挂起情况。有时我可以在几秒或几分钟后接通,但有时在服务器能够响应之前,客户端的连接就会超时。当服务器响应并且我已连接时,如果我发出例如“ls”,它会在 select() 处再次挂起一段时间。

ssh 正常;可以无延迟地连接并发出命令等。

我不认为这是插座死亡:

root@dl:~# cat /proc/net/sockstat
sockets: used 304
TCP: inuse 444 orphan 302 tw 152 alloc 451 mem 5280
UDP: inuse 4
RAW: inuse 0
FRAG: inuse 0 memory 0

root@dl:~# netstat -tan | awk '{print $6}' | sort | uniq -c
    2 CLOSE_WAIT
  121 CLOSING
    1 established)
  109 ESTABLISHED
    17 FIN_WAIT1
    9 FIN_WAIT2
    1 Foreign
  300 LAST_ACK
    20 LISTEN
    2 SYN_RECV
  433 TIME_WAIT

似乎也没有文件描述符不足的问题,但我对此并不十分确定。即使有,那不也会产生错误,而不是挂起吗?

这似乎与 nginx 正在服务的连接数有些关系。我可以关闭 nginx,问题就消失了。话虽如此,nginx 和 apache 能够在这种状态下共存而不会出现问题(apache 永远不会挂起)。在这些“事件”期间,人们还可以毫无问题地连接到同一台计算机上的 IRC 服务器。所以也许它仅限于 select()?

nginx 使用的不是套接字/文件描述符的哪种资源导致 select() 挂起?我为此抓狂不已。

我尝试了所有常用的网络调整方法(通过 sysctl 进行各种设置,减少超时),但都不起作用。机器没有内存不足,CPU 和 I/O 都很好。

Linux dl 2.6.26-2-486 #1 Sat Jun 11 14:47:34 UTC 2011 i686 GNU/Linux

它运行的是 Debian Lenny。

什么可能导致 select() 在检查某些套接字时挂起?

答案1

两件事情:

  1. 调用‘select’的代码中有一个错误。

  2. 尚未收到任何信息。

答案2

我现在已经解决了这个问题;请参阅我最近提出的问题了解详情。基本上,服务器正遭受熵不足的困扰(使用 验证cat /proc/sys/kernel/random/entropy_avail)。haveged通过 Debian 反向移植安装软件包解决了使用 时非常长的挂起问题sftp,这可能与 David Schwartz 所说的有关(“尚未收到任何信息”)...因为无法加密。目前我不清楚为什么ssh不受影响(或没有受到太大影响)。

相关内容