2014-03-28 4 views
5

Ich versuche die Skalierbarkeit eines Java Vert.x Webservers (der auf Netty basiert) unter Mac OS zu testen X. Dafür habe ich das Verbindungslimit auf 1 Million erhöht:"Verbindung durch Peer zurückgesetzt" und "Zu viele Dateien öffnen" Ausnahmen beim Versuch, den Vert.x Server zu skalieren

sudo sysctl -w kern.maxfiles=1000200 
sudo sysctl -w kern.maxfilesperproc=1000100 
sudo ulimit -n 1000000 

Dann habe ich erstellt localhost Aliase mit:

for i in `seq 200 250`; do sudo ifconfig lo0 alias 172.16.123.$i ; done 

ich bin jetzt in der Lage diese IP-Adressen zu verbinden; jedoch nach etwa 1000-2000 aufgebauten Verbindungen erhalte ich „Verbindung von Peer zurückgesetzt“ Verbindungen:

java.net.SocketException: Connection reset by peer 
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) 
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:712) 
    at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:191) 
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:228) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:497) 
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447) 

Sie werden gefolgt von „Zu viele offene Dateien“ Ausnahmen:

Caused by: java.net.SocketException: Too many open files 
    at sun.nio.ch.Net.socket0(Native Method) 
    at sun.nio.ch.Net.socket(Net.java:393) 
    at sun.nio.ch.Net.socket(Net.java:386) 
    at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:104) 
    at sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60) 
    at java.nio.channels.SocketChannel.open(SocketChannel.java:145) 
    at io.netty.channel.socket.nio.NioSocketChannel.newSocket(NioSocketChannel.java:48) 

Interessant ist, wenn ich Liste alle Verbindungen mit netstat dann sehe ich, dass es eine Menge von Verbindungen im FIN_WAIT_1 Zustand ist:

tcp4  0 213 172.16.123.230.55618 172.16.123.230.8877 FIN_WAIT_1 
tcp4  0 213 172.16.123.229.55624 172.16.123.229.8877 FIN_WAIT_1 
tcp4  0 213 172.16.123.228.55617 172.16.123.228.8877 FIN_WAIT_1 
tcp4  0 213 172.16.123.227.55616 172.16.123.227.8877 FIN_WAIT_1 
tcp4  0 213 172.16.123.226.55612 172.16.123.226.8877 FIN_WAIT_1 

Weitere Ergebnisse:

$ netstat -a | wc -l: 
14282 
$ lsof | wc -l 
6922 

Server-Code (vereinfacht):

HttpServer server = vertx.createHttpServer(); 
server.websocketHandler(ws -> { 
    connections++; 
    ws.exceptionHandler(t -> t.printStackTrace()); 
    ws.closeHandler(h -> { 
     connections--; 
    }); 

    if (ws.path().equals("/app")) { 
     ws.dataHandler(data -> { 
      // ... 
     }); 
    } else { 
     ws.reject(); 
    } 
}).listen(8877); 

Code Client (vereinfacht):

Handler<Void> connectHandler = new Handler<Void>() { 
    @Override 
    public void handle(Void e) { 
     HttpClient client = vertx.createHttpClient().setHost(nextHost()).setPort(8877); 

     client.connectWebsocket("/app", ws -> { 
      connections++; 
      ws.exceptionHandler(t -> t.printStackTrace()); 
      ws.closeHandler(h -> { 
       connections--; 
      }); 

      // ... 
     }); 

     if (connections < 1000000) { 
      vertx.runOnContext(this); 
     } 
    } 
}; 
connectHandler.handle(null); 

Beide begannen mit (auf demselben Computer):

vertx run Class -cp classes:... -instances 8 

Does Jeder hat eine Idee, was könnte das Problem sein? Ich bin noch nicht mit solchen Setups vertraut und vielleicht habe ich gerade einen einfachen Fehler gemacht. Es hilft nicht, den Akzeptierungsstau zu erhöhen.

Weitere Informationen:

Update:

Nach

limit maxfiles 1000100 2000200 
Hinzufügen

/etc/launchd.conf und

kern.maxfiles=2000400 
kern.maxfilesperproc=1000200 

/etc/sysctl.conf und den Computer neu zu starten, hat es schon ein bisschen besser geworden.Aber nachdem ich während ich jetzt „Zu viele offene Dateien“ Ausnahmen auch für das Lesen von normalen Dateien, obwohl es nicht mehr als 10000 geöffneten Dateien:

Caused by: sun.nio.fs.UnixException: Too many open files 
     at sun.nio.fs.UnixNativeDispatcher.getcwd(Native Method) 
     at sun.nio.fs.UnixFileSystem.<init>(UnixFileSystem.java:67) 
     at sun.nio.fs.BsdFileSystem.<init>(BsdFileSystem.java:41) 
     at sun.nio.fs.MacOSXFileSystem.<init>(MacOSXFileSystem.java:44) 
     at sun.nio.fs.MacOSXFileSystemProvider.newFileSystem(MacOSXFileSystemProvider.java:45) 
     at sun.nio.fs.MacOSXFileSystemProvider.newFileSystem(MacOSXFileSystemProvider.java:38) 
     at sun.nio.fs.UnixFileSystemProvider.<init>(UnixFileSystemProvider.java:56) 
     at sun.nio.fs.BsdFileSystemProvider.<init>(BsdFileSystemProvider.java:36) 
     at sun.nio.fs.MacOSXFileSystemProvider.<init>(MacOSXFileSystemProvider.java:40) 

Update 2:

Ich habe versucht, mehrere andere Optionen, aber es scheint, gibt es ein Limit bei genau 10180 Verbindungen, die nicht überschritten werden können. Wenn jemand keine andere Idee hat, werde ich wahrscheinlich nur auf Linux umsteigen.

Update 3:

Nachdem die JVM-Option Hinzufügen "-XX: -MaxFDLimit" Ich kann jetzt offen 16331 Verbindungen, bis ich die folgenden Ausnahmen erhalten:

java.net.BindException: Can't assign requested address 
     at sun.nio.ch.Net.connect0(Native Method) 
     at sun.nio.ch.Net.connect(Net.java:435) 
     at sun.nio.ch.Net.connect(Net.java:427) 
     at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:643) 
     at io.netty.channel.socket.nio.NioSocketChannel.doConnect(NioSocketChannel.java:176) 

Dies ist wahrscheinlich wegen die Standard-port (16383 Ports):

net.inet.ip.portrange.first: 49152 
net.inet.ip.portrange.last: 65535 

da ich aber 50 localhost alises verwenden hätte ich erwartet, dass ab zu sein le, um 16383 * 50 = 819150 Verbindungen zu öffnen. Oder ist es eine bekannte Einschränkung, dass Sie nicht denselben Port für verschiedene Aliase verwenden können?

Update 4:

Ich habe versucht, virtuelle Schnittstellen mit network zu erstellen, aber das Ergebnis ist das gleiche:

for i in `seq 200 250`; do sudo networksetup -createnetworkservice lo$i lo0 ; sudo networksetup -setmanual lo$i 172.16.123.$i 255.240.0.0 ; done 
+0

Vielleicht haben Sie keine verfügbaren 'Ephemeral Ports'? – swKK

+0

@swKK Das glaube ich nicht, da es egal ist, ob ich mich nur mit localhost oder allen 50 Aliasen verbinde. Außerdem enthält der Portrange 16383 Ports. Jedenfalls werde ich es erhöhen und prüfen, ob es einen Unterschied macht. –

+0

@swKK Leider hat es nicht geholfen, die ephemere Port-Reichweite zu erhöhen. –

Antwort

1
+0

Vielen Dank für diesen Tipp! Ich kann jetzt 16331 Verbindungen öffnen und dann bekomme ich "java.net.BindException: Kann nicht angeforderte Adresse" Ausnahmen. Dies ist wahrscheinlich auf das kurzlebige Port-Range-Limit (derzeit 16383) zurückzuführen, aber ich verstehe nicht wirklich warum, weil ich 50 Aliase verwende, um das zu umgehen. Ich werde die Frage aktualisieren. –

Verwandte Themen