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