我使用ubuntu(12.04)+ nodejs(v0.10.22)+ socket.io(v0.9.14)传输消息。

大约有300个同时连接。几个小时后(大约1或2个小时以上,它不会立即显示),某些连接将以 CLOSE_WAIT FIN_WAIT2 状态持续存在。

这些不间断的连接随着时间线性增长。当连接数达到限制(默认1024)时,用户将很难连接套接字服务器,除非某些连接正常释放。

以下是套接字服务连接状态,大约运行3个小时。

netstat -anl | grep <PORT_OF_NODE_PROCESS> | awk '/^tcp/ {t[$NF]++}END{for(state in t){print state, t[state]} }'

FIN_WAIT2 23
LISTEN 1
CLOSE_WAIT 27
TIME_WAIT 12
ESTABLISHED 333
FIN_WAIT1 12

可能的解决方案

1.定期触摸js文件

使用Nodemon Package运行js文件,当更改文件的上次修改时间时,nodemon将重新启动服务,并释放所有以前的不死连接( CLOSEWAIT FINWAIT2 )

2.增加连接数限制
sudo vim /etc/security/limits.conf

*       soft    nofile  1024
*       hard    nofile  2048
root    soft    nofile  4096
root    hard    nofile  8192
user1   soft    nofile  2048
user1   hard    nofile  2048

尝试使连接难以达到极限。

3.减少保持 Activity 超时

让操作系统在短时间内自动关闭连接,但是我还没有尝试过。

问题

我发现了一些可能解决此问题的解决方案。但是上述解决方案并没有真正解决状态为 CLOSE_WAIT FIN_WAIT2 的持久连接。我发现这是服务器( CLOSE_WAIT )或客户端( FIN_WAIT2 )无法正确关闭连接的结果。我认为socket.io将在超时后强制关闭这些错误的连接。但似乎无法正常工作。

我尝试在测试环境中重新出现 CLOSE_WAIT FIN_WAIT2 状态的问题。但是它永远不会显示这些连接情况。
  • 连接套接字服务器并断开网络
  • 之后
  • 长时间连接套接字服务器

  • 我发现有人问过相关问题(Many stale connections in state CLOSE_WAIT and FIN_WAIT2),但仍然找不到解决方案。有谁知道如何解决这个问题?

    谢谢

    最佳答案

    我尝试同时使用多个连接来连接套接字服务器,我发现某些客户端套接字将使用相同的 SOCKET ID (从xhr获取,它看起来像 nmXTMmCGNQp4EncrfHqj )来建立连接。建立所有连接后,我将关闭浏览器,这将导致许多CLOSE_WAIT连接而没有释放。一些连接将关闭(基于已生成的唯一SOCKET ID 的数量)。因为服务器将从 SOCKET ID 建立TCP/IP连接。但是,如果 SOCKET ID 连接已存在于连接池中,则此连接将不会存储在连接池中。因此,当客户端发送FIN数据包尝试关闭连接,但服务器连接池中不存在该数据包时。服务器将始终不发送ACK数据包以准备关闭连接。因此,这些连接将保持 CLOSE_WAIT 的状态,并且不会释放。

    var host = 'http://socket.server/';
    var sockets = [];
    for(var i=0;i<200;i++){
        var socket = io.connect(host,{"force new connection":true});
        sockets.push(socket);
    
      socket.on("message",function(message){
        console.log(message);
      });
      socket.on("disconnect",function(){
        console.log("disconnect");
      });
    }
    

    修复 lib\manager.js 第670行。

    当连接池中已经存在 SOCKET ID 连接时,不要从 SOCKET ID 建立TCP/IP连接。

    另请参阅:https://github.com/kejyun/socket.io/commit/8d6c02a477d365f019530b4ec992420dfb90eb09
    if (!this.connected[data.id]) {
      if (transport.open) {
        if (this.closed[data.id] && this.closed[data.id].length) {
          transport.payload(this.closed[data.id]);
          this.closed[data.id] = [];
          }
    
          this.onOpen(data.id);
          this.store.publish('open', data.id);
          this.transports[data.id] = transport;
        }
    
        this.onConnect(data.id);
        this.store.publish('connect', data.id);
        //....etc
      }
    }
    

    以下是套接字服务连接状态,大约运行6个小时。
    netstat -anl | grep <PORT_OF_NODE_PROCESS> | awk '/^tcp/ {t[$NF]++}END{for(state in t){print state, t[state]} }'
    
    FIN_WAIT2 37
    LISTEN 1
    TIME_WAIT 13
    ESTABLISHED 295
    FIN_WAIT1 20
    
  • Benchmarkt socket.io
  • 10-08 09:41
    查看更多