Ich habe eine Anwendung, der die Dateideskriptoren ausgehen, anscheinend indem ich Sockets öffne, aber ich kann nicht genau herausfinden, was diese Sockets tun. Diese erscheinen in der Ausgabe als
java 9689 appuser 1010u sock 0,5 263746675 can't identify protocol
java 9689 appuser 1011u sock 0,5 263746676 can't identify protocol
java 9689 appuser 1012u sock 0,5 263746677 can't identify protocol
java 9689 appuser 1014u sock 0,5 263746678 can't identify protocol
java 9689 appuser 1015u sock 0,5 263746679 can't identify protocol
java 9689 appuser 1016u sock 0,5 263746681 can't identify protocol
und in / proc / $ PID / fd als
lrwx------ 1 appuser appuser 64 Jun 23 11:49 990 -> socket:[263732085]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 991 -> socket:[263732086]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 992 -> socket:[263735307]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 993 -> socket:[263732088]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 995 -> socket:[263735308]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 996 -> socket:[263735309]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 997 -> socket:[263745434]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 998 -> socket:[263745435]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 999 -> socket:[263745436]
aber es gibt keine ähnliche Ausgabe in netstat -a
.
Was sind diese Steckdosen und wie kann ich herausfinden, was sie tun?
Bearbeiten : Ich habe versucht, ausgeführt grep $SOCKET /proc/net
, wie in den lsof-FAQ empfohlen , wobei $ SOCKET beispielsweise 263746679 ist, aber das gab auch keine Ergebnisse.
Als Hintergrund ist die Anwendung ein Container für mehrere Aufgaben, die unter anderem Netzwerkaufrufe durchführen. Ich muss den heraussuchen, der wahnsinnig wird, aber bis ich herausfinde, mit wem diese Steckdosen kommunizieren, stecke ich fest.
Antworten:
Dies kann auftreten, wenn Sie einen Socket erstellen, ihn jedoch niemals verbinden () oder binden (). Am besten ist es, die Anwendung zu stracen (-fF) und dann mit der Ausgabe von lsof zu verweisen, um zu bestimmen, welche Sockets das Problem verursachen. Als Bonusmethode für das Debuggen: Wenn Sie Ihre Socket-Aufrufe mit Debugging-Informationen versehen und an / dev / null ausschreiben, wird dies in Kürze angezeigt, ohne dass Sie unglaublich große Protokolldateien erhalten.
quelle
Mit Python habe ich das gleiche Problem bei SSL-Sockets festgestellt:
Die Lösung bestand darin, die SSL-Ebene vor dem Schließen zu entpacken:
Dadurch werden die Sockets in meiner App ordnungsgemäß geschlossen.
quelle
Das erste, was ich tun würde, ist zu erhöhen, wenn Ihre Dateideskriptor-Grenze:
Als nächstes würde ich sicherstellen, dass Ihr System auf dem neuesten Stand ist, dies schließt alle Bibliotheken und Server ein. Möglicherweise ist Ihr Java-Anwendungsserver veraltet (falls Sie einen verwenden). Es ist auch möglich, dass Ihr Anwendungsserver falsch konfiguriert ist. Sehen Sie sich Ihre Konfigurationsdatei an und senken Sie Ihre
connectionTimeout
und / oder IhremaxKeepAliveRequests
(ich bin nicht sicher, welchen Anwendungsserver Sie verwenden oder ob Sie überhaupt einen verwenden ...).Ich bin mir nicht sicher, was diese Anwendung bewirkt, aber wenn Sie nicht glauben, dass Zehntausende von Sockets erforderlich sind, ist dies mit ziemlicher Sicherheit ein "Dateideskriptorleck" in Ihrer Java-Anwendung. Möglicherweise müssen Sie einen Fehlerbericht an den Anbieter senden. In diesem Fehlerbericht sollten Sie Informationen zum erneuten Erstellen des Problems enthalten.
Hier finden Sie einige Möglichkeiten zum Debuggen des Problems.
Wireshark (oder Twireshark für das CLI) ist das beste Werkzeug, um zu sehen, wie diese Sockel verwendet werden. Wireshark gibt Ihnen eine Aufschlüsselung der Art des Verkehrs, der über das Kabel geworfen wird. Es ist wahrscheinlich, dass die ersten Verbindungen erfolgreich sind und dann das Dateideskriptorlimit erreicht wird. Sobald das Dateideskriptorlimit erreicht ist, wird Wireshark nichts mehr bemerken (und in diesem Fall ist es netter als netstat), aber dies wird helfen, das Problem einzugrenzen. Es kann vorkommen, dass viele ausgehende SYNs gesendet werden, jedoch keine SYN / ACKs empfangen werden, sodass viele TCP-Verbindungen nur im SYN_WAIT-Status hängen bleiben.
Wenn Sie Zugriff auf den Quellcode haben und wissen, welche Sockets erstellt werden (z. B. mit strace oder nur durch Durchsuchen des Codes), können Sie das Projekt in Eclipse (oder einer anderen IDE) öffnen und bei der Funktion that einen Haltepunkt setzen schafft diese Sockets. Wenn der Haltepunkt erreicht wird, können Sie den Stack-Trace anzeigen. Bei diesem Dateideskriptorleck handelt es sich möglicherweise um eine einfache Endlosschleife, oder der Socket-Timeout-Wert ist zu groß. Eine andere Möglichkeit besteht darin, dass die Java-App
socket.close()
die Verbindungen nicht bereinigt. Das Schließen wird normalerweise imfinely
Block a ausgeführttry/catch
(Ja, ein Socket muss in Java immer einen try / catch-Befehl haben, sonst wird er nicht erstellt :). Letztendlich ist es wahrscheinlich, dass die Java-App ihre IOException nicht richtig verarbeitet.quelle