J'ai testé la charge de mes API REST à l'aide de JMeter.
Je reçois l'erreur suivante lorsque je rencontre 1000 utilisateurs simultanés:
Too many open files. Stacktrace follows:
Java.net.SocketException: Too many open files
at Java.net.Socket.createImpl(Socket.Java:397)
at Java.net.Socket.getImpl(Socket.Java:460)
at Java.net.Socket.setSoTimeout(Socket.Java:1017)
at org.Apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.Java:126)
at org.Apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.Java:180)
at org.Apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.Java:294)
at org.Apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.Java:640)
at org.Apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.Java:479)
at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:906)
at org.Apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.Java:805)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.Java:476)
at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.Java:441)
at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.Java:390)
Mon serveur essaie de frapper une autre API REST pour obtenir les données, les traiter et finalement renvoyer une réponse JSON.
Comment augmenter le nombre de fichiers ouverts sous Linux?
Voici l'appel que je fais à un autre serveur
Map getResponse(Map data, String url){
HTTPBuilder httpBuilder = new HTTPBuilder(url);
httpBuilder.request(Method.POST, JSON) {
headers.'Authorization' = AppConfig.config.appKey;
headers.'Content-type' = 'application/json'
body = data
response.success = { resp, reader ->
return reader as Map;
}
response.failure = { response, reader ->
return null
}
}
}
Vous avez certainement ouvert le nombre maximum de fichiers/sockets ouverts. Le nombre maximal de fichiers ou de sockets ouverts sur les machines Linux est de 1024. Par défaut. Vous devez changer cela. Vous pouvez vous référer à ceci Java.net.SocketException Trop de fichiers ouverts
Vous pouvez utiliser la requête ci-dessous pour vérifier à partir de votre terminal afin d'obtenir le nombre maximal de fichiers ouverts autorisés.
ulimit -n
De ici :
Ce qui se passe, c'est que les sockets sous-jacents ne sont pas fermés et que la JVM finit par basculer dans la limite système par processus du nombre de descripteurs de fichiers ouverts.
La bonne solution serait de fermer les sockets au bon moment (c'est-à-dire quand ou peu de temps après, le serveur a fermé la fin de la connexion). Cela semble difficile avec HttpURLConnection. Tout est très confus:
disconnect () semble juste le fermer immédiatement - ou pas; les Javadocs sont intentionnellement vagues sur ce qu'il fait réellement, et surtout quand il le fait.
close () pourrait être le bon choix. La section Evaluation du bogue Java n ° 4147525 indique: "... appelez close () sur les flux d’entrée et/ou de sortie. Le socket sous-jacent sera correctement fermé lorsque vous ne ferez pas de connexions keepalive et mettra correctement en cache et réutiliser des connexions de keepalive (et qui expireront tout de même et se fermeront après un court moment de toute façon). "
Mais peut-être pas. Le bogue 4142971 indique: "L'appel des méthodes close () n'a aucun effet sur la persistance de la connexion HTTP sous-jacente."
À défaut d'une réponse claire, les objets HttpURLConnection pourraient éventuellement être ajoutés à une liste et tous déconnectés en même temps à la fin de l'exécution du test. Cela limiterait toujours la taille totale de l'analyse, mais au moins les descripteurs perdus ne s'accumuleraient pas entre les analyses.
Peut-être que la vraie solution consiste à abandonner HttpURLConnection et à utiliser le client HTTP de Jakarta Commons. Quelqu'un a suggéré cela en rapport avec un problème différent (bug
#4143518
).
"Java.net.SocketException: trop de fichiers open" peuvent être vus dans n'importe quelle application Java Server, par exemple. Tomcat, Weblogic, WebSphere, etc., avec client se connectant et se déconnectant fréquemment.
Vous pouvez découvrir comment résoudre "Java.net.SocketException: trop de fichiers ouverts" ici